blob: 1ee2c5cb17a0c54eaa6d9a265436fdff52dc747d [file] [log] [blame]
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -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.
16"""Test script to test PBAP contact download between two devices which can run SL4A.
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070017"""
18
Joseph Pirozzof304d362016-06-17 15:15:40 -070019from time import sleep
20from time import time
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070021
22from acts.base_test import BaseTestClass
Joseph Pirozzof304d362016-06-17 15:15:40 -070023from acts.test_utils.bt import bt_test_utils
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070024from acts.utils import exe_cmd
25import acts.test_utils.bt.bt_contacts_utils as bt_contacts_utils
Joseph Pirozzof304d362016-06-17 15:15:40 -070026import acts.test_utils.bt.BtEnum as BtEnum
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070027
Joseph Pirozzof304d362016-06-17 15:15:40 -070028# Names for temporary files for contacts cards for import and export from PSE and PCE
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070029PSE_CONTACTS_FILE = "psecontacts.vcf"
30PCE_CONTACTS_FILE = "pcecontacts.vcf"
Joseph Pirozzof304d362016-06-17 15:15:40 -070031
32# Offset call logs by 1 minute
33CALL_LOG_TIME_OFFSET_IN_MSEC = 60000
34
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070035
36class BtCarPbapTest(BaseTestClass):
37 def __init__(self, controllers):
38 BaseTestClass.__init__(self, controllers)
39 self.pce = self.android_devices[0]
40 self.pse = self.android_devices[1]
41
42 def setup_class(self):
43 # Reset the devices in a clean state.
Joseph Pirozzof304d362016-06-17 15:15:40 -070044 bt_test_utils.reset_bluetooth(self.android_devices)
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070045
46 for a in self.android_devices:
47 a.ed.clear_all_events()
48
49 # Pair the devices.
50 # This call may block until some specified timeout in bt_test_utils.py.
Joseph Pirozzof304d362016-06-17 15:15:40 -070051 if not bt_test_utils.pair_pri_to_sec(self.pce.droid, self.pse.droid):
52 self.log.error("Failed to pair.")
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070053 return False
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070054
Joseph Pirozzof304d362016-06-17 15:15:40 -070055 self.pse.droid.bluetoothChangeProfileAccessPermission(
56 self.pce.droid.bluetoothGetLocalAddress(),
57 BtEnum.BluetoothProfile.PBAP_SERVER.value,
58 BtEnum.BluetoothAccessLevel.ACCESS_ALLOWED.value)
59
60 # Allow Autoconnect to process so we can start disconnected.
61 sleep(15)
62
63 self.pce.droid.bluetoothPbapClientDisconnect(
64 self.pse.droid.bluetoothGetLocalAddress())
65 if self.pce.droid.bluetoothGetConnectedDevicesOnProfile(
66 BtEnum.BluetoothProfile.PBAP_CLIENT.value):
67 self.log.error("Client connected and shouldn't be.")
68 return False
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070069 return True
70
71 def setup_test(self):
72 bt_contacts_utils.set_logger(self.log)
Joseph Pirozzof304d362016-06-17 15:15:40 -070073 self.pse.droid.callLogsEraseAll()
74 if not (bt_contacts_utils.erase_contacts(self.pse) and
75 bt_contacts_utils.erase_contacts(self.pce)):
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070076 return False
Joseph Pirozzof304d362016-06-17 15:15:40 -070077 # Allow all content providers to synchronize.
78 sleep(1)
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070079 return True
80
81 def teardown_test(self):
Joseph Pirozzof304d362016-06-17 15:15:40 -070082 self.pce.droid.bluetoothPbapClientDisconnect(
83 self.pse.droid.bluetoothGetLocalAddress())
84 bt_contacts_utils.erase_contacts(self.pse)
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070085 return True
86
87 def on_fail(self, test_name, begin_time):
Joseph Pirozzof304d362016-06-17 15:15:40 -070088 bt_test_utils.take_btsnoop_logs(self.android_devices, self, test_name)
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -070089
Joseph Pirozzof304d362016-06-17 15:15:40 -070090 def verify_contacts_match(self):
91 bt_contacts_utils.export_device_contacts_to_vcf(self.pce,
92 PCE_CONTACTS_FILE)
93 return bt_contacts_utils.count_contacts_with_differences(
94 PCE_CONTACTS_FILE, PSE_CONTACTS_FILE) == 0
95
96 def connect_and_verify(self, count):
97 bt_test_utils.connect_pri_to_sec(
98 self.log, self.pce, self.pse.droid,
99 set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
100 bt_contacts_utils.wait_for_phone_number_update_complete(self.pce,
101 count)
102 contacts_added = self.verify_contacts_match()
103 self.pce.droid.bluetoothPbapClientDisconnect(
104 self.pse.droid.bluetoothGetLocalAddress())
105 contacts_removed = bt_contacts_utils.wait_for_phone_number_update_complete(
106 self.pce, 0)
107 return contacts_added and contacts_removed
108
109 def test_pbap_connect_and_disconnect(self):
110 """Test Connectivity
111
112 Test connecting with the server enabled and disabled
113
114 Precondition:
115 1. Devices are paired.
116
117 Steps:
118 1. Disable permission on PSE to prevent PCE from connecting
119 2. Attempt to connect PCE to PSE
120 3. Verify connection failed
121 4. Enable permission on PSE to allow PCE to connect
122 5. Attempt to connect PCE to PSE
123 6. Verify connection succeeded
124
125 Returns:
126 Pass if True
127 Fail if False
128 """
129 self.pse.droid.bluetoothChangeProfileAccessPermission(
130 self.pce.droid.bluetoothGetLocalAddress(),
131 BtEnum.BluetoothProfile.PBAP_SERVER.value,
132 BtEnum.BluetoothAccessLevel.ACCESS_DENIED.value)
133 if bt_test_utils.connect_pri_to_sec(
134 self.log, self.pce, self.pse.droid,
135 set([BtEnum.BluetoothProfile.PBAP_CLIENT.value])):
136 self.log.error("Client connected and shouldn't be.")
137 return False
138 self.pce.droid.bluetoothPbapClientDisconnect(
139 self.pse.droid.bluetoothGetLocalAddress())
140
141 self.pse.droid.bluetoothChangeProfileAccessPermission(
142 self.pce.droid.bluetoothGetLocalAddress(),
143 BtEnum.BluetoothProfile.PBAP_SERVER.value,
144 BtEnum.BluetoothAccessLevel.ACCESS_ALLOWED.value)
145 if not bt_test_utils.connect_pri_to_sec(
146 self.log, self.pce, self.pse.droid,
147 set([BtEnum.BluetoothProfile.PBAP_CLIENT.value])):
148 self.log.error("No client connected and should be.")
149 return False
150
151 return True
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -0700152
153 def test_contact_download(self):
154 """Test Contact Download
155
156 Test download of contacts from a clean state.
157
Joseph Pirozzof304d362016-06-17 15:15:40 -0700158 Precondition:
159 1. Devices are paired.
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -0700160
Joseph Pirozzof304d362016-06-17 15:15:40 -0700161 Steps:
162 1. Erase contacts from PSE and PCE.
163 2. Add a predefined list of contacts to PSE.
164 3. Connect PCE to PSE to perform transfer.
165 4. Compare transfered contacts.
166 5. Disconnect.
167 6. Verify PCE cleaned up contact list.
168
169 Returns:
170 Pass if True
171 Fail if False
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -0700172 """
Joseph Pirozzof304d362016-06-17 15:15:40 -0700173 bt_contacts_utils.generate_contact_list(PSE_CONTACTS_FILE, 100)
174 phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
175 self.pse, PSE_CONTACTS_FILE)
176 bt_test_utils.connect_pri_to_sec(
177 self.log, self.pce, self.pse.droid,
178 set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
179 bt_contacts_utils.wait_for_phone_number_update_complete(
180 self.pce, phone_numbers_added)
181 if not self.verify_contacts_match():
182 return False
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -0700183 self.pce.droid.bluetoothPbapClientDisconnect(
184 self.pse.droid.bluetoothGetLocalAddress())
Joseph Pirozzof304d362016-06-17 15:15:40 -0700185 return bt_contacts_utils.wait_for_phone_number_update_complete(
186 self.pce, 0)
187
188 def test_modify_phonebook(self):
189 """Test Modify Phonebook
190
191 Test changing contacts and reconnecting PBAP.
192
193 Precondition:
194 1. Devices are paired.
195
196 Steps:
197 1. Add a predefined list of contacts to PSE.
198 2. Connect PCE to PSE to perform transfer.
199 3. Verify that contacts match.
200 4. Change some contacts on the PSE.
201 5. Reconnect PCE to PSE to perform transfer.
202 6. Verify that new contacts match.
203
204 Returns:
205 Pass if True
206 Fail if False
207 """
208 bt_contacts_utils.generate_contact_list(PSE_CONTACTS_FILE, 100)
209 phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
210 self.pse, PSE_CONTACTS_FILE)
211 if not self.connect_and_verify(phone_numbers_added):
212 return False
213
Joseph Pirozzo66fb3f62016-05-31 16:57:39 -0700214 bt_contacts_utils.erase_contacts(self.pse)
Joseph Pirozzof304d362016-06-17 15:15:40 -0700215 bt_contacts_utils.generate_contact_list(PSE_CONTACTS_FILE, 110, 2)
216 phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
217 self.pse, PSE_CONTACTS_FILE)
218 return self.connect_and_verify(phone_numbers_added)
219
220 def test_special_contacts(self):
221 """Test Special Contacts
222
223 Test numerous special cases of contacts that could cause errors.
224
225 Precondition:
226 1. Devices are paired.
227
228 Steps:
229 1. Add a predefined list of contacts to PSE that includes special cases:
230 2. Connect PCE to PSE to perform transfer.
231 3. Verify that contacts match.
232
233 Returns:
234 Pass if True
235 Fail if False
236 """
237
238 vcards = []
239
240 # Generate a contact with no email address
241 current_contact = bt_contacts_utils.VCard()
242 current_contact.first_name = "Mr."
243 current_contact.last_name = "Smiley"
244 current_contact.add_phone_number(
245 bt_contacts_utils.generate_random_phone_number())
246 vcards.append(current_contact)
247
248 # Generate a 2nd contact with the same name but different phone number
249 current_contact = bt_contacts_utils.VCard()
250 current_contact.first_name = "Mr."
251 current_contact.last_name = "Smiley"
252 current_contact.add_phone_number(
253 bt_contacts_utils.generate_random_phone_number())
254 vcards.append(current_contact)
255
256 # Generate a contact with no name
257 current_contact = bt_contacts_utils.VCard()
258 current_contact.email = "{}@gmail.com".format(
259 bt_contacts_utils.generate_random_string())
260 current_contact.add_phone_number(
261 bt_contacts_utils.generate_random_phone_number())
262 vcards.append(current_contact)
263
264 # Generate a contact with random characters in its name
265 current_contact = bt_contacts_utils.VCard()
266 current_contact.first_name = bt_contacts_utils.generate_random_string()
267 current_contact.last_name = bt_contacts_utils.generate_random_string()
268 current_contact.add_phone_number(
269 bt_contacts_utils.generate_random_phone_number())
270 vcards.append(current_contact)
271
272 # Generate a contact with only a phone number
273 current_contact = bt_contacts_utils.VCard()
274 current_contact.add_phone_number(
275 bt_contacts_utils.generate_random_phone_number())
276 vcards.append(current_contact)
277
278 # Generate a 2nd contact with only a phone number
279 current_contact = bt_contacts_utils.VCard()
280 current_contact.add_phone_number(
281 bt_contacts_utils.generate_random_phone_number())
282 vcards.append(current_contact)
283
284 bt_contacts_utils.create_new_contacts_vcf_from_vcards(
285 PSE_CONTACTS_FILE, vcards)
286
287 phone_numbers_added = bt_contacts_utils.import_device_contacts_from_vcf(
288 self.pse, PSE_CONTACTS_FILE)
289
290 return self.connect_and_verify(phone_numbers_added)
291
292 def test_call_log(self):
293 """Test Call Log
294
295 Test that Call Logs are transfered
296
297 Precondition:
298 1. Devices are paired.
299
300 Steps:
301 1. Add a predefined list of calls to the PSE call log.
302 2. Connect PCE to PSE to allow call log transfer
303 3. Verify the Missed, Incoming, and Outgoing Call History
304
305 Returns:
306 Pass if True
307 Fail if False
308 """
309
310 bt_contacts_utils.add_call_log(
311 self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
312 bt_contacts_utils.generate_random_phone_number().phone_number,
313 int(time()) * 1000)
314 bt_contacts_utils.add_call_log(
315 self.pse, bt_contacts_utils.INCOMMING_CALL_TYPE,
316 bt_contacts_utils.generate_random_phone_number().phone_number,
317 int(time()) * 1000 - 4 * CALL_LOG_TIME_OFFSET_IN_MSEC)
318 bt_contacts_utils.add_call_log(
319 self.pse, bt_contacts_utils.OUTGOING_CALL_TYPE,
320 bt_contacts_utils.generate_random_phone_number().phone_number,
321 int(time()) * 1000 - CALL_LOG_TIME_OFFSET_IN_MSEC)
322 bt_contacts_utils.add_call_log(
323 self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
324 bt_contacts_utils.generate_random_phone_number().phone_number,
325 int(time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
326 bt_contacts_utils.add_call_log(
327 self.pse, bt_contacts_utils.MISSED_CALL_TYPE,
328 bt_contacts_utils.generate_random_phone_number().phone_number,
329 int(time()) * 1000 - 2 * CALL_LOG_TIME_OFFSET_IN_MSEC)
330
331 bt_test_utils.connect_pri_to_sec(
332 self.log, self.pce, self.pse.droid,
333 set([BtEnum.BluetoothProfile.PBAP_CLIENT.value]))
334 pse_call_log_count = self.pse.droid.callLogGetCount()
335 self.log.info("Waiting for {} call logs to be transfered".format(
336 pse_call_log_count))
337 bt_contacts_utils.wait_for_call_log_update_complete(self.pce,
338 pse_call_log_count)
339
340 if not bt_contacts_utils.get_and_compare_call_logs(
341 self.pse, self.pce, bt_contacts_utils.INCOMMING_CALL_TYPE):
342 return False
343 if not bt_contacts_utils.get_and_compare_call_logs(
344 self.pse, self.pce, bt_contacts_utils.OUTGOING_CALL_TYPE):
345 return False
346 if not bt_contacts_utils.get_and_compare_call_logs(
347 self.pse, self.pce, bt_contacts_utils.MISSED_CALL_TYPE):
348 return False
349
350 return True