blob: 0db59e05c6c866901e899dfc69a979188f4b025b [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
Franz-Xaver Geiger223ae752018-02-19 14:54:08 +0100118 ret = adb('push', scenarios_dir, '/sdcard/viser', serial=serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100119 if 0 < ret.returncode:
120 print('Could not push the scenarios, error was: {}'.format(ret.stderr),
121 file=sys.stderr)
122 else:
123 print('Scenarios pushed.')
124
125 # Copy the scenarios data
Franz-Xaver Geiger223ae752018-02-19 14:54:08 +0100126 ret = adb('push', data_dir, '/sdcard/viser/data', serial=serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100127 if 0 < ret.returncode:
128 print('Could not push the scenarios data, error was: {}'.format(ret.stderr),
129 file=sys.stderr)
130 else:
131 print('Scenarios data pushed.')
132
133 # Install the smartviser apps
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100134 for app in PREBUILT_APKS:
135 install_apk(serial, app, prebuilts_dir)
136
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100137
138# Grant the permissions through the UI
139def configure_perms(dut):
Borjan Tchakaloff6dad85d2018-04-11 13:55:25 +0200140 dut() \
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100141 .child_by_text('You need to grant access for the Permissions Group '
142 'Calendar Camera Contacts Microphone SMS Storage Telephone Location',
Borjan Tchakaloff6dad85d2018-04-11 13:55:25 +0200143 resourceId='android:id/content') \
144 .child(text='OK', className='android.widget.Button') \
145 .click()
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100146
147 # Accept any permission that is asked for
148 prompt = dut(resourceId='com.android.packageinstaller:id/permission_allow_button',
149 className='android.widget.Button')
150 while prompt.exists:
151 prompt.click()
152
153 # Input the credentials
154 dut(resourceId='android:id/content') \
155 .child(text='Username') \
156 .child(className='android.widget.EditText') \
157 .set_text('borjan@fairphone.com')
158 dut(resourceId='android:id/content') \
159 .child(text='Password') \
160 .child(className='android.widget.EditText') \
161 .set_text('Rickisalso1niceguy!')
162
163 # Sign in
164 dut(resourceId='android:id/content') \
165 .child(text='Sign in', className='android.widget.Button') \
166 .click()
167
168def configure_sms(dut):
169 # TODO wait for the connection to be established and time-out
170 prompt = dut(resourceId='android:id/content') \
171 .child(text='Viser must be your SMS app to send messages')
172 while not prompt.exists:
173 time.sleep(1)
174
175 # Make viser the default SMS app
176 dut(resourceId='android:id/content') \
177 .child_by_text('Viser must be your SMS app to send messages',
178 className='android.widget.LinearLayout') \
179 .child(text='OK', className='android.widget.Button') \
180 .click()
181
182 dut(resourceId='android:id/content') \
183 .child_by_text('Change SMS app?', className='android.widget.LinearLayout') \
184 .child(text='Yes', className='android.widget.Button') \
185 .click()
186
187def configure_settings(dut):
188 # Set the e-mail account
189 dut(text='Settings', className='android.widget.TextView') \
190 .click()
191 dut(resourceId='android:id/list') \
192 .child_by_text('User settings', className='android.widget.LinearLayout') \
193 .click()
194 dut(resourceId='android:id/list') \
195 .child_by_text('Email account', className='android.widget.LinearLayout') \
196 .click()
197 prompt = dut(resourceId='android:id/content') \
198 .child_by_text('Email account', className='android.widget.LinearLayout')
199 prompt.child(resourceId='android:id/edit') \
200 .set_text('fairphone.viser@gmail.com')
201 prompt.child(text='OK', className='android.widget.Button') \
202 .click()
203 dut(resourceId='android:id/list') \
204 .child_by_text('Email password', className='android.widget.LinearLayout') \
205 .click()
206 dut(text='Password :') \
207 .child(className='android.widget.EditText') \
208 .set_text('fairphoneviser2017')
209 dut(description='OK', className='android.widget.TextView') \
210 .click()
211 dut.press.back()
212 dut.press.back()
213
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100214
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100215def deploy():
216 serials = []
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100217
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100218 if len(sys.argv) > 1:
219 serials.append(sys.argv[1])
220 else:
221 # List devices attached to adb
222 ret = subprocess.run(
223 "adb devices | grep -E '^[a-z0-9-]+\s+device$' | awk '{{print $1}}'",
224 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
225 universal_newlines=True)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100226
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100227 if 0 < ret.returncode:
228 # TODO handle the error
229 raise Exception('Failed to list adb devices')
230 elif ret.stdout:
231 for line in ret.stdout.splitlines():
232 serial = line.strip()
233 if serial:
234 serials.append(serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100235
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100236 for serial in serials:
237 print('Configuring device {}'.format(serial))
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100238
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100239 dut = Device(serial)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100240
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100241 # Push the scenarios, their data, and install the apps
Franz-Xaver Geigerb28348e2018-02-19 14:41:40 +0100242 prepare_dut(serial, '../scenarios', '../scenarios-data', PREBUILTS_PATH)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100243
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100244 # Start the viser app
Franz-Xaver Geiger223ae752018-02-19 14:54:08 +0100245 ret = adb(
246 'shell', 'monkey', '-p', 'com.lunarlabs.panda', '-c',
247 'android.intent.category.LAUNCHER', '1', serial=serial)
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100248 if 0 < ret.returncode:
249 print('Could not start the viser app, error was: {}'.format(app,
250 ret.stderr), file=sys.stderr)
251 exit(-1)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100252
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100253 configure_perms(dut)
Borjan Tchakaloffa4bdae12017-11-21 14:58:12 +0100254
Franz-Xaver Geigerd1079e22018-02-19 14:34:15 +0100255 # TODO DO NOT DO THE FOLLOWING IF NO SIM CARD IS IN THE DUT
256 # time.sleep(10)
257 # configure_sms(dut)
258
259 configure_settings(dut)
260
261
262if __name__ == '__main__':
263 deploy()