Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0a61b0f authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes Ic4716ad0,I12d04de8 am: 8bc65eac am: e184eba3 am: e14bed49 am: 82412c27

parents b1766334 82412c27
Loading
Loading
Loading
Loading
+39 −33
Original line number Diff line number Diff line
# Binder for Trusty

This is the Trusty port of the libbinder library.
To build it, take the following steps:

* Check out copies of the Trusty and AOSP repositories.
* Apply the patches from the `trusty_binder` topic on both repositories.
* Build Trusty normally using `build.py`.
* Run the sample AIDL test for Trusty:
To build it, first you will need a checkout of the Trusty tree:
```shell
  $ ./build-root/.../run --headless --boot-test com.android.trusty.aidl.test
$ mkdir /path/to/trusty
$ cd /path/to/trusty
$ repo init -u https://android.googlesource.com/trusty/manifest -b master
$ repo sync -j$(nproc) -c --no-tags
```

To run the Android-Trusty IPC test, do the following:

* Build AOSP for the `qemu_trusty_arm64-userdebug` target:
After the checkout is complete, you can use the `build.py` script for both
building and testing Trusty. For a quick build without any tests, run:
```shell
  $ lunch qemu_trusty_arm64-userdebug
  $ m
$ ./trusty/vendor/google/aosp/scripts/build.py generic-arm64-test-debug
```
* In the Trusty directory, run the emulator with the newly built Android:
This will build the smaller `generic-arm64-test-debug` project which
does not run any tests.

The qemu-generic-arm64-test-debug` project includes the QEMU emulator and
a full Trusty test suite, including a set of libbinder tests.
To run the latter, use the command:
```shell
  $ ./build-root/.../run --android /path/to/aosp
$ ./trusty/vendor/google/aosp/scripts/build.py \
    --test "boot-test:com.android.trusty.binder.test" \
    qemu-generic-arm64-test-debug
```
* Using either `adb` or the shell inside the emulator itself, run the Trusty
  Binder test as root:
  ```shell
  # /data/nativetest64/vendor/trusty_binder_test/trusty_binder_test

## Building AIDL files on Trusty
To compile AIDL interfaces into Trusty libraries, include the `make/aidl.mk`
in your `rules.mk` file, e.g.:
```
LOCAL_DIR := $(GET_LOCAL_DIR)

## Running the AIDL compiler
For now, you will need to run the AIDL compiler manually to generate the C++
source code for Trusty clients and services. The general syntax is:
```shell
$ aidl --lang=cpp -o <output directory> -h <output header directory> <AIDL files...>
MODULE := $(LOCAL_DIR)

MODULE_AIDLS := \
        $(LOCAL_DIR)/IFoo.aidl \

include make/aidl.mk
```

The compiler will emit some `.cpp` files in the output directory and their
corresponding `.h` files in the header directory.
## Examples
The Trusty tree contains some sample test apps at
`trusty/user/app/sample/binder-test`.
+28 −7
Original line number Diff line number Diff line
@@ -104,8 +104,17 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u
            return;
        }

        /* Save the session for easy access */
        *ctx_p = session.get();
        /* Save the session and connection for the other callbacks */
        auto* channelContext = new (std::nothrow) ChannelContext;
        if (channelContext == nullptr) {
            rc = ERR_NO_MEMORY;
            return;
        }

        channelContext->session = std::move(session);
        channelContext->connection = std::move(result.connection);

        *ctx_p = channelContext;
    };

    base::unique_fd clientFd(chan);
@@ -119,9 +128,14 @@ int RpcServerTrusty::handleConnect(const tipc_port* port, handle_t chan, const u
}

int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* ctx) {
    auto* session = reinterpret_cast<RpcSession*>(ctx);
    status_t status = session->state()->drainCommands(session->mConnections.mIncoming[0], session,
                                                      RpcState::CommandType::ANY);
    auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
    LOG_ALWAYS_FATAL_IF(channelContext == nullptr,
                        "bad state: message received on uninitialized channel");

    auto& session = channelContext->session;
    auto& connection = channelContext->connection;
    status_t status =
            session->state()->drainCommands(connection, session, RpcState::CommandType::ANY);
    if (status != OK) {
        LOG_RPC_DETAIL("Binder connection thread closing w/ status %s",
                       statusToString(status).c_str());
@@ -133,10 +147,17 @@ int RpcServerTrusty::handleMessage(const tipc_port* port, handle_t chan, void* c
void RpcServerTrusty::handleDisconnect(const tipc_port* port, handle_t chan, void* ctx) {}

void RpcServerTrusty::handleChannelCleanup(void* ctx) {
    auto* session = reinterpret_cast<RpcSession*>(ctx);
    auto& connection = session->mConnections.mIncoming.at(0);
    auto* channelContext = reinterpret_cast<ChannelContext*>(ctx);
    if (channelContext == nullptr) {
        return;
    }

    auto& session = channelContext->session;
    auto& connection = channelContext->connection;
    LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection),
                        "bad state: connection object guaranteed to be in list");

    delete channelContext;
}

} // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -77,6 +77,12 @@ private:
    explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName,
                             std::shared_ptr<const PortAcl>&& portAcl, size_t msgMaxSize);

    // The Rpc-specific context maintained for every open TIPC channel.
    struct ChannelContext {
        sp<RpcSession> session;
        sp<RpcSession::RpcConnection> connection;
    };

    static int handleConnect(const tipc_port* port, handle_t chan, const uuid* peer, void** ctx_p);
    static int handleMessage(const tipc_port* port, handle_t chan, void* ctx);
    static void handleDisconnect(const tipc_port* port, handle_t chan, void* ctx);