1# Test GRPC Server. 2 3A test GRPC server that implements wakeup_client.proto. This test server acts 4as a reference implementation for a remote wakeup client running on TCU. The 5test server does not communicate with any actual network server. It has the 6following behavior: 7 8* It starts a GRPC server on 'DGRPC_SERVICE_ADDRESS' compile flag which is 9 localhost:50051. The GRPC server provides the service according to 10 hardware/interfaces/automotive/remoteaccess/hal/default/proto/wakeup_client.proto. 11 12 In real implementation, DGRPC_SERVICE_ADDRESS can be specified to any IP 13 address where the TCU can be exposed to Application Processor. The default 14 remote access HAL implementation 15 (hardware/interfaces/automotive/remoteaccess/hal/default/Android.bp) also 16 uses DGRPC_SERVICE_ADDRESS to find this GRPC server, so it must have the 17 same IP address. 18 19* It generates a fake task using FakeTaskGenerator every 'kTaskIntervalInMs' ms. 20 21 In real implementation, it should receive task from the remote server. 22 23* Each fake task has an increasing unique client ID. The task data is always 24 what's defined for 'DATA' variable. 25 26 In real implementation, the client ID and task data should come from the 27 remote server. 28 29* The generated tasks are put into a task queue which is a priority queue sorted 30 by task received time. 31 32 In real implementation, if the server provides a task timestamp, then this 33 queue can be sorted by that task timestamp instead. 34 35* When the Application processor is started, the remote access HAL running on 36 Android will call 'GetRemoteTasks' to establish a long-live connection. This 37 connection is used to deliver all task data from remote wakeup client to 38 remote access HAL, which eventually to car service and applications. 39 40 When the 'GetRemoteTasks' is called, the wakeup client must send all the 41 pending tasks through the 'ServerWriter'. If no task is pending, then it must 42 block and wait for a new task to arrive. 43 44 If one task data fails to be sent through the channel, it likely means 45 the other side (Application processor) is shutting down or has closed the 46 channel. The wakeup client must put the task back to the pending queue and 47 wait for a new 'GetRemoteTasks' request to retry sending the task. 48 49* When a new task arrives, if 'WakeupRequired' is true, then try to wakeup 50 the Application Processor by sending a specific CAN message. It is possible that 51 the waking up is already in progress. This is okay since Vehicle Processor 52 should ignore wakeup message if a wakeup is already in progress. 53 54* When 'WakeupRequired' is updated from false to true, if there are unexpired 55 pending tasks in the task queue, try to wakeup Application Processor. 56 57 This is to handle the situation when a task arrives while the device is 58 shutting down. During the device shutdown, the channel to deliver the remote 59 tasks to Application Processor is shutdown so the new task will be added to the 60 task queue. 'WakeupRequired' will be set to false to prevent the wakeup 61 message preventing the shutdown. After the shutdown is complete, 62 'WakeupRequired' will be set to true and this wakeup client must try to wake 63 up the device again to execute the pending tasks. 64 65* Every pending task has a timeout: 'kTaskTimeoutInMs'. If the pending task 66 is not delivered to remote access HAL before the timeout (through 67 GetRemoteTasks), the task timed out and a warning message is logged. 68 69 In real implementation, this kTaskTimeoutInMs has to be set long enough to 70 allow an Android bootup to happen. 20s is a reasonable value. When a task 71 timed out, the wakeup client should also report to remote task server about 72 the task timeout failure. 73 74## How to build the test wakeup client 75 76* Under android root: `source build/envsetup.sh` 77 78* Add 79 ``` 80 PRODUCT_SOONG_NAMESPACES += hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib` 81 ``` 82 83 to `device/generic/car/common/car.mk`. 84 85* `lunch sdk_car_x86_64-userdebug` 86 87* `make -j TestWakeupClientServer` 88 89* `make -j ApPOwerControlLib` 90 91## How to push the test wakeup client to a TCU which runs Android. 92 93* Make the target device writable: 94 95 `adb root` 96 97 `adb remount` (remount might take a while) 98 99 `adb reboot` 100 101 `adb root` 102 103 `adb remount` 104 105* Under android root: `cd $ANDROID_PRODUCT_OUT` 106 107* `adb push vendor/bin/TestWakeupClientServer /vendor/bin` 108 109* `adb push vendor/lib64/ApPowerControlLib.so /vendor/lib64` 110 111* `adb shell` 112 113* `su` 114 115* `/vendor/bin/TestWakeupClientServer` 116 117## How to build and test the test wakeup client using one car emulator. 118 119In this test setup we will use one car emulator 120(sdk_car_x86_64-userdebug). We assume both the TCU and the remote access HAL 121runs on the same Android system, and they communicate through local loopback 122interface. 123 124* Under android root, `source build/envsetup.sh` 125 126* Add 127 ``` 128 PRODUCT_SOONG_NAMESPACES += hardware/interfaces/automotive/remoteaccess/test_grpc_server/lib` 129 ``` 130 131 to `device/generic/car/common/car.mk`. 132 133* `lunch sdk_car_x86_64-userdebug` 134 135* `m -j` 136 137* Run the emulator, the '-read-only' flag is required to run multiple instances: 138 139 `emulator -writable-system -read-only` 140 141* The android lunch target: sdk_car_x86_64-userdebug and 142 cf_x86_64_auto-userdebug already contains the default remote access HAL. For 143 other lunch target, you can add the default remote access HAL by adding 144 'android.hardware.automotive.remoteaccess@V2-default-service' to 145 'PRODUCT_PACKAGES' variable in mk file, see `device/generic/car/common/car.mk` 146 as example. 147 148 To verify whether remote access HAL is running, you can use the following 149 command to check: 150 151 `dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default` 152 153* Make the target device writable: 154 155 `adb root` 156 157 `adb remount` (remount might take a while) 158 159 `adb reboot` 160 161 `adb root` 162 163 `adb remount` 164 165* `make -j TestWakeupClientServer` 166 167* `make -j ApPOwerControlLib` 168 169* `adb push $ANDROID_PRODUCT_OUT/vendor/bin/TestWakeupClientServer /vendor/bin` 170 171* `adb push $ANDROID_PRODUCT_OUT/vendor/lib64/ApPowerControlLib.so /vendor/lib64` 172 173* `adb shell` 174 175* `emulator_car_x86_64:/ # su` 176 177* `emulator_car_x86_64:/ # /vendor/bin/TestWakeupClientServer` 178 179* Remote access HAL should start by default when the car emulator starts. Now 180 the test wake up client should also be running and generating fake tasks. 181 182 Start a new session under android root 183 184 `source build/envsetup.sh` 185 186 `lunch sdk_car_x86_64-userdebug` 187 188 `adb shell` 189 190 `emulator_car_x86_64:/ # su` 191 192* Issue the command to start a simple debug callback that will capture all the 193 received tasks at the remote access HAL side: 194 195 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --start-debug-callback` 196 197* Issue the following debug command to remote access HAL to establish the 198 communication channel between it and the test wakeup client. This command 199 also notifies that wakeup is not required: 200 201 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0` 202 203* Wait for a while, issue the following command to show the received fake tasks: 204 205 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task` 206 207 You should expect to see some received tasks printed out. 208 209* Simulate the Application Processor is shutting down by issuing the following 210 command: 211 212 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 0` 213 214* Wait for a while, issue the following command to show received tasks again: 215 216 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task` 217 218 You should expect to see no new tasks received since remote access HAL already 219 closed the communication channel. 220 221* Simulate the Application Processor is already shutdown and wake up is required 222 now: 223 224 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 0 1` 225 226 Now you should expect to see the test wakeup client printing out messages 227 that it is trying to wake up application processor. 228 229* Simulate the Application Processor is waken up: 230 231 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --set-ap-state 1 0` 232 233* A new communication channel should have been established and all pending 234 non-expired tasks should be delivered to the remote access HAL. 235 236 `emulator_car_x86_64:/ # dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --show-task` 237 238* Now you can issue `ctrl c` on the first adb shell to stop the test wakeup 239 client. 240 241* After the test, you can use `ctrl D` to exit the adb shell. 242 243## How to build and test the test wakeup client using two car emulators. 244 245In this test case, we are going to use two car emulators, one as the 246Application Processor, one as the TCU. 247 248* Change the IP address to allow IP communication between different emulator 249 instances. For detail about why we change it this way, see [interconnecting 250 emulator instance](https://developer.android.com/studio/run/emulator-networking#connecting). 251 252 Change 'DGRPC_SERVICE_ADDRESS' in `[android_root]/hardware/interfaces/automotive/remoteaccess/test_grpc_server/impl/Android.bp` to 253 `10.0.2.15:50051`. 254 255 Change `DGRPC_SERVICE_ADDRESS` in '[android_root]/hardware/interfaces/automotive/remoteaccess/hal/defaut/Android.bp' to 256 `10.0.2.2:50051`. 257 258* Under android root: `source build/envsetup.sh` 259 260* `lunch sdk_car_x86_64-userdebug` 261 262* `m -j` 263 264* Start one car emulator as TCU 265 266 `emulator -writable-system -read-only` 267 268* Start a new shell session. Connect to the emulator's console, 269 see [Start and stop a console session](https://developer.android.com/studio/run/emulator-console#console-session) 270 for detail. 271 272 `telnet localhost 5554` 273 274* `auth auth_token` where auth_token must match the contents of the 275 `~/.emulator_console_auth_token` file. 276 277* `redir add tcp:50051:50051` 278 279* Exit the telnet session using 'ctrl-C' 280 281 Make the target device writable: 282 283 Under android root: 284 285 `source build/envsetup.sh` 286 287 `lunch sdk_car_x86_64-userdebug` 288 289 `adb root` 290 291 `adb remount` (remount might take a while) 292 293 `adb reboot` 294 295 `adb root` 296 297 `adb remount` 298 299* `make -j TestWakeupClientServer` 300 301* `adb push $ANDROID_PRODUCT_OUT/vendor/bin/TestWakeupClientServer /vendor/bin` 302 303* `adb shell` 304 305* `emulator_car_x86_64:/ # su` 306 307* `emulator_car_x86_64:/ # /vendor/bin/TestWakeupClientServer` 308 309* Start a new shell under android root, start another car emulator as the Application Processor: 310 311 `source build/envsetup.sh` 312 313 `lunch sdk_car_x86_64-userdebug` 314 315 `emulator -writable-system -read-only` 316 317* Open a new shell under android root: 318 319 `source build/envsetup.sh` 320 321 `lunch sdk_car_x86_64-userdebug` 322 323* Connect to adb shell for the application processor: 324 325 `adb -s emulator-5556 shell` 326 327 `emulator_car_x86_64:/ # su` 328 329* Follow the test instructions for one car emulator using the 'dumpsys' 330 commands. 331 332* After the test, you can use `ctrl D` to exit the adb shell. 333