blob: 590e1501d3b97316d938a56fc1cd13df2662204c [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
6import sys
7import subprocess
8import pathlib
9
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +010010
11PREBUILTS_PATH = '../../vendor/smartviser/viser/prebuilts/apk'
12
13PREBUILT_APKS = [
14 'com.smartviser.demogame.apk',
15 'com.lunarlabs.panda.proxy.apk',
16 'com.lunarlabs.panda.apk',
17]
18
19
20def adb(*args, serial = None):
21 """Run ADB command attached to serial.
22
23 Example:
24 >>> process = adb('shell', 'getprop', 'ro.build.fingerprint', serial='cc60c021')
25 >>> process.returncode
26 0
27 >>> process.stdout.strip()
28 'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.02.0/FP2-gms-18.02.0:user/release-keys'
29
30 :param *args:
31 List of options to ADB (including command).
32 :param str serial:
33 Identifier for ADB connection to device.
34 :returns subprocess.CompletedProcess:
35 Completed process.
36 """
37
38 # Make sure the adb server is started to avoid the infamous "out of date"
39 # message that pollutes stdout.
40 subprocess.run(
41 ['adb', 'start-server'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
42 universal_newlines=True)
43
44 command = ['adb']
45 if serial:
46 command += ['-s', serial]
47 if args:
48 command += list(args)
49 return subprocess.run(
50 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
51 universal_newlines=True)
52
53
54def aapt(*args):
55 """Run an AAPT command.
56
57 :param *args:
58 The AAPT command with its options.
59 :returns subprocess.CompletedProcess:
60 Completed process.
61 """
62 command = ['aapt']
63 if args:
64 command += list(args)
65 return subprocess.run(
66 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
67 universal_newlines=True)
68
69
70def uninstall_apk(serial, filename, prebuilts_dir):
71 """Uninstall apk from prebuilts_dir on device."""
72 ret = aapt('dump', 'badging', '{}/{}'.format(prebuilts_dir, filename))
73 if 0 < ret.returncode:
74 print('Could retrieve app `{}` info, error was: {}'.format(
75 filename, ret.stderr), file=sys.stderr)
76 else:
77 package = None
78 for line in ret.stdout.splitlines():
79 if line.startswith('package'):
80 for token in line.split(' '):
81 if token.startswith('name='):
82 # Extract the package name out of the token
83 # (name='some.package.name')
84 package = token[6:-1]
85 break
86 if not package:
87 print('Could not find package of app `{}`'.format(filename),
88 file=sys.stderr)
89 else:
90 print('Uninstalling `{}`'.format(package))
91 ret = adb('uninstall', package, serial=serial)
92 if 0 < ret.returncode:
93 print('Could not uninstall app `{}`, error was: {}'.format(
94 filename, ret.stderr), file=sys.stderr)
95 else:
96 print('App `{}` uninstalled.'.format(filename))
97
98
99def install_apk(serial, filename, prebuilts_dir):
100 """Install apk from prebuilts_dir on device."""
101 print('Installing {}.'.format(filename))
102 path = os.path.join(prebuilts_dir, filename)
103 ret = adb('install', '-r', path, serial=serial)
104 if 0 < ret.returncode:
105 print('Could not install app `{}`, error was: {}'.format(
106 filename, ret.stderr), file=sys.stderr)
107 else:
108 print('App `{}` installed.'.format(filename))
109
110
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100111# Prepare the DUT
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100112def prepare_dut(serial, scenarios_dir, data_dir, prebuilts_dir):
113 # Uninstall the smartviser apps
114 for app in PREBUILT_APKS:
115 uninstall_apk(serial, app, prebuilts_dir)
116
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100117 # Copy the scenarios
118 ret = subprocess.run(['adb', '-s', serial, 'push', scenarios_dir,
119 '/sdcard/viser'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
120 universal_newlines=True)
121 if 0 < ret.returncode:
122 print('Could not push the scenarios, error was: {}'.format(ret.stderr),
123 file=sys.stderr)
124 else:
125 print('Scenarios pushed.')
126
127 # Copy the scenarios data
128 ret = subprocess.run(['adb', '-s', serial, 'push', data_dir,
129 '/sdcard/viser/data'], stdout=subprocess.PIPE,
130 stderr=subprocess.PIPE, universal_newlines=True)
131 if 0 < ret.returncode:
132 print('Could not push the scenarios data, error was: {}'.format(ret.stderr),
133 file=sys.stderr)
134 else:
135 print('Scenarios data pushed.')
136
137 # Install the smartviser apps
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100138 for app in PREBUILT_APKS:
139 install_apk(serial, app, prebuilts_dir)
140
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100141
142# Grant the permissions through the UI
143def configure_perms(dut):
Borjan Tchakaloff6dad85d2018-04-11 13:55:25 +0200144 dut() \
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100145 .child_by_text('You need to grant access for the Permissions Group '
146 'Calendar Camera Contacts Microphone SMS Storage Telephone Location',
Borjan Tchakaloff6dad85d2018-04-11 13:55:25 +0200147 resourceId='android:id/content') \
148 .child(text='OK', className='android.widget.Button') \
149 .click()
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100150
151 # Accept any permission that is asked for
152 prompt = dut(resourceId='com.android.packageinstaller:id/permission_allow_button',
153 className='android.widget.Button')
154 while prompt.exists:
155 prompt.click()
156
157 # Input the credentials
158 dut(resourceId='android:id/content') \
159 .child(text='Username') \
160 .child(className='android.widget.EditText') \
161 .set_text('borjan@fairphone.com')
162 dut(resourceId='android:id/content') \
163 .child(text='Password') \
164 .child(className='android.widget.EditText') \
165 .set_text('Rickisalso1niceguy!')
166
167 # Sign in
168 dut(resourceId='android:id/content') \
169 .child(text='Sign in', className='android.widget.Button') \
170 .click()
171
172def configure_sms(dut):
173 # TODO wait for the connection to be established and time-out
174 prompt = dut(resourceId='android:id/content') \
175 .child(text='Viser must be your SMS app to send messages')
176 while not prompt.exists:
177 time.sleep(1)
178
179 # Make viser the default SMS app
180 dut(resourceId='android:id/content') \
181 .child_by_text('Viser must be your SMS app to send messages',
182 className='android.widget.LinearLayout') \
183 .child(text='OK', className='android.widget.Button') \
184 .click()
185
186 dut(resourceId='android:id/content') \
187 .child_by_text('Change SMS app?', className='android.widget.LinearLayout') \
188 .child(text='Yes', className='android.widget.Button') \
189 .click()
190
191def configure_settings(dut):
192 # Set the e-mail account
193 dut(text='Settings', className='android.widget.TextView') \
194 .click()
195 dut(resourceId='android:id/list') \
196 .child_by_text('User settings', className='android.widget.LinearLayout') \
197 .click()
198 dut(resourceId='android:id/list') \
199 .child_by_text('Email account', className='android.widget.LinearLayout') \
200 .click()
201 prompt = dut(resourceId='android:id/content') \
202 .child_by_text('Email account', className='android.widget.LinearLayout')
203 prompt.child(resourceId='android:id/edit') \
204 .set_text('fairphone.viser@gmail.com')
205 prompt.child(text='OK', className='android.widget.Button') \
206 .click()
207 dut(resourceId='android:id/list') \
208 .child_by_text('Email password', className='android.widget.LinearLayout') \
209 .click()
210 dut(text='Password :') \
211 .child(className='android.widget.EditText') \
212 .set_text('fairphoneviser2017')
213 dut(description='OK', className='android.widget.TextView') \
214 .click()
215 dut.press.back()
216 dut.press.back()
217
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100218
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100219def deploy():
220 serials = []
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100221
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100222 if len(sys.argv) > 1:
223 serials.append(sys.argv[1])
224 else:
225 # List devices attached to adb
226 ret = subprocess.run(
227 "adb devices | grep -E '^[a-z0-9-]+\s+device$' | awk '{{print $1}}'",
228 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
229 universal_newlines=True)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100230
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100231 if 0 < ret.returncode:
232 # TODO handle the error
233 raise Exception('Failed to list adb devices')
234 elif ret.stdout:
235 for line in ret.stdout.splitlines():
236 serial = line.strip()
237 if serial:
238 serials.append(serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100239
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100240 for serial in serials:
241 print('Configuring device {}'.format(serial))
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100242
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100243 dut = Device(serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100244
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100245 # Push the scenarios, their data, and install the apps
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100246 prepare_dut(serial, '../scenarios', '../scenarios-data', PREBUILTS_PATH)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100247
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100248 # Start the viser app
249 ret = subprocess.run(['adb', '-s', serial, 'shell', 'monkey', '-p',
250 'com.lunarlabs.panda', '-c', 'android.intent.category.LAUNCHER',
251 '1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
252 universal_newlines=True)
253 if 0 < ret.returncode:
254 print('Could not start the viser app, error was: {}'.format(app,
255 ret.stderr), file=sys.stderr)
256 exit(-1)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100257
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100258 configure_perms(dut)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100259
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100260 # TODO DO NOT DO THE FOLLOWING IF NO SIM CARD IS IN THE DUT
261 # time.sleep(10)
262 # configure_sms(dut)
263
264 configure_settings(dut)
265
266
267if __name__ == '__main__':
268 deploy()