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

Commit 55043aee authored by Yu Shan's avatar Yu Shan Committed by Android (Google) Code Review
Browse files

Merge changes Ic02b451d,Ieb84a84f into udc-dev

* changes:
  Add inject task cmd to default remoteaccess hal.
  Grant net_raw capabilities to remote access hal.
parents c6e81d24 9549368d
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -97,7 +97,10 @@ class RemoteAccessService
    bool mTaskWaitStopped GUARDED_BY(mLock);
    // A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
    std::mutex mStartStopTaskLoopLock;
    bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock);
    bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
    bool mGrpcConnected GUARDED_BY(mLock) = false;
    std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);

    // Default wait time before retry connecting to remote access client is 10s.
    size_t mRetryWaitInMs = 10'000;
    std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback;
@@ -110,6 +113,12 @@ class RemoteAccessService

    void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; }
    void dumpHelp(int fd);
    void printCurrentStatus(int fd);
    std::string clientIdToTaskCountToStringLocked() REQUIRES(mLock);
    void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
    void updateGrpcConnected(bool connected);
    android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
                                                                 std::string_view taskData);
};

}  // namespace remoteaccess
+1 −0
Original line number Diff line number Diff line
@@ -2,3 +2,4 @@ service vendor.remoteaccess-default /vendor/bin/hw/android.hardware.automotive.r
    class hal
    user vehicle_network
    group system inet
    capabilities NET_RAW
+93 −25
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ namespace {
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::android::base::Error;
using ::android::base::Result;
using ::android::base::ScopedLockAssertion;
using ::android::base::StringAppendF;
using ::android::base::StringPrintf;
@@ -54,8 +56,10 @@ constexpr char COMMAND_START_DEBUG_CALLBACK[] = "--start-debug-callback";
constexpr char COMMAND_STOP_DEBUG_CALLBACK[] = "--stop-debug-callback";
constexpr char COMMAND_SHOW_TASK[] = "--show-task";
constexpr char COMMAND_GET_VEHICLE_ID[] = "--get-vehicle-id";
constexpr char COMMAND_INJECT_TASK[] = "--inject-task";
constexpr char COMMAND_STATUS[] = "--status";

std::vector<uint8_t> stringToBytes(const std::string& s) {
std::vector<uint8_t> stringToBytes(std::string_view s) {
    const char* data = s.data();
    return std::vector<uint8_t>(data, data + s.size());
}
@@ -81,6 +85,10 @@ void dprintErrorStatus(int fd, const char* detail, const ScopedAStatus& status)
    dprintf(fd, "%s, code: %d, error: %s\n", detail, status.getStatus(), status.getMessage());
}

std::string boolToString(bool x) {
    return x ? "true" : "false";
}

}  // namespace

RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
@@ -126,6 +134,33 @@ void RemoteAccessService::maybeStopTaskLoop() {
    mTaskLoopRunning = false;
}

void RemoteAccessService::updateGrpcConnected(bool connected) {
    std::lock_guard<std::mutex> lockGuard(mLock);
    mGrpcConnected = connected;
}

Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
                                                                   std::string_view taskData) {
    std::shared_ptr<IRemoteTaskCallback> callback;
    {
        std::lock_guard<std::mutex> lockGuard(mLock);
        callback = mRemoteTaskCallback;
        mClientIdToTaskCount[clientId] += 1;
    }
    if (callback == nullptr) {
        return Error() << "No callback registered, task ignored";
    }
    ALOGD("Calling onRemoteTaskRequested callback for client ID: %s", clientId.c_str());
    ScopedAStatus callbackStatus =
            callback->onRemoteTaskRequested(clientId, stringToBytes(taskData));
    if (!callbackStatus.isOk()) {
        return Error() << "Failed to call onRemoteTaskRequested callback, status: "
                       << callbackStatus.getStatus()
                       << ", message: " << callbackStatus.getMessage();
    }
    return {};
}

void RemoteAccessService::runTaskLoop() {
    GetRemoteTasksRequest request = {};
    std::unique_ptr<ClientReaderInterface<GetRemoteTasksResponse>> reader;
@@ -135,28 +170,19 @@ void RemoteAccessService::runTaskLoop() {
            mGetRemoteTasksContext.reset(new ClientContext());
            reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
        }
        updateGrpcConnected(true);
        GetRemoteTasksResponse response;
        while (reader->Read(&response)) {
            ALOGI("Receiving one task from remote task client");

            std::shared_ptr<IRemoteTaskCallback> callback;
            {
                std::lock_guard<std::mutex> lockGuard(mLock);
                callback = mRemoteTaskCallback;
            }
            if (callback == nullptr) {
                ALOGD("No callback registered, task ignored");
            if (auto result =
                        deliverRemoteTaskThroughCallback(response.clientid(), response.data());
                !result.ok()) {
                ALOGE("%s", result.error().message().c_str());
                continue;
            }
            ALOGD("Calling onRemoteTaskRequested callback for client ID: %s",
                  response.clientid().c_str());
            ScopedAStatus callbackStatus = callback->onRemoteTaskRequested(
                    response.clientid(), stringToBytes(response.data()));
            if (!callbackStatus.isOk()) {
                ALOGE("Failed to call onRemoteTaskRequested callback, status: %d, message: %s",
                      callbackStatus.getStatus(), callbackStatus.getMessage());
            }
        }
        updateGrpcConnected(false);
        Status status = reader->Finish();
        mGetRemoteTasksContext.reset();

@@ -252,15 +278,17 @@ bool RemoteAccessService::checkDumpPermission() {
}

void RemoteAccessService::dumpHelp(int fd) {
    dprintf(fd, "%s",
            (std::string("RemoteAccess HAL debug interface, Usage: \n") + COMMAND_SET_AP_STATE +
             " [0/1](isReadyForRemoteTask) [0/1](isWakeupRequired)  Set the new AP state\n" +
             COMMAND_START_DEBUG_CALLBACK +
             " Start a debug callback that will record the received tasks\n" +
             COMMAND_STOP_DEBUG_CALLBACK + " Stop the debug callback\n" + COMMAND_SHOW_TASK +
             " Show tasks received by debug callback\n" + COMMAND_GET_VEHICLE_ID +
             " Get vehicle id\n")
                    .c_str());
    dprintf(fd,
            "RemoteAccess HAL debug interface, Usage: \n"
            "%s [0/1](isReadyForRemoteTask) [0/1](isWakeupRequired): Set the new AP state\n"
            "%s: Start a debug callback that will record the received tasks\n"
            "%s: Stop the debug callback\n"
            "%s: Show tasks received by debug callback\n"
            "%s: Get vehicle id\n"
            "%s [client_id] [task_data]: Inject a task\n"
            "%s: Show status\n",
            COMMAND_SET_AP_STATE, COMMAND_START_DEBUG_CALLBACK, COMMAND_STOP_DEBUG_CALLBACK,
            COMMAND_SHOW_TASK, COMMAND_GET_VEHICLE_ID, COMMAND_INJECT_TASK, COMMAND_STATUS);
}

binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t numArgs) {
@@ -271,6 +299,7 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu

    if (numArgs == 0) {
        dumpHelp(fd);
        printCurrentStatus(fd);
        return STATUS_OK;
    }

@@ -330,6 +359,14 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu
        } else {
            dprintf(fd, "Vehicle Id: %s\n", vehicleId.c_str());
        }
    } else if (!strcmp(args[0], COMMAND_INJECT_TASK)) {
        if (numArgs < 3) {
            dumpHelp(fd);
            return STATUS_OK;
        }
        debugInjectTask(fd, args[1], args[2]);
    } else if (!strcmp(args[0], COMMAND_STATUS)) {
        printCurrentStatus(fd);
    } else {
        dumpHelp(fd);
    }
@@ -337,6 +374,37 @@ binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t nu
    return STATUS_OK;
}

void RemoteAccessService::printCurrentStatus(int fd) {
    std::lock_guard<std::mutex> lockGuard(mLock);
    dprintf(fd,
            "\nRemoteAccess HAL status \n"
            "Remote task callback registered: %s\n"
            "Task receiving GRPC connection established: %s\n"
            "Received task count by clientId: \n%s\n",
            boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
            clientIdToTaskCountToStringLocked().c_str());
}

void RemoteAccessService::debugInjectTask(int fd, std::string_view clientId,
                                          std::string_view taskData) {
    std::string clientIdCopy = std::string(clientId);
    if (auto result = deliverRemoteTaskThroughCallback(clientIdCopy, taskData); !result.ok()) {
        dprintf(fd, "Failed to inject task: %s", result.error().message().c_str());
        return;
    }
    dprintf(fd, "Task for client: %s, data: [%s] successfully injected\n", clientId.data(),
            taskData.data());
}

std::string RemoteAccessService::clientIdToTaskCountToStringLocked() {
    // Print the table header
    std::string output = "| ClientId | Count |\n";
    for (const auto& [clientId, taskCount] : mClientIdToTaskCount) {
        output += StringPrintf("  %-9s  %-6zu\n", clientId.c_str(), taskCount);
    }
    return output;
}

ScopedAStatus DebugRemoteTaskCallback::onRemoteTaskRequested(const std::string& clientId,
                                                             const std::vector<uint8_t>& data) {
    std::lock_guard<std::mutex> lockGuard(mLock);