blob: 4cdd3022cbc7abe5eba0a61fabcf4a599bfd2a20 [file] [log] [blame]
Sanket Agarwald09c7d82016-05-17 20:24:51 -07001#/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.
Sanket Agarwald09c7d82016-05-17 20:24:51 -070016"""
17Test the HFP profile for basic calling functionality.
18"""
19
Sanket Agarwal54ad6232016-05-17 20:24:51 -070020import os
Sanket Agarwald09c7d82016-05-17 20:24:51 -070021import time
22
23from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
24from acts.test_utils.bt import BtEnum
25from acts.test_utils.bt import bt_test_utils
Sanket Agarwal54ad6232016-05-17 20:24:51 -070026from acts.test_utils.car import tel_telecom_utils
Sanket Agarwald09c7d82016-05-17 20:24:51 -070027from acts.test_utils.tel import tel_defines
Sanket Agarwal54ad6232016-05-17 20:24:51 -070028from acts.test_utils.tel.tel_test_utils import get_phone_number
29from acts.test_utils.tel.tel_test_utils import setup_droid_properties
Sanket Agarwald09c7d82016-05-17 20:24:51 -070030
31BLUETOOTH_PKG_NAME = "com.android.bluetooth"
32CALL_TYPE_OUTGOING = "CALL_TYPE_OUTGOING"
33CALL_TYPE_INCOMING = "CALL_TYPE_INCOMING"
34default_timeout = 20
35
Sanket Agarwal54ad6232016-05-17 20:24:51 -070036
Sanket Agarwald09c7d82016-05-17 20:24:51 -070037class BtCarHfpTest(BluetoothBaseTest):
38 def setup_class(self):
39 self.hf = self.android_devices[0]
40 self.ag = self.android_devices[1]
41 self.re = self.android_devices[2]
Sanket Agarwal54ad6232016-05-17 20:24:51 -070042 if not "sim_conf_file" in self.user_params.keys():
43 self.log.error("Missing mandatory user config \"sim_conf_file\"!")
44 return False
45 sim_conf_file = self.user_params["sim_conf_file"]
46 if not os.path.isfile(sim_conf_file):
47 sim_conf_file = os.path.join(
48 self.user_params[Config.key_config_path], sim_conf_file)
49 if not os.path.isfile(sim_conf_file):
50 self.log.error("Unable to load user config " + sim_conf_file +
51 " from test config file.")
52 return False
53 setup_droid_properties(self.log, self.ag, sim_conf_file)
54 setup_droid_properties(self.log, self.re, sim_conf_file)
55 self.ag_phone_number = get_phone_number(self.log, self.ag)
56 self.re_phone_number = get_phone_number(self.log, self.re)
57 self.log.info("ag tel: {} re tel: {}".format(self.ag_phone_number,
58 self.re_phone_number))
Sanket Agarwald09c7d82016-05-17 20:24:51 -070059
60 # Setup includes pairing and connecting the devices.
61 bt_test_utils.setup_multiple_devices_for_bt_test([self.hf, self.ag])
62 bt_test_utils.reset_bluetooth([self.hf, self.ag])
63
64 # Pair and connect the devices.
65 if not bt_test_utils.pair_pri_to_sec(self.hf.droid, self.ag.droid):
66 self.log.error("Failed to pair")
67 return False
68
69 # Connect the devices now, try twice.
70 attempts = 2
71 connected = False
72 while attempts > 0 and not connected:
73 connected = bt_test_utils.connect_pri_to_sec(
74 self.log, self.hf, self.ag.droid,
tturneyf02ac392016-09-21 10:37:35 -070075 set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value]))
Sanket Agarwald09c7d82016-05-17 20:24:51 -070076 self.log.info("Connected {}".format(connected))
77 attempts -= 1
78 return connected
79
80 def setup_test(self):
81 # Reset the devices.
Sanket Agarwald09c7d82016-05-17 20:24:51 -070082 for d in self.android_devices:
83 d.ed.clear_all_events()
84
85 def on_fail(self, test_name, begin_time):
86 self.log.debug("Test {} failed.".format(test_name))
87
Sanket Agarwald09c7d82016-05-17 20:24:51 -070088 @BluetoothBaseTest.bt_test_wrap
89 def test_default_calling_account(self):
90 """
91 Tests if the default calling account is coming from the
92 bluetooth pacakge.
93
94 Precondition:
95 1. Devices are connected.
96
97 Steps:
98 1. Check if the default calling account is via Bluetooth package.
99
100 Returns:
101 Pass if True
102 Fail if False
103
104 Priority: 0
105 """
106 selected_acc = \
107 self.hf.droid.telecomGetUserSelectedOutgoingPhoneAccount()
108 if not selected_acc:
109 self.log.info("No default account found.")
110 return False
111
112 # Check if the default account is from the Bluetooth package. This is a
113 # light weight check.
114 try:
115 acc_component_id = selected_acc['ComponentName']
116 except KeyError:
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700117 self.log.info("No component name for account {}".format(
118 selected_acc))
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700119 return False
120 if not acc_component_id.startswith(BLUETOOTH_PKG_NAME):
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700121 self.log.info("Component name does not start with pkg name {}".
122 format(selected_acc))
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700123 return False
124
125 @BluetoothBaseTest.bt_test_wrap
126 def test_outgoing_call_hf(self):
127 """
128 Tests if we can make a phone call from HF role and disconnect from HF
129 role.
130
131 Precondition:
132 1. Devices are connected.
133
134 Steps:
135 1. Make a call from HF role.
136 2. Wait for the HF, AG to be dialing and RE to see the call ringing.
137 3. Hangup the call on HF role.
138 4. Wait for all devices to hangup the call.
139
140 Returns:
141 Pass if True
142 Fail if False
143
144 Priority: 0
145 """
146 return self.dial_a_hangup_b(self.hf, self.hf)
147
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700148 @BluetoothBaseTest.bt_test_wrap
149 def test_outgoing_call_ag(self):
150 """
151 Tests if we can make a phone call from AG role and disconnect from AG
152 role.
153
154 Precondition:
155 1. Devices are connected.
156
157 Steps:
158 1. Make a call from AG role.
159 2. Wait for the HF, AG to be in dialing and RE to see the call ringing.
160 3. Hangup the call on AG role.
161 4. Wait for all devices to hangup the call.
162
163 Returns:
164 Pass if True
165 Fail if False
166
167 Priority: 0
168 """
169 return self.dial_a_hangup_b(self.ag, self.ag)
170
171 @BluetoothBaseTest.bt_test_wrap
172 def test_outgoing_dial_ag_hangup_hf(self):
173 """
174 Tests if we can make a phone call from AG role and disconnect from HF
175 role.
176
177 Precondition:
178 1. Devices are connected.
179
180 Steps:
181 1. Make a call from AG role.
182 2. Wait for the HF, AG to show dialing and RE to see the call ringing.
183 3. Hangup the call on HF role.
184 4. Wait for all devices to hangup the call.
185
186 Returns:
187 Pass if True
188 Fail if False
189
190 Priority: 0
191 """
192 return self.dial_a_hangup_b(self.ag, self.hf)
193
194 @BluetoothBaseTest.bt_test_wrap
195 def test_outgoing_dial_hf_hangup_ag(self):
196 """
197 Tests if we can make a phone call from HF role and disconnect from AG
198 role.
199
200 Precondition:
201 1. Devices are connected.
202
203 Steps:
204 1. Make a call from HF role.
205 2. Wait for the HF, AG to show dialing and RE to see the call ringing.
206 3. Hangup the call on AG role.
207 4. Wait for all devices to hangup the call.
208
209 Returns:
210 Pass if True
211 Fail if False
212
213 Priority: 0
214 """
215 return self.dial_a_hangup_b(self.hf, self.ag)
216
217 @BluetoothBaseTest.bt_test_wrap
218 def test_incoming_dial_re_hangup_re(self):
219 """
220 Tests if we can make a phone call from remote and disconnect from
221 remote.
222
223 Precondition:
224 1. Devices are connected.
225
226 Steps:
227 1. Make a call from RE role.
228 2. Wait for the HF, AG to show ringing and RE to see the call dialing.
229 3. Hangup the call on RE role.
230 4. Wait for all devices to hangup the call.
231
232 Returns:
233 Pass if True
234 Fail if False
235
236 Priority: 0
237 """
238 return self.dial_a_hangup_b(self.re, self.re, self.ag_phone_number)
239
240 def dial_a_hangup_b(self, a, b, ph=""):
241 """
242 a, b and c can be either of AG, HF or Remote.
243 1. Make a call from 'a' on a fixed number.
244 2. Wait for the call to get connected (check on both 'a' and 'b')
245 Check that 'c' is in ringing state.
246 3. Hangup the call on 'b'.
247 4. Wait for call to get completely disconnected
248 (check on both 'a' and 'b')
249 It is assumed that scenarios will not go into voice mail.
250 """
251 if ph == "": ph = self.re_phone_number
252
253 # Determine if this is outgoing or incoming call.
254 call_type = None
255 if a == self.ag or a == self.hf:
256 call_type = CALL_TYPE_OUTGOING
257 if b != self.ag and b != self.hf:
258 self.log.info("outgoing call should terminate at AG or HF")
259 return False
260 elif a == self.re:
261 call_type = CALL_TYPE_INCOMING
262 if b != self.re:
263 self.log.info("Incoming call should terminate at Re")
264 return False
265
266 self.log.info("Call type is {}".format(call_type))
267
268 # make a call on 'a'
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700269 if not tel_telecom_utils.dial_number(self.log, a, ph):
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700270 return False
271
272 # Check that everyone is in dialing/ringing state.
273 ret = True
274 if call_type == CALL_TYPE_OUTGOING:
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700275 ret &= tel_telecom_utils.wait_for_dialing(self.log, self.hf)
276 ret &= tel_telecom_utils.wait_for_dialing(self.log, self.ag)
277 ret &= tel_telecom_utils.wait_for_ringing(self.log, self.re)
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700278 else:
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700279 ret &= tel_telecom_utils.wait_for_ringing(self.log, self.hf)
280 ret &= tel_telecom_utils.wait_for_ringing(self.log, self.ag)
281 ret &= tel_telecom_utils.wait_for_dialing(self.log, self.re)
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700282 if not ret:
283 return False
284
285 # Check if we have any calls with dialing or active state on 'b'.
286 # We assume we never disconnect from 'ringing' state since it will lead
287 # to voicemail.
288 call_state_dialing_or_active = \
289 [tel_defines.CALL_STATE_CONNECTING,
290 tel_defines.CALL_STATE_DIALING,
291 tel_defines.CALL_STATE_ACTIVE]
292
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700293 calls_in_dialing_or_active = tel_telecom_utils.get_calls_in_states(
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700294 self.log, b, call_state_dialing_or_active)
295
296 # Make sure there is only one!
297 if len(calls_in_dialing_or_active) != 1:
298 self.log.info("Call State in dialing or active failed {}".format(
299 calls_in_dialing_or_active))
300 return False
301
302 # Hangup the *only* call on 'b'
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700303 if not tel_telecom_utils.hangup_call(self.log, b,
304 calls_in_dialing_or_active[0]):
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700305 return False
306
307 # Make sure everyone got out of in call state.
308 for d in self.android_devices:
Sanket Agarwal54ad6232016-05-17 20:24:51 -0700309 ret &= tel_telecom_utils.wait_for_not_in_call(self.log, d)
Sanket Agarwald09c7d82016-05-17 20:24:51 -0700310 return ret