Home | History | Annotate | Download | only in car_bt
      1 #/usr/bin/env python3.4
      2 #
      3 # Copyright (C) 2016 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 Test the HFP profile for calling and connection management.
     18 """
     19 
     20 import time
     21 
     22 from acts.test_decorators import test_tracker_info
     23 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     24 from acts.test_utils.bt.BluetoothCarHfpBaseTest import BluetoothCarHfpBaseTest
     25 from acts.test_utils.bt import BtEnum
     26 from acts.test_utils.bt import bt_test_utils
     27 from acts.test_utils.car import car_bt_utils
     28 from acts.test_utils.car import car_telecom_utils
     29 from acts.test_utils.tel import tel_defines
     30 from acts.test_utils.tel.tel_test_utils import hangup_call
     31 from acts.test_utils.tel.tel_test_utils import initiate_call
     32 from acts.test_utils.tel.tel_test_utils import wait_and_answer_call
     33 
     34 BLUETOOTH_PKG_NAME = "com.android.bluetooth"
     35 CALL_TYPE_OUTGOING = "CALL_TYPE_OUTGOING"
     36 CALL_TYPE_INCOMING = "CALL_TYPE_INCOMING"
     37 default_timeout = 20
     38 
     39 
     40 class BtCarHfpConnectionTest(BluetoothCarHfpBaseTest):
     41     def setup_class(self):
     42         if not super(BtCarHfpConnectionTest, self).setup_class():
     43             return False
     44 
     45         # Disable all
     46         car_bt_utils.set_car_profile_priorities_off(self.hf, self.ag)
     47 
     48         # Enable A2DP
     49         bt_test_utils.set_profile_priority(
     50             self.hf, self.ag, [BtEnum.BluetoothProfile.HEADSET_CLIENT],
     51             BtEnum.BluetoothPriorityLevel.PRIORITY_ON)
     52 
     53         return True
     54 
     55     def setup_test(self):
     56         if not super(BtCarHfpConnectionTest, self).setup_test():
     57             return False
     58         self.hf.droid.bluetoothDisconnectConnected(
     59             self.ag.droid.bluetoothGetLocalAddress())
     60 
     61     @test_tracker_info(uuid='a6669f9b-fb49-4bd8-aa9c-9d6369e34442')
     62     @BluetoothBaseTest.bt_test_wrap
     63     def test_call_transfer_disconnect_connect(self):
     64         """
     65         Tests that after we connect when an active call is in progress,
     66         we show the call.
     67 
     68         Precondition:
     69         1. AG & HF are disconnected but paired.
     70 
     71         Steps:
     72         1. Make a call from AG role (since disconnected)
     73         2. Accept from RE role and transition the call to Active
     74         3. Connect AG & HF
     75         4. HF should transition into Active call state.
     76 
     77         Returns:
     78           Pass if True
     79           Fail if False
     80 
     81         Priority: 1
     82         """
     83         # make a call on AG
     84         if not initiate_call(self.log, self.ag, self.re_phone_number):
     85             self.ag.log.error("Failed to initiate call from ag.")
     86             return False
     87         if not wait_and_answer_call(self.log, self.re):
     88             self.re.log.error("Failed to accept call on re.")
     89             return False
     90 
     91         # Wait for AG, RE to go into an Active state.
     92         if not car_telecom_utils.wait_for_active(self.log, self.ag):
     93             self.ag.log.error("AG not in Active state.")
     94             return False
     95         if not car_telecom_utils.wait_for_active(self.log, self.re):
     96             self.re.log.error("RE not in Active state.")
     97             return False
     98 
     99         # Now connect the devices.
    100         if not bt_test_utils.connect_pri_to_sec(
    101                 self.hf, self.ag,
    102                 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
    103             self.log.error("Could not connect HF and AG {} {}".format(
    104                 self.hf.serial, self.ag.serial))
    105             return False
    106 
    107         # Check that HF is in active state
    108         if not car_telecom_utils.wait_for_active(self.log, self.hf):
    109             self.hf.log.error("HF not in Active state.")
    110             return False
    111 
    112         # Hangup the call and check all devices are clean
    113         self.hf.droid.telecomEndCall()
    114         ret = True
    115         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
    116         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
    117         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)
    118 
    119         return ret
    120 
    121     @test_tracker_info(uuid='97727b64-a590-4d84-a257-1facd8aafd16')
    122     @BluetoothBaseTest.bt_test_wrap
    123     def test_call_transfer_off_on(self):
    124         """
    125         Tests that after we turn adapter on when an active call is in
    126         progress, we show the call.
    127 
    128         Precondition:
    129         1. AG & HF are disconnected but paired.
    130         2. HF's adapter is OFF
    131 
    132         Steps:
    133         1. Make a call from AG role (since disconnected)
    134         2. Accept from RE role and transition the call to Active
    135         3. Turn HF's adapter ON
    136         4. HF should transition into Active call state.
    137 
    138         Returns:
    139           Pass if True
    140           Fail if False
    141 
    142         Priority: 1
    143         """
    144         # Connect HF & AG
    145         if not bt_test_utils.connect_pri_to_sec(
    146                 self.hf, self.ag,
    147                 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
    148             self.log.error("Could not connect HF and AG {} {}".format(
    149                 self.hf.serial, self.ag.serial))
    150             return False
    151 
    152         # make a call on AG
    153         if not initiate_call(self.log, self.ag, self.re_phone_number):
    154             self.ag.log.error("Failed to initiate call from ag.")
    155             return False
    156 
    157         # Wait for all HF
    158         if not car_telecom_utils.wait_for_dialing(self.log, self.hf):
    159             self.hf.log.error("HF not in ringing state.")
    160             return False
    161 
    162         # Accept the call on RE
    163         if not wait_and_answer_call(self.log, self.re):
    164             self.re.log.error("Failed to accept call on re.")
    165             return False
    166         # Wait for all HF, AG, RE to go into an Active state.
    167         if not car_telecom_utils.wait_for_active(self.log, self.hf):
    168             self.hf.log.error("HF not in Active state.")
    169             return False
    170         if not car_telecom_utils.wait_for_active(self.log, self.ag):
    171             self.ag.log.error("AG not in Active state.")
    172             return False
    173         if not car_telecom_utils.wait_for_active(self.log, self.re):
    174             self.re.log.error("RE not in Active state.")
    175             return False
    176 
    177         # Turn the adapter OFF on HF
    178         if not bt_test_utils.disable_bluetooth(self.hf.droid):
    179             self.hf.log.error("Failed to turn BT off on HF.")
    180             return False
    181 
    182         # Turn adapter ON on HF
    183         if not bt_test_utils.enable_bluetooth(self.hf.droid, self.hf.ed):
    184             self.hf.log.error("Failed to turn BT ON after call on HF.")
    185             return False
    186 
    187         # Check that HF is in active state
    188         if not car_telecom_utils.wait_for_active(self.log, self.hf):
    189             self.hf.log.error("HF not in Active state.")
    190             return False
    191 
    192         # Hangup the call and check all devices are clean
    193         self.hf.droid.telecomEndCall()
    194         ret = True
    195         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
    196         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
    197         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)
    198 
    199         return ret
    200 
    201     @test_tracker_info(uuid='95f76e2c-1cdd-4a7c-8e26-863b4c4242be')
    202     @BluetoothBaseTest.bt_test_wrap
    203     def test_call_transfer_connect_disconnect_connect(self):
    204         """
    205         Test that when we go from connect -> disconnect -> connect on an active
    206         call then the call is restored on HF.
    207 
    208         Precondition:
    209         1. AG & HF are paired
    210 
    211         Steps:
    212         0. Connect AG & HF
    213         1. Make a call from HF role
    214         2. Accept from RE role and transition the call to Active
    215         3. Disconnect AG & HF
    216         4. Verify that we don't have any calls on HF
    217         5. Connect AG & HF
    218         6. Verify that HF gets the call back.
    219 
    220         Returns:
    221           Pass if True
    222           Fail if False
    223 
    224         Priority: 1
    225         """
    226         # Now connect the devices.
    227         if not bt_test_utils.connect_pri_to_sec(
    228                 self.hf, self.ag,
    229                 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
    230             self.log.error("Could not connect HF and AG {} {}".format(
    231                 self.hf.serial, self.ag.serial))
    232             return False
    233 
    234         # make a call on HF
    235         if not car_telecom_utils.dial_number(self.log, self.hf,
    236                                              self.re_phone_number):
    237             self.hf.log.error("HF not in dialing state.")
    238             return False
    239 
    240         # Wait for HF, AG to be dialing and RE to be ringing
    241         ret = True
    242         ret &= car_telecom_utils.wait_for_dialing(self.log, self.hf)
    243         #uncomment once sl4a code has been merged.
    244         ret &= car_telecom_utils.wait_for_dialing(self.log, self.ag)
    245         ret &= car_telecom_utils.wait_for_ringing(self.log, self.re)
    246 
    247         if not ret:
    248             self.log.error("Outgoing call did not get established")
    249             return False
    250 
    251         # Accept call on RE.
    252         if not wait_and_answer_call(self.log, self.re):
    253             self.re.log.error("Failed to accept call on re.")
    254             return False
    255 
    256         ret &= car_telecom_utils.wait_for_active(self.log, self.hf)
    257         ret &= car_telecom_utils.wait_for_active(self.log, self.ag)
    258         ret &= car_telecom_utils.wait_for_active(self.log, self.re)
    259 
    260         if not ret:
    261             self.log.error("Outgoing call did not transition to active")
    262             return False
    263 
    264         # Disconnect HF & AG
    265         self.hf.droid.bluetoothDisconnectConnected(
    266             self.ag.droid.bluetoothGetLocalAddress())
    267 
    268         # We use the proxy of the Call going away as HF disconnected
    269         if not car_telecom_utils.wait_for_not_in_call(self.log, self.hf):
    270             self.hf.log.error("HF still in call after disconnection.")
    271             return False
    272 
    273         # Now connect the devices.
    274         if not bt_test_utils.connect_pri_to_sec(
    275                 self.hf, self.ag,
    276                 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
    277             self.log.error("Could not connect HF and AG {} {}".format(
    278                 self.hf.serial, self.ag.serial))
    279             # Additional profile connection check for b/
    280             if not bt_test_utils.is_hfp_client_device_connected(
    281                     self.hf, self.ag.droid.bluetoothGetLocalAddress()):
    282                 self.hf.log.info(
    283                     "HFP Client connected even though connection state changed "
    284                     + " event not found")
    285                 return False
    286 
    287         # Check that HF is in active state
    288         if not car_telecom_utils.wait_for_active(self.log, self.hf):
    289             self.hf.log.error("HF not in Active state.")
    290             return False
    291 
    292         # Hangup the call and check all devices are clean
    293         self.hf.droid.telecomEndCall()
    294         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
    295         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
    296         ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)
    297 
    298         return ret
    299