blob: 8c4a6568b13a43ba6427cbae89c8d43c6859f24b [file] [log] [blame]
Victor Hsieh2eba8922016-08-17 12:54:14 -07001# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import glob
6import logging
7import os
8import pipes
9import re
10import shutil
11import subprocess
12import sys
13import tempfile
14
15from autotest_lib.client.bin import test, utils
16from autotest_lib.client.common_lib import error
17from autotest_lib.client.common_lib.cros import chrome, arc_common
18
19_ADB_KEYS_PATH = '/tmp/adb_keys'
20_ADB_VENDOR_KEYS = 'ADB_VENDOR_KEYS'
21_ANDROID_CONTAINER_PATH = '/var/run/containers/android_*'
22_SCREENSHOT_DIR_PATH = '/var/log/arc-screenshots'
23_SCREENSHOT_BASENAME = 'arc-screenshot'
24_MAX_SCREENSHOT_NUM = 10
25_SDCARD_PID_PATH = '/var/run/arc/sdcard.pid'
26_ANDROID_ADB_KEYS_PATH = '/data/misc/adb/adb_keys'
27_PROCESS_CHECK_INTERVAL_SECONDS = 1
28_WAIT_FOR_ADB_READY = 60
29_WAIT_FOR_ANDROID_PROCESS_SECONDS = 60
30_VAR_LOGCAT_PATH = '/var/log/logcat'
31
32
33def setup_adb_host():
34 """Setup ADB host keys.
35
36 This sets up the files and environment variables that wait_for_adb_ready() needs"""
37 if _ADB_VENDOR_KEYS in os.environ:
38 return
39 if not os.path.exists(_ADB_KEYS_PATH):
40 os.mkdir(_ADB_KEYS_PATH)
41 # adb expects $HOME to be writable.
42 os.environ['HOME'] = _ADB_KEYS_PATH
43
44 # Generate and save keys for adb if needed
45 key_path = os.path.join(_ADB_KEYS_PATH, 'test_key')
46 if not os.path.exists(key_path):
47 utils.system('adb keygen ' + pipes.quote(key_path))
48 os.environ[_ADB_VENDOR_KEYS] = key_path
49
50
51def adb_connect():
52 """Attempt to connect ADB to the Android container.
53
54 Returns true if successful. Do not call this function directly. Call
55 wait_for_adb_ready() instead."""
56 if not is_android_booted():
57 return False
Ricky Zhou5c2745d2016-09-19 20:44:39 -070058 if utils.system('adb connect localhost:22', ignore_status=True) != 0:
59 return False
Victor Hsieh2eba8922016-08-17 12:54:14 -070060 return is_adb_connected()
61
62
63def is_adb_connected():
64 """Return true if adb is connected to the container."""
Ricky Zhou5c2745d2016-09-19 20:44:39 -070065 output = utils.system_output('adb get-state', ignore_status=True)
Victor Hsieh2eba8922016-08-17 12:54:14 -070066 logging.debug('adb get-state: %s', output)
67 return output.strip() == 'device'
68
69
70def wait_for_adb_ready(timeout=_WAIT_FOR_ADB_READY):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +080071 """Wait for the ADB client to connect to the ARC container.
72
73 @param timeout: Timeout in seconds.
74 """
Victor Hsieh2eba8922016-08-17 12:54:14 -070075 setup_adb_host()
76 if is_adb_connected():
77 return
78
79 # Push keys for adb.
80 pubkey_path = os.environ[_ADB_VENDOR_KEYS] + '.pub'
81 with open(pubkey_path, 'r') as f:
82 _write_android_file(_ANDROID_ADB_KEYS_PATH, f.read())
83 _android_shell('restorecon ' + pipes.quote(_ANDROID_ADB_KEYS_PATH))
84
85 # This starts adbd.
86 _android_shell('setprop sys.usb.config mtp,adb')
87
88 # Kill existing adb server to ensure that a full reconnect is performed.
Ricky Zhou5c2745d2016-09-19 20:44:39 -070089 utils.system('adb kill-server', ignore_status=True)
Victor Hsieh2eba8922016-08-17 12:54:14 -070090
91 exception = error.TestFail('adb is not ready in %d seconds.' % timeout)
92 utils.poll_for_condition(adb_connect,
93 exception,
94 timeout)
95
96
Cheng-Yi Chiang21cf23a2016-09-10 01:31:31 +080097def grant_permissions(package, permissions):
98 """Grants permissions to a package.
99
100 @param package: Package name.
101 @param permissions: A list of permissions.
102
103 """
104 for permission in permissions:
105 adb_shell('pm grant %s android.permission.%s' % (
106 pipes.quote(package), pipes.quote(permission)))
107
108
Victor Hsieh2eba8922016-08-17 12:54:14 -0700109def adb_cmd(cmd, **kwargs):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800110 """Executed cmd using adb. Must wait for adb ready.
111
112 @param cmd: Command to run.
113 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700114 wait_for_adb_ready()
115 return utils.system_output('adb %s' % cmd, **kwargs)
116
117
118def adb_shell(cmd, **kwargs):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800119 """Executed shell command with adb.
120
121 @param cmd: Command to run.
122 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700123 output = adb_cmd('shell %s' % pipes.quote(cmd), **kwargs)
124 # Some android commands include a trailing CRLF in their output.
125 if kwargs.pop('strip_trailing_whitespace', True):
126 output = output.rstrip()
127 return output
128
129
130def adb_install(apk):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800131 """Install an apk into container. You must connect first.
132
133 @param apk: Package to install.
134 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700135 return adb_cmd('install -r %s' % apk)
136
137
138def adb_uninstall(apk):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800139 """Remove an apk from container. You must connect first.
140
141 @param apk: Package to uninstall.
142 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700143 return adb_cmd('uninstall %s' % apk)
144
145
146def adb_reboot():
147 """Reboots the container. You must connect first."""
148 adb_root()
149 return adb_cmd('reboot', ignore_status=True)
150
151
152def adb_root():
153 """Restart adbd with root permission."""
154 adb_cmd('root')
155
156
157def get_container_root():
158 """Returns path to Android container root directory.
159
160 Raises:
161 TestError if no container root directory is found, or
162 more than one container root directories are found.
163 """
164 arc_container_roots = glob.glob(_ANDROID_CONTAINER_PATH)
165 if len(arc_container_roots) != 1:
166 raise error.TestError(
167 'Android container not available: %r' % arc_container_roots)
168 return arc_container_roots[0]
169
170
171def get_job_pid(job_name):
172 """Returns the PID of an upstart job."""
173 status = utils.system_output('status %s' % job_name)
174 match = re.match(r'^%s start/running, process (\d+)$' % job_name,
175 status)
176 if not match:
177 raise error.TestError('Unexpected status: "%s"' % status)
178 return match.group(1)
179
180
181def get_container_pid():
182 """Returns the PID of the container."""
183 container_root = get_container_root()
184 pid_path = os.path.join(container_root, 'container.pid')
185 return utils.read_one_line(pid_path)
186
187
188def get_sdcard_pid():
189 """Returns the PID of the sdcard container."""
190 return utils.read_one_line(_SDCARD_PID_PATH)
191
192
Victor Hsieh2eba8922016-08-17 12:54:14 -0700193def get_removable_media_pid():
194 """Returns the PID of the arc-removable-media FUSE daemon."""
195 job_pid = get_job_pid('arc-removable-media')
196 # |job_pid| is the minijail process, obtain the PID of the process running
197 # inside the mount namespace.
198 # FUSE process is the only process running as chronos in the process group.
199 return utils.system_output('pgrep -u chronos -g %s' % job_pid)
200
201
202def get_obb_mounter_pid():
203 """Returns the PID of the OBB mounter."""
204 return utils.system_output('pgrep -f -u root ^/usr/bin/arc-obb-mounter')
205
206
207def is_android_booted():
208 """Return whether Android has completed booting."""
209 output = _android_shell('getprop sys.boot_completed',
210 ignore_status=True)
211 return output.strip() == '1'
212
213
214def is_android_process_running(process_name):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800215 """Return whether Android has completed booting.
216
217 @param process_name: Process name.
218 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700219 output = adb_shell('ps %s' % pipes.quote(process_name))
220 # ps always prints the header.
221 return len(output.splitlines()) == 2
222
223
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800224def check_android_file_exists(filename):
225 """Checks whether the given file exists in the Android filesystem
226
227 @param filename: File to check.
228 """
229 return adb_shell('test -e {} && echo FileExists'.format(
230 pipes.quote(filename))).find("FileExists") >= 0
231
232
Victor Hsieh2eba8922016-08-17 12:54:14 -0700233def read_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800234 """Reads a file in Android filesystem.
235
236 @param filename: File to read.
237 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700238 with tempfile.NamedTemporaryFile() as tmpfile:
239 adb_cmd('pull %s %s' % (pipes.quote(filename), pipes.quote(tmpfile.name)))
240 with open(tmpfile.name) as f:
241 return f.read()
242
243 return None
244
245
246def write_android_file(filename, data):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800247 """Writes to a file in Android filesystem.
248
249 @param filename: File to write.
250 @param data: Data to write.
251 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700252 with tempfile.NamedTemporaryFile() as tmpfile:
253 tmpfile.write(data)
254 tmpfile.flush()
255
256 adb_cmd('push %s %s' % (pipes.quote(tmpfile.name), pipes.quote(filename)))
257
258
259def _write_android_file(filename, data):
260 """Writes to a file in Android filesystem.
261
262 This is an internal function used to bootstrap adb.
263 Tests should use write_android_file instead.
264 """
265 android_cmd = 'cat > %s' % pipes.quote(filename)
266 cros_cmd = 'android-sh -c %s' % pipes.quote(android_cmd)
267 utils.run(cros_cmd, stdin=data)
268
269
270def remove_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800271 """Removes a file in Android filesystem.
272
273 @param filename: File to remove.
274 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700275 adb_shell('rm -f %s' % pipes.quote(filename))
276
277
278def wait_for_android_boot(timeout=None):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800279 """Sleep until Android has completed booting or timeout occurs.
280
281 @param timeout: Timeout in seconds.
282 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700283 arc_common.wait_for_android_boot(timeout)
284
285
286def wait_for_android_process(process_name,
287 timeout=_WAIT_FOR_ANDROID_PROCESS_SECONDS):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800288 """Sleep until an Android process is running or timeout occurs.
289
290 @param process_name: Process name.
291 @param timeout: Timeout in seconds.
292 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700293 condition = lambda: is_android_process_running(process_name)
294 utils.poll_for_condition(condition=condition,
295 desc='%s is running' % process_name,
296 timeout=timeout,
297 sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
298
299
300def _android_shell(cmd, **kwargs):
301 """Execute cmd instead the Android container.
302
303 This function is strictly for internal use only, as commands do not run in a
304 fully consistent Android environment. Prefer adb_shell instead.
305 """
306 return utils.system_output('android-sh -c {}'.format(pipes.quote(cmd)),
307 **kwargs)
308
309
310def is_android_container_alive():
311 """Check if android container is alive."""
312 try:
313 container_pid = get_container_pid()
314 except Exception:
315 return False
316 return utils.pid_is_alive(int(container_pid))
317
318
319def is_package_installed(package):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800320 """Check if a package is installed. adb must be ready.
321
322 @param package: Package in request.
323 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700324 packages = adb_shell('pm list packages').splitlines()
325 package_entry = 'package:{}'.format(package)
326 return package_entry in packages
327
328
329def _before_iteration_hook(obj):
330 """Executed by parent class before every iteration.
331
332 This function resets the run_once_finished flag before every iteration
333 so we can detect failure on every single iteration.
334
335 Args:
336 obj: the test itself
337 """
338 obj.run_once_finished = False
339
340
341def _after_iteration_hook(obj):
342 """Executed by parent class after every iteration.
343
344 The parent class will handle exceptions and failures in the run and will
345 always call this hook afterwards. Take a screenshot if the run has not
346 been marked as finished (i.e. there was a failure/exception).
347
348 Args:
349 obj: the test itself
350 """
351 if not obj.run_once_finished:
352 if not os.path.exists(_SCREENSHOT_DIR_PATH):
353 os.mkdir(_SCREENSHOT_DIR_PATH, 0755)
354 obj.num_screenshots += 1
355 if obj.num_screenshots <= _MAX_SCREENSHOT_NUM:
356 logging.warning('Iteration %d failed, taking a screenshot.',
357 obj.iteration)
358 from cros.graphics.drm import crtcScreenshot
359 image = crtcScreenshot()
360 image.save('{}/{}_iter{}.png'.format(_SCREENSHOT_DIR_PATH,
361 _SCREENSHOT_BASENAME,
362 obj.iteration))
363 else:
364 logging.warning('Too many failures, no screenshot taken')
365
366
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800367def send_keycode(keycode):
368 """Sends the given keycode to the container
369
370 @param keycode: keycode to send.
371 """
372 adb_shell('input keyevent {}'.format(keycode))
373
374
Victor Hsieh2eba8922016-08-17 12:54:14 -0700375class ArcTest(test.test):
376 """ Base class of ARC Test.
377
378 This class could be used as super class of an ARC test for saving
379 redundant codes for container bringup, autotest-dep package(s) including
380 uiautomator setup if required, and apks install/remove during
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800381 arc_setup/arc_teardown, respectively. By default arc_setup() is called in
382 initialize() after Android have been brought up. It could also be overridden
383 to perform non-default tasks. For example, a simple ArcHelloWorldTest can be
384 just implemented with print 'HelloWorld' in its run_once() and no other
385 functions are required. We could expect ArcHelloWorldTest would bring up
386 browser and wait for container up, then print 'Hello World', and shutdown
387 browser after. As a precaution, if you overwrite initialize(), arc_setup(),
388 or cleanup() function(s) in ARC test, remember to call the corresponding
389 function(s) in this base class as well.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700390
391 """
392 version = 1
393 _PKG_UIAUTOMATOR = 'uiautomator'
394 _FULL_PKG_NAME_UIAUTOMATOR = 'com.github.uiautomator'
395
396 def __init__(self, *args, **kwargs):
397 """Initialize flag setting."""
398 super(ArcTest, self).__init__(*args, **kwargs)
399 self.initialized = False
400 # Set the flag run_once_finished to detect if a test is executed
401 # successfully without any exception thrown. Otherwise, generate
402 # a screenshot in /var/log for debugging.
403 self.run_once_finished = False
404 self.logcat_proc = None
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800405 self.dep_package = None
406 self.apks = None
407 self.full_pkg_names = []
408 self.uiautomator = False
409 self.email_id = None
410 self.password = None
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800411 self._chrome = None
Victor Hsieh2eba8922016-08-17 12:54:14 -0700412 if os.path.exists(_SCREENSHOT_DIR_PATH):
413 shutil.rmtree(_SCREENSHOT_DIR_PATH)
414 self.register_before_iteration_hook(_before_iteration_hook)
415 self.register_after_iteration_hook(_after_iteration_hook)
416 # Keep track of the number of debug screenshots taken and keep the
417 # total number sane to avoid issues.
418 self.num_screenshots = 0
419
420 def initialize(self, extension_path=None,
421 arc_mode=arc_common.ARC_MODE_ENABLED, **chrome_kargs):
422 """Log in to a test account."""
423 extension_paths = [extension_path] if extension_path else []
424 self._chrome = chrome.Chrome(extension_paths=extension_paths,
Victor Hsieh2eba8922016-08-17 12:54:14 -0700425 arc_mode=arc_mode,
426 **chrome_kargs)
427 if extension_path:
428 self._extension = self._chrome.get_extension(extension_path)
429 else:
430 self._extension = None
431 # With ARC enabled, Chrome will wait until container to boot up
432 # before returning here, see chrome.py.
433 self.initialized = True
Victor Hsieh2eba8922016-08-17 12:54:14 -0700434 try:
435 if is_android_container_alive():
436 self.arc_setup()
437 else:
438 logging.error('Container is alive?')
439 except Exception as err:
440 self.cleanup()
441 raise error.TestFail(err)
442
443 def after_run_once(self):
444 """Executed after run_once() only if there were no errors.
445
446 This function marks the run as finished with a flag. If there was a
447 failure the flag won't be set and the failure can then be detected by
448 testing the run_once_finished flag.
449 """
450 logging.info('After run_once')
451 self.run_once_finished = True
452
453 def cleanup(self):
454 """Log out of Chrome."""
455 if not self.initialized:
456 logging.info('Skipping ARC cleanup: not initialized')
457 return
458 logging.info('Starting ARC cleanup')
459 try:
460 if is_android_container_alive():
461 self.arc_teardown()
462 except Exception as err:
463 raise error.TestFail(err)
464 finally:
465 try:
466 self._stop_logcat()
467 finally:
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800468 if self._chrome is not None:
469 self._chrome.close()
Victor Hsieh2eba8922016-08-17 12:54:14 -0700470
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800471 def arc_setup(self, dep_package=None, apks=None, full_pkg_names=[],
472 uiautomator=False, email_id=None, password=None):
473 """ARC test setup: Setup dependencies and install apks.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700474
475 This function disables package verification and enables non-market
476 APK installation. Then, it installs specified APK(s) and uiautomator
477 package and path if required in a test.
478
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800479 @param dep_package: Package name of autotest_deps APK package.
480 @param apks: Array of APK names to be installed in dep_package.
481 @param full_pkg_names: Array of full package names to be removed
482 in teardown.
483 @param uiautomator: uiautomator python package is required or not.
484
485 @param email_id: email id to be attached to the android. Only used
486 when account_util is set to true.
487 @param password: password related to the email_id.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700488 """
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800489 if not self.initialized:
490 logging.info('Skipping ARC setup: not initialized')
491 return
492 logging.info('Starting ARC setup')
493 self.dep_package = dep_package
494 self.apks = apks
495 self.uiautomator = uiautomator
496 self.email_id = email_id
497 self.password = password
498 # Setup dependent packages if required
499 packages = []
500 if dep_package:
501 packages.append(dep_package)
502 if self.uiautomator:
503 packages.append(self._PKG_UIAUTOMATOR)
504 if packages:
505 logging.info('Setting up dependent package(s) %s', packages)
506 self.job.setup_dep(packages)
507
Victor Hsieh2eba8922016-08-17 12:54:14 -0700508 # TODO(b/29341443): Run logcat on non ArcTest test cases too.
509 with open(_VAR_LOGCAT_PATH, 'w') as f:
510 self.logcat_proc = subprocess.Popen(
511 ['android-sh', '-c', 'logcat -v threadtime'],
512 stdout=f,
513 stderr=subprocess.STDOUT,
514 close_fds=True)
515
516 wait_for_adb_ready()
517
518 # package_verifier_user_consent == -1 means to reject Google's
519 # verification on the server side through Play Store. This suppress a
520 # consent dialog from the system.
521 adb_shell('settings put secure package_verifier_user_consent -1')
522 # TODO(30310952): Remove the workaround below to a Phonesky bug.
523 adb_shell('am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE '
524 '-e finsky.platform_anti_malware_enabled false')
525 adb_shell('settings put global package_verifier_enable 0')
526 adb_shell('settings put secure install_non_market_apps 1')
527
528 if self.dep_package:
529 apk_path = os.path.join(self.autodir, 'deps', self.dep_package)
530 if self.apks:
531 for apk in self.apks:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800532 logging.info('Installing %s', apk)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700533 adb_install('%s/%s' % (apk_path, apk))
534 # Verify if package(s) are installed correctly
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800535 if not full_pkg_names:
Victor Hsieh2eba8922016-08-17 12:54:14 -0700536 raise error.TestError('Package names of apks expected')
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800537 for pkg in full_pkg_names:
538 logging.info('Check if %s is installed', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700539 if not is_package_installed(pkg):
540 raise error.TestError('Package %s not found' % pkg)
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800541 # Make sure full_pkg_names contains installed packages only
542 # so arc_teardown() knows what packages to uninstall.
543 self.full_pkg_names.append(pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700544
545 if self.uiautomator:
546 path = os.path.join(self.autodir, 'deps', self._PKG_UIAUTOMATOR)
547 sys.path.append(path)
548
549 def _stop_logcat(self):
550 """Stop the adb logcat process gracefully."""
551 if not self.logcat_proc:
552 return
553 # Running `adb kill-server` should have killed `adb logcat`
554 # process, but just in case also send termination signal.
555 self.logcat_proc.terminate()
556
557 class TimeoutException(Exception):
558 """Termination timeout timed out."""
559
560 try:
561 utils.poll_for_condition(
562 condition=lambda: self.logcat_proc.poll() is not None,
563 exception=TimeoutException,
564 timeout=10,
565 sleep_interval=0.1,
566 desc='Waiting for adb logcat to terminate')
567 except TimeoutException:
568 logging.info('Killing adb logcat due to timeout')
569 self.logcat_proc.kill()
570 self.logcat_proc.wait()
571
572 def arc_teardown(self):
573 """ARC test teardown.
574
575 This function removes all installed packages in arc_setup stage
576 first. Then, it restores package verification and disables non-market
577 APK installation.
578
579 """
580 if self.full_pkg_names:
581 for pkg in self.full_pkg_names:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800582 logging.info('Uninstalling %s', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700583 if not is_package_installed(pkg):
584 raise error.TestError('Package %s was not installed' % pkg)
585 adb_uninstall(pkg)
586 if self.uiautomator:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800587 logging.info('Uninstalling %s', self._FULL_PKG_NAME_UIAUTOMATOR)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700588 adb_uninstall(self._FULL_PKG_NAME_UIAUTOMATOR)
589 adb_shell('settings put secure install_non_market_apps 0')
590 adb_shell('settings put global package_verifier_enable 1')
591 # TODO(30310952): Remove the workaround below to a Phonesky bug.
592 adb_shell('am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE '
593 '--esn finsky.platform_anti_malware_enabled')
594 adb_shell('settings put secure package_verifier_user_consent 0')
595
596 remove_android_file(_ANDROID_ADB_KEYS_PATH)
597 utils.system_output('adb kill-server')
598
599 def block_outbound(self):
600 """ Blocks the connection from the container to outer network.
601
Abhishek Bhardwaj754b7fb2017-01-05 16:02:48 -0800602 The iptables settings accept only 100.115.92.2 port 5555 (adb) and
Victor Hsieh2eba8922016-08-17 12:54:14 -0700603 localhost port 9008 (uiautomator)
604 """
605 logging.info('Blocking outbound connection')
606 _android_shell('iptables -I OUTPUT -j REJECT')
Abhishek Bhardwaj754b7fb2017-01-05 16:02:48 -0800607 _android_shell('iptables -I OUTPUT -p tcp -s 100.115.92.2 --sport 5555 -j ACCEPT')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700608 _android_shell('iptables -I OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
609 _android_shell('iptables -I OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
610
611
612 def unblock_outbound(self):
613 """ Unblocks the connection from the container to outer network.
614
615 The iptables settings are not permanent which means they reset on
616 each instance invocation. But we can still use this function to
617 unblock the outbound connections during the test if needed.
618 """
619 logging.info('Unblocking outbound connection')
620 _android_shell('iptables -D OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
621 _android_shell('iptables -D OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
Abhishek Bhardwaj754b7fb2017-01-05 16:02:48 -0800622 _android_shell('iptables -D OUTPUT -p tcp -s 100.115.92.2 --sport 5555 -j ACCEPT')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700623 _android_shell('iptables -D OUTPUT -j REJECT')