1# Android Bumble extensions 2 3While [experimental Pandora API][pandora-experimental-api-code] are implemented 4for Android, they may not be for Bumble. When writing Android Avatar tests, if 5you need one of these APIs on Bumble, you can implement it by adding a custom 6service. 7 8Note: Before going further, make sure you read the 9[Implementing your own tests](android-guide#implementing-your-own-tests) 10section of the Avatar Android guide. 11 12In the following example, we will add stub files required to write HID tests for 13the [`hid.proto`][hid-proto] interface. 14 15Note: The code for this example is available in a [WIP CL][hid-example]. 16 17## Create a new test class 18 19Follow [Create a test class](android-guide#create-a-test-class) to create a 20`HidTest` test class in `hid_test.py`. 21 22## Create a Bumble HID extension 23 24Create an HID extension file: 25 26```shell 27cd packages/modules/Bluetooth/ 28touch pandora/server/bumble_experimental/hid.py 29``` 30 31Add the following code to it: 32 33```python 34import grpc 35import logging 36 37from bumble.device import Device 38from pandora_experimental.hid_grpc import ( 39 SendHostReportRequest, 40 SendHostReportResponse, 41) 42from pandora_experimental.hid_grpc_aio import HIDServicer 43 44# This class implements the HID experimental Pandora interface. 45class HIDService(HIDServicer): 46 device: Device 47 48 def __init__(self, device: Device) -> None: 49 self.device = device 50 51 async def SendHostReport( 52 self, 53 request: SendHostReportRequest, 54 context: grpc.ServicerContext 55 ) -> SendHostReportResponse: 56 logging.info( 57 f'SendHostReport(address={request.address}, ' 58 f'type={request.report_type}, report="{request.report}")' 59 ) 60 # You should implement SendHostReport here by doing direct call to the 61 # Bumble instance (i.e. `self.device`). 62 return SendHostReportResponse() 63``` 64 65## Add an HID test to your test class 66 67In `hid_test.py`: 68 69```python 70def test_report(self) -> None: 71 from pandora_experimental.hid_grpc import HID, HidReportType 72 HID(self.ref.channel).SendHostReport( 73 address=self.dut.address, 74 report_type=HidReportType.HID_REPORT_TYPE_INPUT, 75 report="pause cafe" 76 ) 77``` 78 79### Add your HID test class to Avatar test suite runner 80 81```diff 82diff --git a/android/pandora/test/main.py b/android/pandora/test/main.py 83--- a/android/pandora/test/main.py 84+++ b/android/pandora/test/main.py 85@@ -3,18 +3,22 @@ from avatar import bumble_server 86 87 import example 88 import gatt_test 89+import hid_test 90 91 import logging 92 import sys 93 94 from bumble_experimental.gatt import GATTService 95 from pandora_experimental.gatt_grpc_aio import add_GATTServicer_to_server 96+from bumble_experimental.hid import HIDService 97+from pandora_experimental.hid_grpc_aio import add_HIDServicer_to_server 98 99-_TEST_CLASSES_LIST = [example.ExampleTest, gatt_test.GattTest] 100+_TEST_CLASSES_LIST = [example.ExampleTest, gatt_test.GattTest, hid_test.HidTest] 101 102 103 def _bumble_servicer_hook(server: bumble_server.Server) -> None: 104 add_GATTServicer_to_server(GATTService(server.bumble.device), server.server) 105+ add_HIDServicer_to_server(HIDService(server.bumble.device), server.server) 106 107 108 if __name__ == "__main__": 109``` 110 111You can now run your new HID test: 112 113```shell 114avatar run --mobly-std-log --include-filter 'HidTest' 115``` 116 117[pandora-experimental-api-code]: https://cs.android.com/android/platform/superproject/+/main:packages/modules/Bluetooth/pandora/interfaces/pandora_experimental/ 118 119[hid-proto]: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Bluetooth/pandora/interfaces/pandora_experimental/hid.proto 120 121[hid-example]: https://android-review.git.corp.google.com/c/platform/packages/modules/Bluetooth/+/2454811 122