Add debug command to remote access HAL.
Add debug command to test remote access HAL.
Bug: 241483300
Test: Follow:
change file sytem to read-write.
m -j TestWakeupClientServer
adb push
out/target/product/emulator_car64_x86_64/vendor/bin/TestWakeupClientServer
/vendor/bin
In one adb shell:
/vendor/bin/TestWakeupClientServer
In another shell:
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --start-debug-callback
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task
[should show no tasks]
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --ready-for-remote-task 1
[wait for 5s]
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task
[should see all the tasks from client ID 1]
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --ready-for-remote-task 0
[wait for 5s]
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task
[should see no new tasks]
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default
--ready-for-remote-task 1
dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task
[should see new tasks]
Change-Id: I551bf9ab5b55c4de9d8382d69bd5078ec62cad51
diff --git a/automotive/remoteaccess/hal/default/Android.bp b/automotive/remoteaccess/hal/default/Android.bp
index 25bda3e..2502079 100644
--- a/automotive/remoteaccess/hal/default/Android.bp
+++ b/automotive/remoteaccess/hal/default/Android.bp
@@ -29,6 +29,7 @@
"RemoteAccessService",
],
shared_libs: [
+ "libbase",
"libbinder_ndk",
"liblog",
"libutils",
@@ -56,6 +57,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
+ "libcutils",
"liblog",
"libutils",
"libgrpc++",
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 806440a..207c093 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -18,8 +18,11 @@
#include <aidl/android/hardware/automotive/remoteaccess/ApState.h>
#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteAccess.h>
+#include <aidl/android/hardware/automotive/remoteaccess/BnRemoteTaskCallback.h>
#include <aidl/android/hardware/automotive/remoteaccess/IRemoteTaskCallback.h>
#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <utils/SystemClock.h>
#include <wakeup_client.grpc.pb.h>
#include <string>
@@ -30,6 +33,27 @@
namespace automotive {
namespace remoteaccess {
+// A IRemoteTaskCallback implementation for debug purpose.
+class DebugRemoteTaskCallback final
+ : public aidl::android::hardware::automotive::remoteaccess::BnRemoteTaskCallback {
+ public:
+ DebugRemoteTaskCallback() { mStartTimeMillis = android::uptimeMillis(); };
+
+ ndk::ScopedAStatus onRemoteTaskRequested(const std::string& clientId,
+ const std::vector<uint8_t>& data) override;
+ std::string printTasks();
+
+ private:
+ struct TaskData {
+ std::string clientId;
+ std::vector<uint8_t> data;
+ };
+
+ std::mutex mLock;
+ int64_t mStartTimeMillis;
+ std::vector<TaskData> mTasks;
+};
+
class RemoteAccessService
: public aidl::android::hardware::automotive::remoteaccess::BnRemoteAccess {
public:
@@ -51,10 +75,14 @@
ndk::ScopedAStatus notifyApStateChange(
const aidl::android::hardware::automotive::remoteaccess::ApState& newState) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
private:
// For testing.
friend class RemoteAccessServiceUnitTest;
+ static bool checkDumpPermission();
+
WakeupClient::StubInterface* mGrpcStub;
std::thread mThread;
std::mutex mLock;
@@ -69,12 +97,14 @@
bool mTaskLoopRunning GUARDED_BY(mStartStopTaskLoopLock);
// Default wait time before retry connecting to remote access client is 10s.
size_t mRetryWaitInMs = 10'000;
+ std::shared_ptr<DebugRemoteTaskCallback> mDebugCallback;
void runTaskLoop();
void maybeStartTaskLoop();
void maybeStopTaskLoop();
void setRetryWaitInMs(size_t retryWaitInMs) { mRetryWaitInMs = retryWaitInMs; }
+ void dumpHelp(int fd);
};
} // namespace remoteaccess
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 6c297e3..cc8b50c 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -16,8 +16,10 @@
#include "RemoteAccessService.h"
+#include <android-base/stringprintf.h>
#include <android/binder_status.h>
#include <grpc++/grpc++.h>
+#include <private/android_filesystem_config.h>
#include <utils/Log.h>
#include <chrono>
#include <thread>
@@ -32,6 +34,8 @@
using ::aidl::android::hardware::automotive::remoteaccess::ApState;
using ::aidl::android::hardware::automotive::remoteaccess::IRemoteTaskCallback;
using ::android::base::ScopedLockAssertion;
+using ::android::base::StringAppendF;
+using ::android::base::StringPrintf;
using ::grpc::ClientContext;
using ::grpc::ClientReaderInterface;
using ::grpc::Status;
@@ -39,6 +43,10 @@
using ::ndk::ScopedAStatus;
const std::string WAKEUP_SERVICE_NAME = "com.google.vehicle.wakeup";
+constexpr char COMMAND_SET_AP_STATE[] = "--set-ap-state";
+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";
std::vector<uint8_t> stringToBytes(const std::string& s) {
const char* data = s.data();
@@ -50,6 +58,18 @@
status.error_code(), (errorMsg + ", error: " + status.error_message()).c_str());
}
+std::string printBytes(const std::vector<uint8_t>& bytes) {
+ std::string s;
+ for (size_t i = 0; i < bytes.size(); i++) {
+ StringAppendF(&s, "%02x", bytes[i]);
+ }
+ return s;
+}
+
+bool checkBoolFlag(const char* flag) {
+ return !strcmp(flag, "1") || !strcmp(flag, "0");
+}
+
} // namespace
RemoteAccessService::RemoteAccessService(WakeupClient::StubInterface* grpcStub)
@@ -154,7 +174,7 @@
}
ScopedAStatus RemoteAccessService::setRemoteTaskCallback(
- [[maybe_unused]] const std::shared_ptr<IRemoteTaskCallback>& callback) {
+ const std::shared_ptr<IRemoteTaskCallback>& callback) {
std::lock_guard<std::mutex> lockGuard(mLock);
mRemoteTaskCallback = callback;
return ScopedAStatus::ok();
@@ -184,6 +204,110 @@
return ScopedAStatus::ok();
}
+bool RemoteAccessService::checkDumpPermission() {
+ uid_t uid = AIBinder_getCallingUid();
+ return uid == AID_ROOT || uid == AID_SHELL || uid == AID_SYSTEM;
+}
+
+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")
+ .c_str());
+}
+
+binder_status_t RemoteAccessService::dump(int fd, const char** args, uint32_t numArgs) {
+ if (!checkDumpPermission()) {
+ dprintf(fd, "Caller must be root, system or shell\n");
+ return STATUS_PERMISSION_DENIED;
+ }
+
+ if (numArgs == 0) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+
+ if (!strcmp(args[0], COMMAND_SET_AP_STATE)) {
+ if (numArgs < 3) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+ ApState apState = {};
+ const char* remoteTaskFlag = args[1];
+ if (!strcmp(remoteTaskFlag, "1") && !strcmp(remoteTaskFlag, "0")) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+ if (!checkBoolFlag(args[1])) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+ if (!strcmp(args[1], "1")) {
+ apState.isReadyForRemoteTask = true;
+ }
+ if (!checkBoolFlag(args[2])) {
+ dumpHelp(fd);
+ return STATUS_OK;
+ }
+ if (!strcmp(args[2], "1")) {
+ apState.isWakeupRequired = true;
+ }
+ auto status = notifyApStateChange(apState);
+ if (!status.isOk()) {
+ dprintf(fd, "Failed to set AP state, code: %d, error: %s\n", status.getStatus(),
+ status.getMessage());
+ } else {
+ dprintf(fd, "successfully set the new AP state\n");
+ }
+ } else if (!strcmp(args[0], COMMAND_START_DEBUG_CALLBACK)) {
+ mDebugCallback = ndk::SharedRefBase::make<DebugRemoteTaskCallback>();
+ setRemoteTaskCallback(mDebugCallback);
+ dprintf(fd, "Debug callback registered\n");
+ } else if (!strcmp(args[0], COMMAND_STOP_DEBUG_CALLBACK)) {
+ if (mDebugCallback) {
+ mDebugCallback.reset();
+ }
+ clearRemoteTaskCallback();
+ dprintf(fd, "Debug callback unregistered\n");
+ } else if (!strcmp(args[0], COMMAND_SHOW_TASK)) {
+ if (mDebugCallback) {
+ dprintf(fd, "%s", mDebugCallback->printTasks().c_str());
+ } else {
+ dprintf(fd, "Debug callback is not currently used, use \"%s\" first.\n",
+ COMMAND_START_DEBUG_CALLBACK);
+ }
+ } else {
+ dumpHelp(fd);
+ }
+
+ return STATUS_OK;
+}
+
+ScopedAStatus DebugRemoteTaskCallback::onRemoteTaskRequested(const std::string& clientId,
+ const std::vector<uint8_t>& data) {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ mTasks.push_back({
+ .clientId = clientId,
+ .data = data,
+ });
+ return ScopedAStatus::ok();
+}
+
+std::string DebugRemoteTaskCallback::printTasks() {
+ std::lock_guard<std::mutex> lockGuard(mLock);
+ std::string s = StringPrintf("Received %zu tasks in %f seconds", mTasks.size(),
+ (android::uptimeMillis() - mStartTimeMillis) / 1000.);
+ for (size_t i = 0; i < mTasks.size(); i++) {
+ StringAppendF(&s, "Client Id: %s, Data: %s\n", mTasks[i].clientId.c_str(),
+ printBytes(mTasks[i].data).c_str());
+ }
+ return s;
+}
+
} // namespace remoteaccess
} // namespace automotive
} // namespace hardware
diff --git a/automotive/remoteaccess/hal/default/test/Android.bp b/automotive/remoteaccess/hal/default/test/Android.bp
index e92440f..bf7d0b6 100644
--- a/automotive/remoteaccess/hal/default/test/Android.bp
+++ b/automotive/remoteaccess/hal/default/test/Android.bp
@@ -24,6 +24,7 @@
"RemoteAccessService",
],
shared_libs: [
+ "libbase",
"libbinder_ndk",
"liblog",
"libutils",