blob: fd7d6ffb703928a25ba7a1b26bfda0dd360c630d [file] [log] [blame]
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +01001#!/usr/bin/env python3
2
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +01003import os
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +01004import time
5from uiautomator import Device
Franz-Xaver Geigerb0f55422018-04-17 10:33:37 +02006import re
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +01007import sys
8import subprocess
9import pathlib
10
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010011
Borjan Tchakaloffd8445d32018-04-18 18:01:20 +020012VWS_CREDENTIALS = {
13 'user': 'fairphonetesting@gmail.com',
14 'password': 'aish3echi:uwaiSh'
15}
16
17
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010018PREBUILTS_PATH = '../../vendor/smartviser/viser/prebuilts/apk'
19
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +020020PREBUILT_PROXY_APK_PATTERN = (
21 'com.lunarlabs.panda.proxy-latest-sdk{sdk}-{flavour}.apk')
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +020022
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010023PREBUILT_APKS = [
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +020024 'com.smartviser.demogame-latest.apk',
25 'com.lunarlabs.panda-latest.apk',
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010026]
27
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +020028FAIRPHONE_WIFI_NETWORKS = {
29 'Fairphone Guest': {'security': 'WPA/WPA2 PSK', 'password': 'fairwifi'},
30 'Fairphone DEV (2.4 GHz)': {
31 'security': 'WPA/WPA2 PSK', 'password': 'fdev@adm'},
32 'Fairphone DEV (5 GHz)': {
33 'security': 'WPA/WPA2 PSK', 'password': 'fdev@adm'},
34}
35
Franz-Xaver Geigerb0f55422018-04-17 10:33:37 +020036ADB_DEVICES_PATTERN = re.compile(r'^([a-z0-9-]+)\s+device$', flags=re.M)
37
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010038
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020039class HostCommandError(BaseException):
40 """An error happened while issuing a command on the host."""
41 def __init__(self, command, error_message):
42 self.command = command
43 self.error_message = error_message
44 message = 'Command `{}` failed: {}'.format(command, error_message)
45 super(HostCommandError, self).__init__(message)
46
47
48class DeviceCommandError(BaseException):
49 """An error happened while sending a command to a device."""
50 def __init__(self, serial, command, error_message):
51 self.serial = serial
52 self.command = command
53 self.error_message = error_message
54 message = 'Command `{}` failed on {}: {}'.format(
55 command, serial, error_message)
56 super(DeviceCommandError, self).__init__(message)
57
58
59def adb(*args, serial = None, raise_on_error = True):
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010060 """Run ADB command attached to serial.
61
62 Example:
63 >>> process = adb('shell', 'getprop', 'ro.build.fingerprint', serial='cc60c021')
64 >>> process.returncode
65 0
66 >>> process.stdout.strip()
67 'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.02.0/FP2-gms-18.02.0:user/release-keys'
68
69 :param *args:
70 List of options to ADB (including command).
71 :param str serial:
72 Identifier for ADB connection to device.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020073 :param raise_on_error bool:
74 Whether to raise a DeviceCommandError exception if the return code is
75 less than 0.
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010076 :returns subprocess.CompletedProcess:
77 Completed process.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020078 :raises DeviceCommandError:
79 If the command failed.
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010080 """
81
82 # Make sure the adb server is started to avoid the infamous "out of date"
83 # message that pollutes stdout.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020084 ret = subprocess.run(
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010085 ['adb', 'start-server'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
86 universal_newlines=True)
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020087 if ret.returncode < 0:
88 if raise_on_error:
89 raise DeviceCommandError(
90 serial if serial else '??', str(args), ret.stderr)
91 else:
92 return None
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010093
94 command = ['adb']
95 if serial:
96 command += ['-s', serial]
97 if args:
98 command += list(args)
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +020099 ret = subprocess.run(
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100100 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
101 universal_newlines=True)
102
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200103 if raise_on_error and ret.returncode < 0:
104 raise DeviceCommandError(
105 serial if serial else '??', str(args), ret.stderr)
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100106
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200107 return ret
108
109
Franz-Xaver Geigerb0f55422018-04-17 10:33:37 +0200110def list_devices():
111 """List serial numbers of devices attached to adb.
112
113 Raises:
114 DeviceCommandError: If the underlying adb command failed.
115 """
116 process = adb('devices')
117 return ADB_DEVICES_PATTERN.findall(process.stdout)
118
119
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200120def aapt(*args, raise_on_error = True):
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100121 """Run an AAPT command.
122
123 :param *args:
124 The AAPT command with its options.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200125 :param raise_on_error bool:
126 Whether to raise a DeviceCommandError exception if the return code is
127 less than 0.
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100128 :returns subprocess.CompletedProcess:
129 Completed process.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200130 :raises HostCommandError:
131 If the command failed.
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100132 """
133 command = ['aapt']
134 if args:
135 command += list(args)
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200136 ret = subprocess.run(
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100137 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
138 universal_newlines=True)
139
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200140 if raise_on_error and ret.returncode < 0:
141 raise HostCommandError(str(args), ret.stderr)
142
143 return ret
144
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100145
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800146def force_awake(serial, always=True):
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200147 """Force the device to stay awake.
148
149 Raises:
150 DeviceCommandError: If the underlying adb command failed.
151 """
152 adb('shell', 'svc power stayon {}'.format(
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800153 'true' if always else 'false'), serial=serial)
154
155
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200156def unlock(dut):
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200157 """Wake-up the device and unlock it.
158
159 Raises:
160 DeviceCommandError: If the underlying adb commands failed.
161 """
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200162 if not dut.info['screenOn']:
163 adb('shell', 'input keyevent KEYCODE_POWER', serial=dut.serial)
164 time.sleep(1)
165 # The KEYCODE_MENU input is enough to unlock a "swipe up to unlock"
166 # lockscreen on Android 6, but unfortunately not Android 7. So we use a
167 # swipe up (that depends on the screen resolution) instead.
168 adb('shell', 'input touchscreen swipe 930 880 930 380', serial=dut.serial)
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800169 time.sleep(1)
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200170 adb('shell', 'input keyevent KEYCODE_HOME', serial=dut.serial)
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800171
172
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200173def getprop(serial, key):
174 """Get system property of device.
175
176 Example:
177 >>> getprop('167eb6e8', 'ro.build.id')
178 'FP2-gms-18.02.0'
179
180 :param str serial:
181 Identifier for ADB connection to device.
182 :param str key:
183 Key of property to get.
184 :returns str:
185 Value of system property.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200186 :raise DeviceCommandError: If the underlying adb command failed.
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200187 """
188 process = adb('shell', 'getprop', key, serial=serial)
189 return process.stdout.strip()
190
191
192def is_gms_device(serial):
193 """Test if device runs GMS or sibon.
194
195 Example:
196 >>> is_gms_device('167eb6e8')
197 True
198
199 :param str serial:
200 Identifier for ADB connection to device.
201 :returns bool:
202 True if device runs GMS, false otherwise.
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200203 :raise DeviceCommandError: If the underlying adb command failed.
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200204 """
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200205 return (
206 getprop(serial, 'ro.build.id').startswith('FP2-gms-')
207 or getprop(serial, 'ro.build.version.incremental').startswith('gms-'))
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200208
209
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100210def uninstall_apk(serial, filename, prebuilts_dir):
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200211 """Uninstall apk from prebuilts_dir on device.
212
213 Raises:
214 ValueError: If the package name could not be read from the apk.
215 DeviceCommandError: If the uninstall command failed.
216 """
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100217 ret = aapt('dump', 'badging', '{}/{}'.format(prebuilts_dir, filename))
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200218 package = None
219 for line in ret.stdout.splitlines():
220 if line.startswith('package'):
221 for token in line.split(' '):
222 if token.startswith('name='):
223 # Extract the package name out of the token
224 # (name='some.package.name')
225 package = token[6:-1]
226 break
227 if not package:
228 raise ValueError('Could not find package of app `{}`'.format(
229 filename))
230
231 adb('uninstall', package, serial=serial)
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100232
233
Borjan Tchakaloffd2c92ce2018-08-24 17:13:57 +0200234def install_apk(dut, filename, prebuilts_dir):
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200235 """Install apk from prebuilts_dir on device.
236
237 Raises:
238 DeviceCommandError: If the install command failed.
239 """
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100240 path = os.path.join(prebuilts_dir, filename)
Borjan Tchakaloffd2c92ce2018-08-24 17:13:57 +0200241 command = ['install', '-r']
242 if dut.sdk >= 23:
243 # From Marshmallow onwards, adb has a flag to grant default permissions
244 command.append('-g')
245 adb(*command, path, serial=dut.serial)
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100246
247
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200248def configure_wifi_networks(dut, networks):
249 """Configure Wi-Fi networks.
250
251 The `networks` parameters is a list of networks to configure hashed by
252 their SSID. Each network value should have the following format:
253 - security (str): The security value as can be found in the Wi-Fi
254 settings dialog. Common values are 'None' and 'WPA/WPA2 PSK'.
255 - password (str, optional): The network password if the security is
256 'WPA/WPA2 PSK'.
257
258 Parameters:
259 dut (Device): The device object.
260 networks (dict(dict(str))): The list of networks to configure.
261 Raises:
262 DeviceCommandError: If the UI automation fails.
263 """
264 # Open the Wi-Fi settings
265 adb('shell', ('am start -a android.settings.WIFI_SETTINGS '
266 '--activity-clear-task'), serial=dut.serial)
267
268 # Make sure Wi-Fi is enabled
269 wifi_enabler = dut(text='OFF',
270 resourceId='com.android.settings:id/switch_widget')
271 if wifi_enabler.exists:
272 wifi_enabler.click()
273
274 # Check for registered networks
275 registered_networks = set()
Borjan Tchakaloff1d83e562018-05-16 18:47:04 +0200276 dut(description='More options').click.wait()
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200277 time.sleep(1)
278 saved_networks = dut(text='Saved networks')
279 if saved_networks.exists:
Borjan Tchakaloff1d83e562018-05-16 18:47:04 +0200280 saved_networks.click.wait()
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200281 for ssid in networks.keys():
282 if dut(text=ssid).exists:
283 registered_networks.add(ssid)
284 dut.press.back()
285
286 missing_networks = networks.keys() - registered_networks
287
288 for ssid in registered_networks:
289 print('Ignoring `{}` Wi-Fi network, already configured.'.format(ssid))
290
291 for ssid in missing_networks:
292 print('Configuring `{}` Wi-Fi network…'.format(ssid))
293
Borjan Tchakaloff1d83e562018-05-16 18:47:04 +0200294 dut(description='More options').click.wait()
295 dut(text='Add network').click.wait()
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200296 dut(resourceId='com.android.settings:id/ssid') \
297 .set_text(ssid)
298 dut(resourceId='com.android.settings:id/security') \
299 .click()
300 dut(text=networks[ssid]['security']) \
301 .click()
302 password_field = dut(resourceId='com.android.settings:id/password')
303 if 'password' in networks[ssid] and networks[ssid]['password']:
304 if not password_field.exists:
305 dut(text='Cancel').click()
306 raise DeviceCommandError(dut, 'UI: add Wi-Fi',
307 'missing password field')
308 password_field.set_text(networks[ssid]['password'])
309 elif password_field.exists:
310 dut(text='Cancel').click()
311 raise DeviceCommandError(dut, 'UI: add Wi-Fi',
312 'missing password data')
313 save_button = dut(text='Save')
314 if not save_button.click():
315 dut(text='Cancel').click()
316 raise DeviceCommandError(dut, 'UI: add Wi-Fi',
317 'could not save network')
318
319 # Force the Wi-Fi on and off to pick the best network available
320 dut(text='ON', resourceId='com.android.settings:id/switch_widget').click()
321 dut(text='OFF', resourceId='com.android.settings:id/switch_widget').click()
322
323 # Leave the settings
324 dut.press.back()
325
326
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200327def get_proxy_apk(android_sdk, flavour):
328 if android_sdk >= 24:
329 return PREBUILT_PROXY_APK_PATTERN.format(sdk=24, flavour=flavour)
330 else:
331 return PREBUILT_PROXY_APK_PATTERN.format(sdk=19, flavour=flavour)
332
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100333# Prepare the DUT
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200334def prepare_dut(dut, scenarios_dir, data_dir, prebuilts_dir):
335 flavour = 'gms' if is_gms_device(dut.serial) else 'sibon'
336 proxy_apk = get_proxy_apk(dut.sdk, flavour)
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200337
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100338 # Uninstall the smartviser apps
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200339 for app in PREBUILT_APKS + [proxy_apk]:
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200340 print('Uninstalling `{}`…'.format(app))
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200341 uninstall_apk(dut.serial, app, prebuilts_dir)
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100342
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100343 # Copy the scenarios
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200344 print('Pushing scenarios from `{}`…'.format(scenarios_dir))
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200345 adb('push', scenarios_dir, '/sdcard/viser', serial=dut.serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100346
347 # Copy the scenarios data
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200348 print('Pushing scenarios data from `{}`…'.format(data_dir))
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200349 adb('push', data_dir, '/sdcard/viser/data', serial=dut.serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100350
Franz-Xaver Geigerb3f7c982018-04-12 09:29:32 +0200351 # Install the smartviser apps (starting with the proxy app)
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200352 for app in [proxy_apk] + PREBUILT_APKS:
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200353 print('Installing `{}`…'.format(app))
Borjan Tchakaloffd2c92ce2018-08-24 17:13:57 +0200354 install_apk(dut, app, prebuilts_dir)
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100355
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100356
357# Grant the permissions through the UI
358def configure_perms(dut):
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100359 # Input the credentials
360 dut(resourceId='android:id/content') \
361 .child(text='Username') \
362 .child(className='android.widget.EditText') \
Borjan Tchakaloffd8445d32018-04-18 18:01:20 +0200363 .set_text(VWS_CREDENTIALS['user'])
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100364 dut(resourceId='android:id/content') \
365 .child(text='Password') \
366 .child(className='android.widget.EditText') \
Borjan Tchakaloffd8445d32018-04-18 18:01:20 +0200367 .set_text(VWS_CREDENTIALS['password'])
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100368
369 # Sign in
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200370 signin_label = 'SIGN IN' if dut.sdk >= 24 else 'Sign in'
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100371 dut(resourceId='android:id/content') \
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200372 .child(text=signin_label, className='android.widget.Button') \
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100373 .click()
374
Borjan Tchakaloffd2c92ce2018-08-24 17:13:57 +0200375 # Handle Privacy Impact
376 if dut.sdk <= 22:
377 start_button = dut(resourceId='com.fairphone.privacyimpact:id/start_the_app_button')
378 while not start_button.exists:
379 prompt = dut(resourceId='com.fairphone.privacyimpact:id/privacy_got_it')
380 if prompt.exists:
381 prompt.click()
382 dut(resourceId='com.fairphone.privacyimpact:id/notifications_got_it').click()
383 else:
384 print('Waiting for the Privacy Impact screen…')
385 time.sleep(1)
386 start_button.click()
387
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100388def configure_sms(dut):
389 # TODO wait for the connection to be established and time-out
390 prompt = dut(resourceId='android:id/content') \
391 .child(text='Viser must be your SMS app to send messages')
392 while not prompt.exists:
393 time.sleep(1)
394
395 # Make viser the default SMS app
396 dut(resourceId='android:id/content') \
397 .child_by_text('Viser must be your SMS app to send messages',
398 className='android.widget.LinearLayout') \
399 .child(text='OK', className='android.widget.Button') \
400 .click()
401
402 dut(resourceId='android:id/content') \
403 .child_by_text('Change SMS app?', className='android.widget.LinearLayout') \
404 .child(text='Yes', className='android.widget.Button') \
405 .click()
406
407def configure_settings(dut):
408 # Set the e-mail account
409 dut(text='Settings', className='android.widget.TextView') \
410 .click()
411 dut(resourceId='android:id/list') \
412 .child_by_text('User settings', className='android.widget.LinearLayout') \
413 .click()
414 dut(resourceId='android:id/list') \
415 .child_by_text('Email account', className='android.widget.LinearLayout') \
416 .click()
417 prompt = dut(resourceId='android:id/content') \
418 .child_by_text('Email account', className='android.widget.LinearLayout')
419 prompt.child(resourceId='android:id/edit') \
420 .set_text('fairphone.viser@gmail.com')
421 prompt.child(text='OK', className='android.widget.Button') \
422 .click()
423 dut(resourceId='android:id/list') \
424 .child_by_text('Email password', className='android.widget.LinearLayout') \
425 .click()
426 dut(text='Password :') \
427 .child(className='android.widget.EditText') \
428 .set_text('fairphoneviser2017')
429 dut(description='OK', className='android.widget.TextView') \
430 .click()
431 dut.press.back()
432 dut.press.back()
433
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100434
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100435def deploy():
436 serials = []
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100437
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100438 if len(sys.argv) > 1:
439 serials.append(sys.argv[1])
440 else:
Franz-Xaver Geigerb0f55422018-04-17 10:33:37 +0200441 serials = list_devices()
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100442
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100443 for serial in serials:
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200444 print('Configuring device {}…'.format(serial))
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100445
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100446 dut = Device(serial)
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200447 # Work around the not-so-easy Device class
448 dut.serial = serial
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200449 # Cache the Android SDK version (dut.info fetches system properties)
450 dut.sdk = dut.info['sdkInt']
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100451
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200452 try:
453 # Make sure the screen stays on - we're going to use UI automation
454 force_awake(serial)
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200455 unlock(dut)
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800456
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200457 # Configure common Fairphone Wi-Fi networks
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200458 if dut.sdk < 24:
459 configure_wifi_networks(dut, FAIRPHONE_WIFI_NETWORKS)
460 else:
461 print('Uh oh, the device is running Android SDK {} on which we '
462 'do not deploy Wi-Fi networks yet.'.format(dut.sdk))
Borjan Tchakaloff74d962a2018-04-11 17:47:14 +0200463
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200464 # Push the scenarios, their data, and install the apps
465 prepare_dut(
Borjan Tchakaloffd4ce8072018-05-16 18:20:13 +0200466 dut, '../scenarios', '../scenarios-data', PREBUILTS_PATH)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100467
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200468 # Start the viser app
469 adb(
Franz-Xaver Geiger223ae752018-02-19 14:54:08 +0100470 'shell', 'monkey', '-p', 'com.lunarlabs.panda', '-c',
471 'android.intent.category.LAUNCHER', '1', serial=serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100472
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200473 configure_perms(dut)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100474
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200475 # TODO DO NOT DO THE FOLLOWING IF NO SIM CARD IS IN THE DUT
476 # time.sleep(10)
477 # configure_sms(dut)
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100478
Borjan Tchakaloffde9fa0f2018-04-12 12:05:48 +0200479 configure_settings(dut)
480 except (HostCommandError, DeviceCommandError) as e:
481 print('ERROR {}'.format(e), file=sys.stderr)
482 finally:
483 try:
484 # Leave the device alone now
485 force_awake(serial, always=False)
486 except DeviceCommandError as e:
487 print('WARNING {}'.format(e), file=sys.stderr)
Borjan Tchakaloff64ec42b2018-02-07 11:33:15 -0800488
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100489
490if __name__ == '__main__':
491 deploy()