Create a README and change log to print.
Add a README for documentation. Change log to printf so that
it has less android dependency and easier for showing the
message.
Test: Local run following the document.
Bug: 253627094
Change-Id: Ic7377ce763fdbd8599736a745942c1a0e27bc063
diff --git a/automotive/remoteaccess/test_grpc_server/README.md b/automotive/remoteaccess/test_grpc_server/README.md
index deea764..41c8ee1 100644
--- a/automotive/remoteaccess/test_grpc_server/README.md
+++ b/automotive/remoteaccess/test_grpc_server/README.md
@@ -1,7 +1,211 @@
# Test GRPC Server.
A test GRPC server that implements wakeup_client.proto. This test server acts
-as a reference implementation for a remote wakeup client running on TCU. This
-reference server also implements wakeup_client_debug.proto which is the
-debugging interface. It is recommended that the actual implementation also
-implements this test interface for easier end-to-end testing.
+as a reference implementation for a remote wakeup client running on TCU. The
+test server does not communicate with any actual network server. It has the
+following behavior:
+
+* It starts a GRPC server on 'DGRPC_SERVICE_ADDRESS' compile flag which is
+ localhost:50051. The GRPC server provides the service according to
+ hardware/interfaces/automotive/remoteaccess/hal/default/proto/wakeup_client.proto.
+
+ In real implementation, DGRPC_SERVICE_ADDRESS can be specified to any IP
+ address where the TCU can be exposed to Application Processor. The default
+ remote access HAL implementation
+ (hardware/interfaces/automotive/remoteaccess/hal/default/Android.bp) also
+ uses DGRPC_SERVICE_ADDRESS to find this GRPC server, so it must have the
+ same IP address.
+
+* It generates a fake task using FakeTaskGenerator every 'kTaskIntervalInMs' ms.
+
+ In real implementation, it should receive task from the remote server.
+
+* Each fake task has an increasing unique client ID. The task data is always
+ what's defined for 'DATA' variable.
+
+ In real implementation, the client ID and task data should come from the
+ remote server.
+
+* The generated tasks are put into a task queue which is a priority queue sorted
+ by task received time.
+
+ In real implementation, if the server provides a task timestamp, then this
+ queue can be sorted by that task timestamp instead.
+
+* When the Application processor is started, the remote access HAL running on
+ Android will call 'GetRemoteTasks' to establish a long-live connection. This
+ connection is used to deliver all task data from remote wakeup client to
+ remote access HAL, which eventually to car service and applications.
+
+ When the 'GetRemoteTasks' is called, the wakeup client must send all the
+ pending tasks through the 'ServerWriter'. If no task is pending, then it must
+ block and wait for a new task to arrive.
+
+ If one task data is failed to be sent through the channel, it likely means
+ the other side (Application processor) is shutting down or has closed the
+ channel. The wakeup client must put the task back to the pending queue and
+ wait for a new 'GetRemoteTasks' request to retry sending the task.
+
+* When a new task arrives, if 'WakeupRequired' is true, then try to wakeup
+ the Application Processor by sending a specific CAN message. It is possible that
+ the waking up is already in progress. This is okay since Vehicle Processor
+ should ignore wakeup message if a wakeup is already in progress.
+
+* When 'WakeupRequired' is updated from false to true, if there are unexpired
+ pending tasks in the task queue, try to wakeup Application Processor.
+
+ This is to handle the situation when a task arrives while the device is
+ shutting down. During the device shutdown, the channel to deliver the remote
+ tasks to Application Processor is shutdown so the new task will be added to the
+ task queue. 'WakeupRequired' will be set to false to prevent the wakeup
+ message preventing the shutdown. After the shutdown is complete,
+ 'WakeupRequired' will be set to true and this wakeup client must try to wake
+ up the device again to execute the pending tasks.
+
+* Every pending task has a timeout: 'KTaskTimeoutInMs'. If the pending task
+ is not delivered to remote access HAL before the timeout (through
+ GetRemoteTasks), the task timed out and a warning message is logged.
+
+ In real implementation, this kTaskTimeoutInMs has to be set long enough to
+ allow an Android bootup to happen. 20s is a reasonable value. When a task
+ timed out, the wakeup client should also report to remote task server about
+ the task timeout failure.
+
+## How to build the test wakeup client
+
+* Under android root: `make -j TestWakeupClientServer`
+
+## How to push the test wakeup client to a TCU which runs Android.
+
+* Make the target device writable:
+
+ `adb root`
+
+ `adb remount`
+
+ `adb reboot`
+
+ `adb root`
+
+ `adb remount`
+
+* Under android root: `cd out/target/product/[product_name]`
+
+* `adb push vendor/bin/TestWakeupClientServer /vendor/bin`
+
+* `adb shell`
+
+* `su`
+
+* `/vendor/bin/TestWakeupClientServer`
+
+## How to build and test the test wakeup client using one gcar emulator.
+
+In this test setup we will use one google car emulator
+(gcar_emu_x86_64-userdebug). We assume both the TCU and the remote access HAL
+runs on the same Android system, and they communicate through local loopback
+interface.
+
+* Under android root, `source build/envsetup.sh`
+
+* 'lunch gcar_emu_x86_64-userdebug'
+
+* `m -j`
+
+* Run the emulator:
+
+ `aae emulator run`
+
+* The android lunch target: gcar_emu_x86_64-userdebug and
+ cf_x86_64_auto-userdebug already contains the default remote access HAL. For
+ other lunch target, you can add the default remote access HAL by adding
+ 'android.hardware.automotive.remoteaccess@V1-default-service' to
+ 'PRODUCT_PACKAGES' variable in mk file, see `device/generic/car/common/car.mk`
+ as example.
+
+ To verify whether remote access HAL is running, you can use the following
+ command to check:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default`
+
+* Make the target device writable:
+
+ `adb root`
+
+ `adb remount`
+
+ `adb reboot`
+
+ `adb root`
+
+ `adb remount`
+
+* `make -j TestWakeupClientServer`
+
+* `cd out/target/product/emulator_car64_x86_64/`
+
+* `adb push vendor/bin/TestWakeupClientServer /vendor/bin`
+
+* `adb shell`
+
+* `su`
+
+* `/vendor/bin/TestWakeupClientServer`
+
+* Remote access HAL should start by default when the gcar emulator starts. Now
+ the test wake up client should also be running and generating fake tasks.
+
+ Start a new adb shell session by
+
+ `adb shell`
+
+ `su`
+
+* Issue the command to start a simple debug callback that will capture all the
+ received tasks at the remote access HAL side:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --start-debug-callback`
+
+* Issue the following debug command to remote access HAL to establish the
+ communication channel between it and the test wakeup client. This command
+ also notifies that wakeup is not required:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0`
+
+* Wait for a while, issue the following command to show the received fake tasks:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+ You should expect to see some received tasks printed out.
+
+* Simulate the Application Processor is shutting down by issuing the following
+ command:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 0`
+
+* Wait for a while, issue the following command to show received tasks again:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+ You should expect to see no new tasks received since remote access HAL already
+ closed the communication channel.
+
+* Simulate the Application Processor is already shutdown and wake up is required
+ now:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 1`
+
+ Now you should expect to see the test wakeup client printing out messages
+ that it is trying to wake up application processor.
+
+* Simulate the Application Processor is waken up:
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0`
+
+* A new communication channel should have been established and all pending
+ non-expired tasks should be delivered to the remote access HAL.
+
+ `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task`
+
+* Now you can issue `ctrl c` on the first adb shell to stop the test wakeup
+ client.
diff --git a/automotive/remoteaccess/test_grpc_server/impl/Android.bp b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
index 8aab2e3..e978c8c 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/Android.bp
+++ b/automotive/remoteaccess/test_grpc_server/impl/Android.bp
@@ -28,7 +28,6 @@
local_include_dirs: ["include"],
shared_libs: [
"libbase",
- "liblog",
"libutils",
"libgrpc++",
"libprotobuf-cpp-full",
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 2cdf68b..f64ac10 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -18,7 +18,6 @@
#include <android-base/stringprintf.h>
#include <inttypes.h>
-#include <utils/Log.h>
#include <utils/Looper.h>
#include <utils/SystemClock.h>
#include <chrono>
@@ -133,8 +132,6 @@
{
std::unique_lock<std::mutex> lock(mLock);
if (mStopped) {
- ALOGW("The TestWakeupClientServiceImpl is stopping, "
- "exiting checkForTestTimeoutLoop");
return;
}
}
@@ -155,8 +152,8 @@
break;
}
// In real implementation, this should report task failure to remote wakeup server.
- ALOGW("Task for client ID: %s timed-out, added at %" PRId64 " ms, now %" PRId64 " ms",
- taskInfo.taskData.clientid().c_str(), taskInfo.timestampInMs, now);
+ printf("Task for client ID: %s timed-out, added at %" PRId64 " ms, now %" PRId64 " ms",
+ taskInfo.taskData.clientid().c_str(), taskInfo.timestampInMs, now);
mTasks.pop();
}
}
@@ -182,7 +179,7 @@
// from it. Here we simulate receiving one remote task every {kTaskIntervalInMs}ms.
while (true) {
mTaskQueue.add(mFakeTaskGenerator.generateTask());
- ALOGI("Sleeping for %d seconds until next task", kTaskIntervalInMs);
+ printf("Sleeping for %d seconds until next task\n", kTaskIntervalInMs);
std::unique_lock lk(mLock);
if (mServerStoppedCv.wait_for(lk, std::chrono::milliseconds(kTaskIntervalInMs), [this] {
@@ -198,7 +195,7 @@
Status TestWakeupClientServiceImpl::GetRemoteTasks(ServerContext* context,
const GetRemoteTasksRequest* request,
ServerWriter<GetRemoteTasksResponse>* writer) {
- ALOGD("GetRemoteTasks called");
+ printf("GetRemoteTasks called\n");
while (true) {
mTaskQueue.waitForTask();
@@ -213,7 +210,7 @@
const GetRemoteTasksResponse& response = maybeTask.value();
if (!writer->Write(response)) {
// Broken stream, maybe the client is shutting down.
- ALOGW("Failed to deliver remote task to remote access HAL");
+ printf("Failed to deliver remote task to remote access HAL\n");
// The task failed to be sent, add it back to the queue. The order might change, but
// it is okay.
mTaskQueue.add(response);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
index bb03e70..52698b5 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/main.cpp
@@ -22,7 +22,6 @@
#include <grpcpp/security/server_credentials.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
-#include <utils/Log.h>
using ::android::hardware::automotive::remoteaccess::TestWakeupClientServiceImpl;
using ::grpc::Server;
@@ -38,7 +37,7 @@
builder.AddListeningPort(serverAddress, grpc::InsecureServerCredentials());
builder.RegisterService(service.get());
std::unique_ptr<Server> server(builder.BuildAndStart());
- ALOGI("Test Remote Access GRPC Server listening on %s", serverAddress.c_str());
+ printf("Test Remote Access GRPC Server listening on %s\n", serverAddress.c_str());
server->Wait();
}