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

Commit 0fbc17f2 authored by Yu Shan's avatar Yu Shan
Browse files

Make remoteaccess HAL pass VTS.

The reference remote access HAL should still pass CTS even when
the grpc remote access server does not exist. The reference
remote access HAL now allows GRPC_SERVICE_ADDRESS not to be
defined. If it is not defined, it will not try to connect
a remote server and will work in a fake mode.

Test: VtsHalAutomotiveRemoteAccess_TargetTest with an without
grpc server running.
Bug: 277967402

Change-Id: I89509ac8f8ebe9a268d3a338d6e80c24e39dc512
parent 77a4d168
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -53,7 +53,9 @@ cc_binary {
    vintf_fragments: ["remoteaccess-default-service.xml"],
    vintf_fragments: ["remoteaccess-default-service.xml"],
    init_rc: ["remoteaccess-default-service.rc"],
    init_rc: ["remoteaccess-default-service.rc"],
    cflags: [
    cflags: [
        "-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
        // Uncomment this if running on emulator and connecting to a local grpc server
        // running on host 127.0.0.1:50051 (TestWakeupClientServerHost)
        // "-DGRPC_SERVICE_ADDRESS=\"10.0.2.2:50051\"",
    ],
    ],
}
}


+5 −2
Original line number Original line Diff line number Diff line
@@ -111,6 +111,8 @@ class RemoteAccessService


    WakeupClient::StubInterface* mGrpcStub;
    WakeupClient::StubInterface* mGrpcStub;
    std::thread mThread;
    std::thread mThread;
    // Whether the GRPC server exists. Only checked and set during init.
    bool mGrpcServerExist = false;
    std::mutex mLock;
    std::mutex mLock;
    std::condition_variable mCv;
    std::condition_variable mCv;
    std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
    std::shared_ptr<aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback>
@@ -121,7 +123,7 @@ class RemoteAccessService
    // A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
    // A mutex to make sure startTaskLoop does not overlap with stopTaskLoop.
    std::mutex mStartStopTaskLoopLock;
    std::mutex mStartStopTaskLoopLock;
    bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
    bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock) = false;
    bool mGrpcConnected GUARDED_BY(mLock) = false;
    bool mGrpcReadChannelOpen GUARDED_BY(mLock) = false;
    std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);
    std::unordered_map<std::string, size_t> mClientIdToTaskCount GUARDED_BY(mLock);


    // Default wait time before retry connecting to remote access client is 10s.
    // Default wait time before retry connecting to remote access client is 10s.
@@ -143,9 +145,10 @@ class RemoteAccessService
    void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
    void debugInjectTask(int fd, std::string_view clientId, std::string_view taskData);
    void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
    void debugInjectTaskNextReboot(int fd, std::string_view clientId, std::string_view taskData,
                                   const char* latencyInSecStr);
                                   const char* latencyInSecStr);
    void updateGrpcConnected(bool connected);
    void updateGrpcReadChannelOpen(bool grpcReadChannelOpen);
    android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
    android::base::Result<void> deliverRemoteTaskThroughCallback(const std::string& clientId,
                                                                 std::string_view taskData);
                                                                 std::string_view taskData);
    bool isTaskScheduleSupported();
};
};


}  // namespace remoteaccess
}  // namespace remoteaccess
+12 −6
Original line number Original line Diff line number Diff line
@@ -30,10 +30,9 @@
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";
constexpr char SERVICE_NAME[] = "android.hardware.automotive.remoteaccess.IRemoteAccess/default";


int main(int /* argc */, char* /* argv */[]) {
int main(int /* argc */, char* /* argv */[]) {
#ifndef GRPC_SERVICE_ADDRESS
    android::hardware::automotive::remoteaccess::WakeupClient::StubInterface* grpcStub = nullptr;
    LOG(ERROR) << "GRPC_SERVICE_ADDRESS is not defined, exiting";

    exit(1);
#ifdef GRPC_SERVICE_ADDRESS
#endif
    LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
    LOG(INFO) << "Registering RemoteAccessService as service, server: " << GRPC_SERVICE_ADDRESS
              << "...";
              << "...";
    grpc::ChannelArguments grpcargs = {};
    grpc::ChannelArguments grpcargs = {};
@@ -47,11 +46,18 @@ int main(int /* argc */, char* /* argv */[]) {
    android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
    android::netdevice::waitFor({GRPC_SERVICE_IFNAME},
                                android::netdevice::WaitCondition::PRESENT_AND_UP);
                                android::netdevice::WaitCondition::PRESENT_AND_UP);
    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
    LOG(INFO) << "Waiting for interface: " << GRPC_SERVICE_IFNAME << " done";
#endif
#endif  // #ifdef GRPC_SERVICE_IFNAME
    auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
    auto channel = grpc::CreateChannel(GRPC_SERVICE_ADDRESS, grpc::InsecureChannelCredentials());
    auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);
    auto clientStub = android::hardware::automotive::remoteaccess::WakeupClient::NewStub(channel);

    grpcStub = clientStub.get();

#else
    LOG(INFO) << "GRPC_SERVICE_ADDRESS is not defined, work in fake mode";
#endif  // #ifdef GRPC_SERVICE_ADDRESS

    auto service = ndk::SharedRefBase::make<
    auto service = ndk::SharedRefBase::make<
            android::hardware::automotive::remoteaccess::RemoteAccessService>(clientStub.get());
            android::hardware::automotive::remoteaccess::RemoteAccessService>(grpcStub);


    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
    binder_exception_t err = AServiceManager_addService(service->asBinder().get(), SERVICE_NAME);
    if (err != EX_NONE) {
    if (err != EX_NONE) {
+61 −7
Original line number Original line Diff line number Diff line
@@ -103,6 +103,10 @@ std::string boolToString(bool x) {


RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
    : mGrpcStub(grpcStub) {
    : mGrpcStub(grpcStub) {
    if (mGrpcStub != nullptr) {
        mGrpcServerExist = true;
    }

    std::ifstream debugTaskFile;
    std::ifstream debugTaskFile;
    debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in);
    debugTaskFile.open(DEBUG_TASK_FILE, std::ios::in);
    if (!debugTaskFile.is_open()) {
    if (!debugTaskFile.is_open()) {
@@ -177,9 +181,9 @@ void RemoteAccessService::maybeStopTaskLoop() {
    mTaskLoopRunning = false;
    mTaskLoopRunning = false;
}
}


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


Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
Result<void> RemoteAccessService::deliverRemoteTaskThroughCallback(const std::string& clientId,
@@ -213,7 +217,7 @@ void RemoteAccessService::runTaskLoop() {
            mGetRemoteTasksContext.reset(new ClientContext());
            mGetRemoteTasksContext.reset(new ClientContext());
            reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
            reader = mGrpcStub->GetRemoteTasks(mGetRemoteTasksContext.get(), request);
        }
        }
        updateGrpcConnected(true);
        updateGrpcReadChannelOpen(true);
        GetRemoteTasksResponse response;
        GetRemoteTasksResponse response;
        while (reader->Read(&response)) {
        while (reader->Read(&response)) {
            ALOGI("Receiving one task from remote task client");
            ALOGI("Receiving one task from remote task client");
@@ -225,7 +229,7 @@ void RemoteAccessService::runTaskLoop() {
                continue;
                continue;
            }
            }
        }
        }
        updateGrpcConnected(false);
        updateGrpcReadChannelOpen(false);
        Status status = reader->Finish();
        Status status = reader->Finish();
        mGetRemoteTasksContext.reset();
        mGetRemoteTasksContext.reset();


@@ -298,6 +302,11 @@ ScopedAStatus RemoteAccessService::clearRemoteTaskCallback() {
}
}


ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState) {
ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState) {
    if (!mGrpcServerExist) {
        ALOGW("GRPC server does not exist, do nothing");
        return ScopedAStatus::ok();
    }

    ClientContext context;
    ClientContext context;
    NotifyWakeupRequiredRequest request = {};
    NotifyWakeupRequiredRequest request = {};
    request.set_iswakeuprequired(newState.isWakeupRequired);
    request.set_iswakeuprequired(newState.isWakeupRequired);
@@ -315,19 +324,40 @@ ScopedAStatus RemoteAccessService::notifyApStateChange(const ApState& newState)
    return ScopedAStatus::ok();
    return ScopedAStatus::ok();
}
}


bool RemoteAccessService::isTaskScheduleSupported() {
    if (!mGrpcServerExist) {
        ALOGW("GRPC server does not exist, task scheduling not supported");
        return false;
    }

    return true;
}

ScopedAStatus RemoteAccessService::isTaskScheduleSupported(bool* out) {
ScopedAStatus RemoteAccessService::isTaskScheduleSupported(bool* out) {
    *out = true;
    *out = isTaskScheduleSupported();
    return ScopedAStatus::ok();
    return ScopedAStatus::ok();
}
}


ndk::ScopedAStatus RemoteAccessService::getSupportedTaskTypesForScheduling(
ndk::ScopedAStatus RemoteAccessService::getSupportedTaskTypesForScheduling(
        std::vector<TaskType>* out) {
        std::vector<TaskType>* out) {
    out->clear();
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, return empty task types");
        return ScopedAStatus::ok();
    }

    // TODO(b/316233421): support ENTER_GARAGE_MODE type.
    // TODO(b/316233421): support ENTER_GARAGE_MODE type.
    out->push_back(TaskType::CUSTOM);
    out->push_back(TaskType::CUSTOM);
    return ScopedAStatus::ok();
    return ScopedAStatus::ok();
}
}


ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo) {
ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo) {
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, return exception");
        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                           "task scheduling is not supported");
    }

    ClientContext context;
    ClientContext context;
    ScheduleTaskRequest request = {};
    ScheduleTaskRequest request = {};
    ScheduleTaskResponse response = {};
    ScheduleTaskResponse response = {};
@@ -379,6 +409,11 @@ ScopedAStatus RemoteAccessService::scheduleTask(const ScheduleInfo& scheduleInfo


ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
                                                  const std::string& scheduleId) {
                                                  const std::string& scheduleId) {
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, do nothing");
        return ScopedAStatus::ok();
    }

    ClientContext context;
    ClientContext context;
    UnscheduleTaskRequest request = {};
    UnscheduleTaskRequest request = {};
    UnscheduleTaskResponse response = {};
    UnscheduleTaskResponse response = {};
@@ -392,6 +427,11 @@ ScopedAStatus RemoteAccessService::unscheduleTask(const std::string& clientId,
}
}


ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientId) {
ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientId) {
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, do nothing");
        return ScopedAStatus::ok();
    }

    ClientContext context;
    ClientContext context;
    UnscheduleAllTasksRequest request = {};
    UnscheduleAllTasksRequest request = {};
    UnscheduleAllTasksResponse response = {};
    UnscheduleAllTasksResponse response = {};
@@ -405,6 +445,12 @@ ScopedAStatus RemoteAccessService::unscheduleAllTasks(const std::string& clientI


ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,
ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,
                                                   const std::string& scheduleId, bool* out) {
                                                   const std::string& scheduleId, bool* out) {
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, return false");
        *out = false;
        return ScopedAStatus::ok();
    }

    ClientContext context;
    ClientContext context;
    IsTaskScheduledRequest request = {};
    IsTaskScheduledRequest request = {};
    IsTaskScheduledResponse response = {};
    IsTaskScheduledResponse response = {};
@@ -420,6 +466,12 @@ ScopedAStatus RemoteAccessService::isTaskScheduled(const std::string& clientId,


ScopedAStatus RemoteAccessService::getAllPendingScheduledTasks(const std::string& clientId,
ScopedAStatus RemoteAccessService::getAllPendingScheduledTasks(const std::string& clientId,
                                                               std::vector<ScheduleInfo>* out) {
                                                               std::vector<ScheduleInfo>* out) {
    if (!isTaskScheduleSupported()) {
        ALOGW("Task scheduleing is not supported, return empty array");
        out->clear();
        return ScopedAStatus::ok();
    }

    ClientContext context;
    ClientContext context;
    GetAllPendingScheduledTasksRequest request = {};
    GetAllPendingScheduledTasksRequest request = {};
    GetAllPendingScheduledTasksResponse response = {};
    GetAllPendingScheduledTasksResponse response = {};
@@ -560,9 +612,11 @@ void RemoteAccessService::printCurrentStatus(int fd) {
    dprintf(fd,
    dprintf(fd,
            "\nRemoteAccess HAL status \n"
            "\nRemoteAccess HAL status \n"
            "Remote task callback registered: %s\n"
            "Remote task callback registered: %s\n"
            "Task receiving GRPC connection established: %s\n"
            "GRPC server exist: %s\n"
            "GRPC read channel for receiving tasks open: %s\n"
            "Received task count by clientId: \n%s\n",
            "Received task count by clientId: \n%s\n",
            boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcConnected).c_str(),
            boolToString(mRemoteTaskCallback.get()).c_str(), boolToString(mGrpcServerExist).c_str(),
            boolToString(mGrpcReadChannelOpen).c_str(),
            clientIdToTaskCountToStringLocked().c_str());
            clientIdToTaskCountToStringLocked().c_str());
}
}