Home | History | Annotate | Download | only in hid
      1 #!/usr/bin/env python3.4
      2 #
      3 # Copyright (C) 2017 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
      6 # use this file except in compliance with the License. You may obtain a copy of
      7 # the License at
      8 #
      9 # http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     14 # License for the specific language governing permissions and limitations under
     15 # the License.
     16 """
     17 Bluetooth HID Device Test.
     18 """
     19 
     20 from acts.base_test import BaseTestClass
     21 from acts.test_decorators import test_tracker_info
     22 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     23 from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
     24 from acts.test_utils.bt.bt_test_utils import clear_bonded_devices
     25 from acts.test_utils.bt.bt_test_utils import pair_pri_to_sec
     26 from acts.test_utils.bt.bt_test_utils import hid_keyboard_report
     27 from acts.test_utils.bt.bt_test_utils import hid_device_send_key_data_report
     28 from acts.test_utils.bt.bt_constants import hid_connection_timeout
     29 from acts.test_utils.bt import bt_constants
     30 import time
     31 
     32 
     33 class HidDeviceTest(BluetoothBaseTest):
     34     tests = None
     35     default_timeout = 10
     36 
     37     def __init__(self, controllers):
     38         BaseTestClass.__init__(self, controllers)
     39         self.host_ad = self.android_devices[0]
     40         self.device_ad = self.android_devices[1]
     41 
     42     def setup_test(self):
     43         for a in self.android_devices:
     44             if not clear_bonded_devices(a):
     45                 return False
     46         for a in self.android_devices:
     47             a.ed.clear_all_events()
     48 
     49         i = 0
     50         while not self.device_ad.droid.bluetoothHidDeviceIsReady():
     51             time.sleep(1)
     52             i += 1
     53             self.log.info("BluetoothHidDevice NOT Ready")
     54             if i == 10:
     55                 return False
     56 
     57         if not self.device_ad.droid.bluetoothHidDeviceRegisterApp():
     58             self.log.error("Device: registration failed")
     59             return False
     60 
     61         self.log.info("Device: registration done")
     62         return True
     63 
     64     def teardown_test(self):
     65         self.log.info("Device: unregister")
     66         self.device_ad.droid.bluetoothHidDeviceUnregisterApp()
     67         time.sleep(2)
     68         return True
     69 
     70     @BluetoothBaseTest.bt_test_wrap
     71     @test_tracker_info(uuid='047afb31-96c5-4a56-acb5-2b216037f35d')
     72     def test_hid(self):
     73         """Test HID Host and Device basic functionality
     74 
     75         Test the HID Device framework app registration; test HID Host sending
     76         report through HID control channel and interrupt channel.
     77 
     78         Steps:
     79         1. Bluetooth HID device registers the Bluetooth input device service.
     80         2. Get the MAC address of the HID host and HID device.
     81         3. Establish HID profile connection from the HID host to the HID device.
     82         4. HID host sends set_report, get_report, set_protocol, send_data to
     83         the HID device, and check if the HID device receives them.
     84         5. HID device sends data report, report_error, reply_report commands to
     85         the HID host, and check if the HID host receives them.
     86 
     87         Expected Result:
     88         HID profile connection is successfully established; all commands and
     89         data reports are correctly handled.
     90 
     91         Returns:
     92           Pass if True
     93           Fail if False
     94 
     95         TAGS: Classic, HID
     96         Priority: 1
     97         """
     98 
     99         test_result = True
    100 
    101         pair_pri_to_sec(self.host_ad, self.device_ad, attempts=3)
    102 
    103         self.log.info("Device bonded: {}".format(
    104                 self.device_ad.droid.bluetoothGetBondedDevices()))
    105         self.log.info("Host bonded: {}".format(
    106                 self.host_ad.droid.bluetoothGetBondedDevices()))
    107 
    108         host_id = self.host_ad.droid.bluetoothGetLocalAddress()
    109         device_id = self.device_ad.droid.bluetoothGetLocalAddress()
    110 
    111         self.host_ad.droid.bluetoothConnectBonded(device_id)
    112 
    113         time.sleep(hid_connection_timeout)
    114         self.log.info("Device: connected: {}".format(
    115                 self.device_ad.droid.bluetoothHidDeviceGetConnectedDevices()))
    116 
    117         self.log.info("Host: set report")
    118         self.host_ad.droid.bluetoothHidSetReport(
    119                 device_id, 1, bt_constants.hid_default_set_report_payload)
    120 
    121         try:
    122             hid_device_callback = self.device_ad.ed.pop_event(
    123                     bt_constants.hid_on_set_report_event,
    124                     bt_constants.hid_default_event_timeout)
    125         except Empty as err:
    126             self.log.error("Callback not received: {}".format(err))
    127             test_result = False
    128 
    129         self.log.info("Host: get report")
    130         self.host_ad.droid.bluetoothHidGetReport(device_id, 1, 1, 1024)
    131 
    132         try:
    133             hid_device_callback = self.device_ad.ed.pop_event(
    134                     bt_constants.hid_on_get_report_event,
    135                     bt_constants.hid_default_event_timeout)
    136         except Empty as err:
    137             self.log.error("Callback not received: {}".format(err))
    138             test_result = False
    139 
    140         self.log.info("Host: set_protocol")
    141         self.host_ad.droid.bluetoothHidSetProtocolMode(device_id, 1)
    142 
    143         try:
    144             hid_device_callback = self.device_ad.ed.pop_event(
    145                     bt_constants.hid_on_set_protocol_event,
    146                     bt_constants.hid_default_event_timeout)
    147         except Empty as err:
    148             self.log.error("Callback not received: {}".format(err))
    149             test_result = False
    150 
    151         self.log.info("Host: send data")
    152         self.host_ad.droid.bluetoothHidSendData(device_id, "It's a report")
    153 
    154         try:
    155             hid_device_callback = self.device_ad.ed.pop_event(
    156                     bt_constants.hid_on_intr_data_event,
    157                     bt_constants.hid_default_event_timeout)
    158         except Empty as err:
    159             self.log.error("Callback not received: {}".format(err))
    160             test_result = False
    161 
    162         self.log.info("Device: send data report through interrupt channel")
    163         hid_device_send_key_data_report(host_id, self.device_ad, "04")
    164         hid_device_send_key_data_report(host_id, self.device_ad, "05")
    165 
    166         self.log.info("Device: report error")
    167         self.device_ad.droid.bluetoothHidDeviceReportError(host_id, 1)
    168 
    169         self.log.info("Device: reply report")
    170         self.device_ad.droid.bluetoothHidDeviceReplyReport(
    171                 host_id, 1, 1, hid_keyboard_report("04"))
    172 
    173         self.log.info("Device bonded: {}".format(
    174                       self.device_ad.droid.bluetoothGetBondedDevices()))
    175         self.log.info("Host bonded: {}".format(
    176                       self.host_ad.droid.bluetoothGetBondedDevices()))
    177 
    178         return test_result
    179 
    180     @BluetoothBaseTest.bt_test_wrap
    181     @test_tracker_info(uuid='5ddc3eb1-2b8d-43b5-bdc4-ba577d90481d')
    182     def test_hid_host_unplug(self):
    183         """Test HID Host Virtual_cable_unplug
    184 
    185         Test the HID host and HID device handle Virtual_cable_unplug correctly
    186 
    187         Steps:
    188         1. Bluetooth HID device registers the Bluetooth input device service.
    189         2. Get the MAC address of the HID host and HID device.
    190         3. Establish HID profile connection from the HID host to the HID device.
    191         4. HID host sends virtual_cable_unplug command to the HID device.
    192 
    193         Expected Result:
    194         HID profile connection is successfully established; After the HID host
    195         sends virtual_cable_unplug command to the HID device, both disconnect
    196         each other, but not unpair.
    197 
    198         Returns:
    199           Pass if True
    200           Fail if False
    201 
    202         TAGS: Classic, HID
    203         Priority: 2
    204         """
    205 
    206         test_result = True
    207         pair_pri_to_sec(self.host_ad, self.device_ad, attempts=3)
    208 
    209         self.log.info("Device bonded: {}".format(
    210                       self.device_ad.droid.bluetoothGetBondedDevices()))
    211         self.log.info("Host bonded: {}".format(
    212                       self.host_ad.droid.bluetoothGetBondedDevices()))
    213 
    214         host_id = self.host_ad.droid.bluetoothGetLocalAddress()
    215         device_id = self.device_ad.droid.bluetoothGetLocalAddress()
    216 
    217         self.host_ad.droid.bluetoothConnectBonded(device_id)
    218 
    219         time.sleep(hid_connection_timeout)
    220         self.log.info("Device connected: {}".format(
    221                 self.device_ad.droid.bluetoothHidDeviceGetConnectedDevices()))
    222 
    223         self.log.info("Device: send data report through interrupt channel")
    224         hid_device_send_key_data_report(host_id, self.device_ad, "04")
    225         hid_device_send_key_data_report(host_id, self.device_ad, "05")
    226 
    227         self.log.info("Host: virtual unplug")
    228         self.host_ad.droid.bluetoothHidVirtualUnplug(device_id)
    229 
    230         try:
    231             hid_device_callback = self.device_ad.ed.pop_event(
    232                     bt_constants.hid_on_virtual_cable_unplug_event,
    233                     bt_constants.hid_default_event_timeout)
    234         except Empty as err:
    235             self.log.error("Callback not received: {}".format(err))
    236             test_result = False
    237 
    238         self.log.info("Device bonded: {}".format(
    239                 self.device_ad.droid.bluetoothGetBondedDevices()))
    240         self.log.info("Host bonded: {}".format(
    241                 self.host_ad.droid.bluetoothGetBondedDevices()))
    242 
    243         if self.device_ad.droid.bluetoothGetBondedDevices():
    244             self.log.error("HID device didn't unbond on virtual_cable_unplug")
    245             test_result = False
    246 
    247         if self.host_ad.droid.bluetoothGetBondedDevices():
    248             self.log.error("HID host didn't unbond on virtual_cable_unplug")
    249             test_result = False
    250 
    251         return test_result
    252 
    253