Add inject task cmd to default remoteaccess hal.
This allows local remote access HAL test. This CL also adds debug
status dump to remote access HAL.
Test: Manual run on gcar_emu
Bug: 272773565
Change-Id: Ic02b451d800cfe75d8c410a4dc52e8ce15e481b7
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 5cfca61..9aabad6 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -97,7 +97,10 @@
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 @@
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
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index d944593..bbda9df 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -36,6 +36,8 @@
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_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 @@
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 @@
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 @@
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 @@
}
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 @@
if (numArgs == 0) {
dumpHelp(fd);
+ printCurrentStatus(fd);
return STATUS_OK;
}
@@ -330,6 +359,14 @@
} 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 @@
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);