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 basic calling functionality.
     18 """
     19 
     20 import time
     21 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     22 from acts.test_utils.bt.BluetoothCarHfpBaseTest import BluetoothCarHfpBaseTest
     23 from acts.test_utils.bt import BtEnum
     24 from acts.test_utils.bt import bt_test_utils
     25 from acts.test_utils.car import car_telecom_utils
     26 from acts.test_utils.car import tel_telecom_utils
     27 from acts.test_utils.tel import tel_defines
     28 
     29 BLUETOOTH_PKG_NAME = "com.android.bluetooth"
     30 CALL_TYPE_OUTGOING = "CALL_TYPE_OUTGOING"
     31 CALL_TYPE_INCOMING = "CALL_TYPE_INCOMING"
     32 SHORT_TIMEOUT = 5
     33 
     34 
     35 class BtCarHfpTest(BluetoothCarHfpBaseTest):
     36     def setup_class(self):
     37         if not super(BtCarHfpTest, self).setup_class():
     38             return False
     39         # Disable the A2DP profile.
     40         bt_test_utils.set_profile_priority(
     41             self.hf, self.ag, [BtEnum.BluetoothProfile.PBAP_CLIENT.value,
     42                                BtEnum.BluetoothProfile.A2DP_SINK.value],
     43             BtEnum.BluetoothPriorityLevel.PRIORITY_OFF)
     44         bt_test_utils.set_profile_priority(
     45             self.hf, self.ag, [BtEnum.BluetoothProfile.HEADSET_CLIENT.value],
     46             BtEnum.BluetoothPriorityLevel.PRIORITY_ON)
     47 
     48         if not bt_test_utils.connect_pri_to_sec(self.hf, self.ag, set(
     49             [BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
     50             self.log.error("Failed to connect.")
     51             return False
     52         return True
     53 
     54     #@BluetoothTest(UUID=4ce2195a-b70a-4584-912e-cbd20d20e19d)
     55     @BluetoothBaseTest.bt_test_wrap
     56     def test_default_calling_account(self):
     57         """
     58         Tests if the default calling account is coming from the
     59         bluetooth pacakge.
     60 
     61         Precondition:
     62         1. Devices are connected.
     63 
     64         Steps:
     65         1. Check if the default calling account is via Bluetooth package.
     66 
     67         Returns:
     68           Pass if True
     69           Fail if False
     70 
     71         Priority: 0
     72         """
     73         selected_acc = \
     74             self.hf.droid.telecomGetUserSelectedOutgoingPhoneAccount()
     75         if not selected_acc:
     76             self.hf.log.error("No default account found.")
     77             return False
     78 
     79         # Check if the default account is from the Bluetooth package. This is a
     80         # light weight check.
     81         try:
     82             acc_component_id = selected_acc['ComponentName']
     83         except KeyError:
     84             self.hf.log.error("No component name for account {}".format(
     85                 selected_acc))
     86             return False
     87         if not acc_component_id.startswith(BLUETOOTH_PKG_NAME):
     88             self.hf.log.error("Component name does not start with pkg name {}".
     89                           format(selected_acc))
     90             return False
     91         return True
     92 
     93     #@BluetoothTest(UUID=e579009d-05f3-4236-a698-5de8c11d73a9)
     94     @BluetoothBaseTest.bt_test_wrap
     95     def test_outgoing_call_hf(self):
     96         """
     97         Tests if we can make a phone call from HF role and disconnect from HF
     98         role.
     99 
    100         Precondition:
    101         1. Devices are connected.
    102 
    103         Steps:
    104         1. Make a call from HF role.
    105         2. Wait for the HF, AG to be dialing and RE to see the call ringing.
    106         3. Hangup the call on HF role.
    107         4. Wait for all devices to hangup the call.
    108 
    109         Returns:
    110           Pass if True
    111           Fail if False
    112 
    113         Priority: 0
    114         """
    115         return self.dial_a_hangup_b(self.hf, self.hf)
    116 
    117     #@BluetoothTest(UUID=c9d5f9cd-f275-4adf-b212-c2e9a70d4cac)
    118     @BluetoothBaseTest.bt_test_wrap
    119     def test_outgoing_call_ag(self):
    120         """
    121         Tests if we can make a phone call from AG role and disconnect from AG
    122         role.
    123 
    124         Precondition:
    125         1. Devices are connected.
    126 
    127         Steps:
    128         1. Make a call from AG role.
    129         2. Wait for the HF, AG to be in dialing and RE to see the call ringing.
    130         3. Hangup the call on AG role.
    131         4. Wait for all devices to hangup the call.
    132 
    133         Returns:
    134           Pass if True
    135           Fail if False
    136 
    137         Priority: 0
    138         """
    139         return self.dial_a_hangup_b(self.ag, self.ag)
    140 
    141     #@BluetoothTest(UUID=908c199b-ca65-4694-821d-1b864ee3fe69)
    142     @BluetoothBaseTest.bt_test_wrap
    143     def test_outgoing_dial_ag_hangup_hf(self):
    144         """
    145         Tests if we can make a phone call from AG role and disconnect from HF
    146         role.
    147 
    148         Precondition:
    149         1. Devices are connected.
    150 
    151         Steps:
    152         1. Make a call from AG role.
    153         2. Wait for the HF, AG to show dialing and RE to see the call ringing.
    154         3. Hangup the call on HF role.
    155         4. Wait for all devices to hangup the call.
    156 
    157         Returns:
    158           Pass if True
    159           Fail if False
    160 
    161         Priority: 0
    162         """
    163         return self.dial_a_hangup_b(self.ag, self.hf)
    164 
    165     #@BluetoothTest(UUID=5d1d52c7-51d8-4c82-b437-2e91a6220db3)
    166     @BluetoothBaseTest.bt_test_wrap
    167     def test_outgoing_dial_hf_hangup_ag(self):
    168         """
    169         Tests if we can make a phone call from HF role and disconnect from AG
    170         role.
    171 
    172         Precondition:
    173         1. Devices are connected.
    174 
    175         Steps:
    176         1. Make a call from HF role.
    177         2. Wait for the HF, AG to show dialing and RE to see the call ringing.
    178         3. Hangup the call on AG role.
    179         4. Wait for all devices to hangup the call.
    180 
    181         Returns:
    182           Pass if True
    183           Fail if False
    184 
    185         Priority: 0
    186         """
    187         return self.dial_a_hangup_b(self.hf, self.ag)
    188 
    189     #@BluetoothTest(UUID=a718e238-7e31-40c9-a45b-72081210cc73)
    190     @BluetoothBaseTest.bt_test_wrap
    191     def test_incoming_dial_re_hangup_re(self):
    192         """
    193         Tests if we can make a phone call from remote and disconnect from
    194         remote.
    195 
    196         Precondition:
    197         1. Devices are connected.
    198 
    199         Steps:
    200         1. Make a call from RE role.
    201         2. Wait for the HF, AG to show ringing and RE to see the call dialing.
    202         3. Hangup the call on RE role.
    203         4. Wait for all devices to hangup the call.
    204 
    205         Returns:
    206           Pass if True
    207           Fail if False
    208 
    209         Priority: 0
    210         """
    211         return self.dial_a_hangup_b(self.re, self.re, self.ag_phone_number)
    212 
    213     def dial_a_hangup_b(self, caller, callee, ph=""):
    214         """
    215         a, b and c can be either of AG, HF or Remote.
    216         1. Make a call from 'a' on a fixed number.
    217         2. Wait for the call to get connected (check on both 'a' and 'b')
    218            Check that 'c' is in ringing state.
    219         3. Hangup the call on 'b'.
    220         4. Wait for call to get completely disconnected
    221         (check on both 'a' and 'b')
    222         It is assumed that scenarios will not go into voice mail.
    223         """
    224         if ph == "": ph = self.re_phone_number
    225 
    226         # Determine if this is outgoing or incoming call.
    227         call_type = None
    228         if caller == self.ag or caller == self.hf:
    229             call_type = CALL_TYPE_OUTGOING
    230             if callee != self.ag and callee != self.hf:
    231                 self.log.info("outgoing call should terminate at AG or HF")
    232                 return False
    233         elif caller == self.re:
    234             call_type = CALL_TYPE_INCOMING
    235             if callee != self.re:
    236                 self.log.info("Incoming call should terminate at Re")
    237                 return False
    238 
    239         self.log.info("Call type is {}".format(call_type))
    240 
    241         # make a call on 'caller'
    242         if not tel_telecom_utils.dial_number(self.log, caller, ph):
    243             return False
    244 
    245         # Give time for state to update due to carrier limitations
    246         time.sleep(SHORT_TIMEOUT)
    247         # Check that everyone is in dialing/ringing state.
    248         ret = True
    249         if call_type == CALL_TYPE_OUTGOING:
    250             ret &= tel_telecom_utils.wait_for_dialing(self.log, self.hf)
    251             ret &= tel_telecom_utils.wait_for_dialing(self.log, self.ag)
    252             ret &= tel_telecom_utils.wait_for_ringing(self.log, self.re)
    253         else:
    254             ret &= tel_telecom_utils.wait_for_ringing(self.log, self.hf)
    255             ret &= tel_telecom_utils.wait_for_ringing(self.log, self.ag)
    256             ret &= tel_telecom_utils.wait_for_dialing(self.log, self.re)
    257         if not ret:
    258             return False
    259 
    260         # Give time for state to update due to carrier limitations
    261         time.sleep(SHORT_TIMEOUT)
    262         # Check if we have any calls with dialing or active state on 'b'.
    263         # We assume we never disconnect from 'ringing' state since it will lead
    264         # to voicemail.
    265         call_state_dialing_or_active = \
    266             [tel_defines.CALL_STATE_CONNECTING,
    267              tel_defines.CALL_STATE_DIALING,
    268              tel_defines.CALL_STATE_ACTIVE]
    269 
    270         calls_in_dialing_or_active = tel_telecom_utils.get_calls_in_states(
    271             self.log, callee, call_state_dialing_or_active)
    272 
    273         # Make sure there is only one!
    274         if len(calls_in_dialing_or_active) != 1:
    275             self.log.info("Call State in dialing or active failed {}".format(
    276                 calls_in_dialing_or_active))
    277             return False
    278 
    279         # Hangup the *only* call on 'callee'
    280         if not car_telecom_utils.hangup_call(self.log, callee,
    281                                              calls_in_dialing_or_active[0]):
    282             return False
    283 
    284         time.sleep(SHORT_TIMEOUT)
    285         # Make sure everyone got out of in call state.
    286         for d in self.android_devices:
    287             ret &= tel_telecom_utils.wait_for_not_in_call(self.log, d)
    288         return ret
    289