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