blob: e26f17622fdeec9feb612154b1e7d408108220d7 [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
193def get_dlfs_pid():
194 """Returns the PID of the arc-downloads-filesystem FUSE daemon."""
195 job_pid = get_job_pid('arc-downloads-filesystem')
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_removable_media_pid():
203 """Returns the PID of the arc-removable-media FUSE daemon."""
204 job_pid = get_job_pid('arc-removable-media')
205 # |job_pid| is the minijail process, obtain the PID of the process running
206 # inside the mount namespace.
207 # FUSE process is the only process running as chronos in the process group.
208 return utils.system_output('pgrep -u chronos -g %s' % job_pid)
209
210
211def get_obb_mounter_pid():
212 """Returns the PID of the OBB mounter."""
213 return utils.system_output('pgrep -f -u root ^/usr/bin/arc-obb-mounter')
214
215
216def is_android_booted():
217 """Return whether Android has completed booting."""
218 output = _android_shell('getprop sys.boot_completed',
219 ignore_status=True)
220 return output.strip() == '1'
221
222
223def is_android_process_running(process_name):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800224 """Return whether Android has completed booting.
225
226 @param process_name: Process name.
227 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700228 output = adb_shell('ps %s' % pipes.quote(process_name))
229 # ps always prints the header.
230 return len(output.splitlines()) == 2
231
232
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800233def check_android_file_exists(filename):
234 """Checks whether the given file exists in the Android filesystem
235
236 @param filename: File to check.
237 """
238 return adb_shell('test -e {} && echo FileExists'.format(
239 pipes.quote(filename))).find("FileExists") >= 0
240
241
Victor Hsieh2eba8922016-08-17 12:54:14 -0700242def read_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800243 """Reads a file in Android filesystem.
244
245 @param filename: File to read.
246 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700247 with tempfile.NamedTemporaryFile() as tmpfile:
248 adb_cmd('pull %s %s' % (pipes.quote(filename), pipes.quote(tmpfile.name)))
249 with open(tmpfile.name) as f:
250 return f.read()
251
252 return None
253
254
255def write_android_file(filename, data):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800256 """Writes to a file in Android filesystem.
257
258 @param filename: File to write.
259 @param data: Data to write.
260 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700261 with tempfile.NamedTemporaryFile() as tmpfile:
262 tmpfile.write(data)
263 tmpfile.flush()
264
265 adb_cmd('push %s %s' % (pipes.quote(tmpfile.name), pipes.quote(filename)))
266
267
268def _write_android_file(filename, data):
269 """Writes to a file in Android filesystem.
270
271 This is an internal function used to bootstrap adb.
272 Tests should use write_android_file instead.
273 """
274 android_cmd = 'cat > %s' % pipes.quote(filename)
275 cros_cmd = 'android-sh -c %s' % pipes.quote(android_cmd)
276 utils.run(cros_cmd, stdin=data)
277
278
279def remove_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800280 """Removes a file in Android filesystem.
281
282 @param filename: File to remove.
283 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700284 adb_shell('rm -f %s' % pipes.quote(filename))
285
286
287def wait_for_android_boot(timeout=None):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800288 """Sleep until Android has completed booting or timeout occurs.
289
290 @param timeout: Timeout in seconds.
291 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700292 arc_common.wait_for_android_boot(timeout)
293
294
295def wait_for_android_process(process_name,
296 timeout=_WAIT_FOR_ANDROID_PROCESS_SECONDS):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800297 """Sleep until an Android process is running or timeout occurs.
298
299 @param process_name: Process name.
300 @param timeout: Timeout in seconds.
301 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700302 condition = lambda: is_android_process_running(process_name)
303 utils.poll_for_condition(condition=condition,
304 desc='%s is running' % process_name,
305 timeout=timeout,
306 sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
307
308
309def _android_shell(cmd, **kwargs):
310 """Execute cmd instead the Android container.
311
312 This function is strictly for internal use only, as commands do not run in a
313 fully consistent Android environment. Prefer adb_shell instead.
314 """
315 return utils.system_output('android-sh -c {}'.format(pipes.quote(cmd)),
316 **kwargs)
317
318
319def is_android_container_alive():
320 """Check if android container is alive."""
321 try:
322 container_pid = get_container_pid()
323 except Exception:
324 return False
325 return utils.pid_is_alive(int(container_pid))
326
327
328def is_package_installed(package):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800329 """Check if a package is installed. adb must be ready.
330
331 @param package: Package in request.
332 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700333 packages = adb_shell('pm list packages').splitlines()
334 package_entry = 'package:{}'.format(package)
335 return package_entry in packages
336
337
338def _before_iteration_hook(obj):
339 """Executed by parent class before every iteration.
340
341 This function resets the run_once_finished flag before every iteration
342 so we can detect failure on every single iteration.
343
344 Args:
345 obj: the test itself
346 """
347 obj.run_once_finished = False
348
349
350def _after_iteration_hook(obj):
351 """Executed by parent class after every iteration.
352
353 The parent class will handle exceptions and failures in the run and will
354 always call this hook afterwards. Take a screenshot if the run has not
355 been marked as finished (i.e. there was a failure/exception).
356
357 Args:
358 obj: the test itself
359 """
360 if not obj.run_once_finished:
361 if not os.path.exists(_SCREENSHOT_DIR_PATH):
362 os.mkdir(_SCREENSHOT_DIR_PATH, 0755)
363 obj.num_screenshots += 1
364 if obj.num_screenshots <= _MAX_SCREENSHOT_NUM:
365 logging.warning('Iteration %d failed, taking a screenshot.',
366 obj.iteration)
367 from cros.graphics.drm import crtcScreenshot
368 image = crtcScreenshot()
369 image.save('{}/{}_iter{}.png'.format(_SCREENSHOT_DIR_PATH,
370 _SCREENSHOT_BASENAME,
371 obj.iteration))
372 else:
373 logging.warning('Too many failures, no screenshot taken')
374
375
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800376def send_keycode(keycode):
377 """Sends the given keycode to the container
378
379 @param keycode: keycode to send.
380 """
381 adb_shell('input keyevent {}'.format(keycode))
382
383
Victor Hsieh2eba8922016-08-17 12:54:14 -0700384class ArcTest(test.test):
385 """ Base class of ARC Test.
386
387 This class could be used as super class of an ARC test for saving
388 redundant codes for container bringup, autotest-dep package(s) including
389 uiautomator setup if required, and apks install/remove during
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800390 arc_setup/arc_teardown, respectively. By default arc_setup() is called in
391 initialize() after Android have been brought up. It could also be overridden
392 to perform non-default tasks. For example, a simple ArcHelloWorldTest can be
393 just implemented with print 'HelloWorld' in its run_once() and no other
394 functions are required. We could expect ArcHelloWorldTest would bring up
395 browser and wait for container up, then print 'Hello World', and shutdown
396 browser after. As a precaution, if you overwrite initialize(), arc_setup(),
397 or cleanup() function(s) in ARC test, remember to call the corresponding
398 function(s) in this base class as well.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700399
400 """
401 version = 1
402 _PKG_UIAUTOMATOR = 'uiautomator'
403 _FULL_PKG_NAME_UIAUTOMATOR = 'com.github.uiautomator'
404
405 def __init__(self, *args, **kwargs):
406 """Initialize flag setting."""
407 super(ArcTest, self).__init__(*args, **kwargs)
408 self.initialized = False
409 # Set the flag run_once_finished to detect if a test is executed
410 # successfully without any exception thrown. Otherwise, generate
411 # a screenshot in /var/log for debugging.
412 self.run_once_finished = False
413 self.logcat_proc = None
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800414 self.dep_package = None
415 self.apks = None
416 self.full_pkg_names = []
417 self.uiautomator = False
418 self.email_id = None
419 self.password = None
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800420 self._chrome = None
Victor Hsieh2eba8922016-08-17 12:54:14 -0700421 if os.path.exists(_SCREENSHOT_DIR_PATH):
422 shutil.rmtree(_SCREENSHOT_DIR_PATH)
423 self.register_before_iteration_hook(_before_iteration_hook)
424 self.register_after_iteration_hook(_after_iteration_hook)
425 # Keep track of the number of debug screenshots taken and keep the
426 # total number sane to avoid issues.
427 self.num_screenshots = 0
428
429 def initialize(self, extension_path=None,
430 arc_mode=arc_common.ARC_MODE_ENABLED, **chrome_kargs):
431 """Log in to a test account."""
432 extension_paths = [extension_path] if extension_path else []
433 self._chrome = chrome.Chrome(extension_paths=extension_paths,
434 is_component=not extension_paths,
435 arc_mode=arc_mode,
436 **chrome_kargs)
437 if extension_path:
438 self._extension = self._chrome.get_extension(extension_path)
439 else:
440 self._extension = None
441 # With ARC enabled, Chrome will wait until container to boot up
442 # before returning here, see chrome.py.
443 self.initialized = True
Victor Hsieh2eba8922016-08-17 12:54:14 -0700444 try:
445 if is_android_container_alive():
446 self.arc_setup()
447 else:
448 logging.error('Container is alive?')
449 except Exception as err:
450 self.cleanup()
451 raise error.TestFail(err)
452
453 def after_run_once(self):
454 """Executed after run_once() only if there were no errors.
455
456 This function marks the run as finished with a flag. If there was a
457 failure the flag won't be set and the failure can then be detected by
458 testing the run_once_finished flag.
459 """
460 logging.info('After run_once')
461 self.run_once_finished = True
462
463 def cleanup(self):
464 """Log out of Chrome."""
465 if not self.initialized:
466 logging.info('Skipping ARC cleanup: not initialized')
467 return
468 logging.info('Starting ARC cleanup')
469 try:
470 if is_android_container_alive():
471 self.arc_teardown()
472 except Exception as err:
473 raise error.TestFail(err)
474 finally:
475 try:
476 self._stop_logcat()
477 finally:
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800478 if self._chrome is not None:
479 self._chrome.close()
Victor Hsieh2eba8922016-08-17 12:54:14 -0700480
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800481 def arc_setup(self, dep_package=None, apks=None, full_pkg_names=[],
482 uiautomator=False, email_id=None, password=None):
483 """ARC test setup: Setup dependencies and install apks.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700484
485 This function disables package verification and enables non-market
486 APK installation. Then, it installs specified APK(s) and uiautomator
487 package and path if required in a test.
488
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800489 @param dep_package: Package name of autotest_deps APK package.
490 @param apks: Array of APK names to be installed in dep_package.
491 @param full_pkg_names: Array of full package names to be removed
492 in teardown.
493 @param uiautomator: uiautomator python package is required or not.
494
495 @param email_id: email id to be attached to the android. Only used
496 when account_util is set to true.
497 @param password: password related to the email_id.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700498 """
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800499 if not self.initialized:
500 logging.info('Skipping ARC setup: not initialized')
501 return
502 logging.info('Starting ARC setup')
503 self.dep_package = dep_package
504 self.apks = apks
505 self.uiautomator = uiautomator
506 self.email_id = email_id
507 self.password = password
508 # Setup dependent packages if required
509 packages = []
510 if dep_package:
511 packages.append(dep_package)
512 if self.uiautomator:
513 packages.append(self._PKG_UIAUTOMATOR)
514 if packages:
515 logging.info('Setting up dependent package(s) %s', packages)
516 self.job.setup_dep(packages)
517
Victor Hsieh2eba8922016-08-17 12:54:14 -0700518 # TODO(b/29341443): Run logcat on non ArcTest test cases too.
519 with open(_VAR_LOGCAT_PATH, 'w') as f:
520 self.logcat_proc = subprocess.Popen(
521 ['android-sh', '-c', 'logcat -v threadtime'],
522 stdout=f,
523 stderr=subprocess.STDOUT,
524 close_fds=True)
525
526 wait_for_adb_ready()
527
528 # package_verifier_user_consent == -1 means to reject Google's
529 # verification on the server side through Play Store. This suppress a
530 # consent dialog from the system.
531 adb_shell('settings put secure package_verifier_user_consent -1')
532 # TODO(30310952): Remove the workaround below to a Phonesky bug.
533 adb_shell('am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE '
534 '-e finsky.platform_anti_malware_enabled false')
535 adb_shell('settings put global package_verifier_enable 0')
536 adb_shell('settings put secure install_non_market_apps 1')
537
538 if self.dep_package:
539 apk_path = os.path.join(self.autodir, 'deps', self.dep_package)
540 if self.apks:
541 for apk in self.apks:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800542 logging.info('Installing %s', apk)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700543 adb_install('%s/%s' % (apk_path, apk))
544 # Verify if package(s) are installed correctly
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800545 if not full_pkg_names:
Victor Hsieh2eba8922016-08-17 12:54:14 -0700546 raise error.TestError('Package names of apks expected')
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800547 for pkg in full_pkg_names:
548 logging.info('Check if %s is installed', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700549 if not is_package_installed(pkg):
550 raise error.TestError('Package %s not found' % pkg)
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800551 # Make sure full_pkg_names contains installed packages only
552 # so arc_teardown() knows what packages to uninstall.
553 self.full_pkg_names.append(pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700554
555 if self.uiautomator:
556 path = os.path.join(self.autodir, 'deps', self._PKG_UIAUTOMATOR)
557 sys.path.append(path)
558
559 def _stop_logcat(self):
560 """Stop the adb logcat process gracefully."""
561 if not self.logcat_proc:
562 return
563 # Running `adb kill-server` should have killed `adb logcat`
564 # process, but just in case also send termination signal.
565 self.logcat_proc.terminate()
566
567 class TimeoutException(Exception):
568 """Termination timeout timed out."""
569
570 try:
571 utils.poll_for_condition(
572 condition=lambda: self.logcat_proc.poll() is not None,
573 exception=TimeoutException,
574 timeout=10,
575 sleep_interval=0.1,
576 desc='Waiting for adb logcat to terminate')
577 except TimeoutException:
578 logging.info('Killing adb logcat due to timeout')
579 self.logcat_proc.kill()
580 self.logcat_proc.wait()
581
582 def arc_teardown(self):
583 """ARC test teardown.
584
585 This function removes all installed packages in arc_setup stage
586 first. Then, it restores package verification and disables non-market
587 APK installation.
588
589 """
590 if self.full_pkg_names:
591 for pkg in self.full_pkg_names:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800592 logging.info('Uninstalling %s', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700593 if not is_package_installed(pkg):
594 raise error.TestError('Package %s was not installed' % pkg)
595 adb_uninstall(pkg)
596 if self.uiautomator:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800597 logging.info('Uninstalling %s', self._FULL_PKG_NAME_UIAUTOMATOR)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700598 adb_uninstall(self._FULL_PKG_NAME_UIAUTOMATOR)
599 adb_shell('settings put secure install_non_market_apps 0')
600 adb_shell('settings put global package_verifier_enable 1')
601 # TODO(30310952): Remove the workaround below to a Phonesky bug.
602 adb_shell('am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE '
603 '--esn finsky.platform_anti_malware_enabled')
604 adb_shell('settings put secure package_verifier_user_consent 0')
605
606 remove_android_file(_ANDROID_ADB_KEYS_PATH)
607 utils.system_output('adb kill-server')
608
609 def block_outbound(self):
610 """ Blocks the connection from the container to outer network.
611
612 The iptables settings accept only 192.168.254.2 port 5555 (adb) and
613 localhost port 9008 (uiautomator)
614 """
615 logging.info('Blocking outbound connection')
616 _android_shell('iptables -I OUTPUT -j REJECT')
617 _android_shell('iptables -I OUTPUT -p tcp -s 192.168.254.2 --sport 5555 -j ACCEPT')
618 _android_shell('iptables -I OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
619 _android_shell('iptables -I OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
620
621
622 def unblock_outbound(self):
623 """ Unblocks the connection from the container to outer network.
624
625 The iptables settings are not permanent which means they reset on
626 each instance invocation. But we can still use this function to
627 unblock the outbound connections during the test if needed.
628 """
629 logging.info('Unblocking outbound connection')
630 _android_shell('iptables -D OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
631 _android_shell('iptables -D OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
632 _android_shell('iptables -D OUTPUT -p tcp -s 192.168.254.2 --sport 5555 -j ACCEPT')
633 _android_shell('iptables -D OUTPUT -j REJECT')