blob: 3f5c078e785f7a1299c0970b0efb3fa3a72f6dfb [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 """
Shuhei Takahashic4127412017-02-01 15:40:09 +0900219 output = adb_shell('ps | grep %s' % pipes.quote(' %s$' % process_name))
220 return bool(output)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700221
222
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800223def check_android_file_exists(filename):
224 """Checks whether the given file exists in the Android filesystem
225
226 @param filename: File to check.
227 """
228 return adb_shell('test -e {} && echo FileExists'.format(
229 pipes.quote(filename))).find("FileExists") >= 0
230
231
Victor Hsieh2eba8922016-08-17 12:54:14 -0700232def read_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800233 """Reads a file in Android filesystem.
234
235 @param filename: File to read.
236 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700237 with tempfile.NamedTemporaryFile() as tmpfile:
238 adb_cmd('pull %s %s' % (pipes.quote(filename), pipes.quote(tmpfile.name)))
239 with open(tmpfile.name) as f:
240 return f.read()
241
242 return None
243
244
245def write_android_file(filename, data):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800246 """Writes to a file in Android filesystem.
247
248 @param filename: File to write.
249 @param data: Data to write.
250 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700251 with tempfile.NamedTemporaryFile() as tmpfile:
252 tmpfile.write(data)
253 tmpfile.flush()
254
255 adb_cmd('push %s %s' % (pipes.quote(tmpfile.name), pipes.quote(filename)))
256
257
258def _write_android_file(filename, data):
259 """Writes to a file in Android filesystem.
260
261 This is an internal function used to bootstrap adb.
262 Tests should use write_android_file instead.
263 """
264 android_cmd = 'cat > %s' % pipes.quote(filename)
265 cros_cmd = 'android-sh -c %s' % pipes.quote(android_cmd)
266 utils.run(cros_cmd, stdin=data)
267
268
269def remove_android_file(filename):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800270 """Removes a file in Android filesystem.
271
272 @param filename: File to remove.
273 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700274 adb_shell('rm -f %s' % pipes.quote(filename))
275
276
277def wait_for_android_boot(timeout=None):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800278 """Sleep until Android has completed booting or timeout occurs.
279
280 @param timeout: Timeout in seconds.
281 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700282 arc_common.wait_for_android_boot(timeout)
283
284
285def wait_for_android_process(process_name,
286 timeout=_WAIT_FOR_ANDROID_PROCESS_SECONDS):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800287 """Sleep until an Android process is running or timeout occurs.
288
289 @param process_name: Process name.
290 @param timeout: Timeout in seconds.
291 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700292 condition = lambda: is_android_process_running(process_name)
293 utils.poll_for_condition(condition=condition,
294 desc='%s is running' % process_name,
295 timeout=timeout,
296 sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
297
298
299def _android_shell(cmd, **kwargs):
300 """Execute cmd instead the Android container.
301
302 This function is strictly for internal use only, as commands do not run in a
303 fully consistent Android environment. Prefer adb_shell instead.
304 """
305 return utils.system_output('android-sh -c {}'.format(pipes.quote(cmd)),
306 **kwargs)
307
308
309def is_android_container_alive():
310 """Check if android container is alive."""
311 try:
312 container_pid = get_container_pid()
313 except Exception:
314 return False
315 return utils.pid_is_alive(int(container_pid))
316
317
318def is_package_installed(package):
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800319 """Check if a package is installed. adb must be ready.
320
321 @param package: Package in request.
322 """
Victor Hsieh2eba8922016-08-17 12:54:14 -0700323 packages = adb_shell('pm list packages').splitlines()
324 package_entry = 'package:{}'.format(package)
325 return package_entry in packages
326
327
328def _before_iteration_hook(obj):
329 """Executed by parent class before every iteration.
330
331 This function resets the run_once_finished flag before every iteration
332 so we can detect failure on every single iteration.
333
334 Args:
335 obj: the test itself
336 """
337 obj.run_once_finished = False
338
339
340def _after_iteration_hook(obj):
341 """Executed by parent class after every iteration.
342
343 The parent class will handle exceptions and failures in the run and will
344 always call this hook afterwards. Take a screenshot if the run has not
345 been marked as finished (i.e. there was a failure/exception).
346
347 Args:
348 obj: the test itself
349 """
350 if not obj.run_once_finished:
351 if not os.path.exists(_SCREENSHOT_DIR_PATH):
352 os.mkdir(_SCREENSHOT_DIR_PATH, 0755)
353 obj.num_screenshots += 1
354 if obj.num_screenshots <= _MAX_SCREENSHOT_NUM:
355 logging.warning('Iteration %d failed, taking a screenshot.',
356 obj.iteration)
357 from cros.graphics.drm import crtcScreenshot
358 image = crtcScreenshot()
359 image.save('{}/{}_iter{}.png'.format(_SCREENSHOT_DIR_PATH,
360 _SCREENSHOT_BASENAME,
361 obj.iteration))
362 else:
363 logging.warning('Too many failures, no screenshot taken')
364
365
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800366def send_keycode(keycode):
367 """Sends the given keycode to the container
368
369 @param keycode: keycode to send.
370 """
371 adb_shell('input keyevent {}'.format(keycode))
372
373
Shuhei Takahashi8f8524d2017-01-31 14:22:53 +0900374def get_android_sdk_version():
375 """Returns the Android SDK version.
376
377 This function can be called before Android container boots.
378 """
379 with open('/etc/lsb-release') as f:
380 values = dict(line.split('=', 1) for line in f.read().splitlines())
381 try:
382 return int(values['CHROMEOS_ARC_ANDROID_SDK_VERSION'])
383 except (KeyError, ValueError):
384 raise error.TestError('Could not determine Android SDK version')
385
386
Victor Hsieh2eba8922016-08-17 12:54:14 -0700387class ArcTest(test.test):
388 """ Base class of ARC Test.
389
390 This class could be used as super class of an ARC test for saving
391 redundant codes for container bringup, autotest-dep package(s) including
392 uiautomator setup if required, and apks install/remove during
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800393 arc_setup/arc_teardown, respectively. By default arc_setup() is called in
394 initialize() after Android have been brought up. It could also be overridden
395 to perform non-default tasks. For example, a simple ArcHelloWorldTest can be
396 just implemented with print 'HelloWorld' in its run_once() and no other
397 functions are required. We could expect ArcHelloWorldTest would bring up
398 browser and wait for container up, then print 'Hello World', and shutdown
399 browser after. As a precaution, if you overwrite initialize(), arc_setup(),
400 or cleanup() function(s) in ARC test, remember to call the corresponding
401 function(s) in this base class as well.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700402
403 """
404 version = 1
405 _PKG_UIAUTOMATOR = 'uiautomator'
406 _FULL_PKG_NAME_UIAUTOMATOR = 'com.github.uiautomator'
407
408 def __init__(self, *args, **kwargs):
409 """Initialize flag setting."""
410 super(ArcTest, self).__init__(*args, **kwargs)
411 self.initialized = False
412 # Set the flag run_once_finished to detect if a test is executed
413 # successfully without any exception thrown. Otherwise, generate
414 # a screenshot in /var/log for debugging.
415 self.run_once_finished = False
416 self.logcat_proc = None
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800417 self.dep_package = None
418 self.apks = None
419 self.full_pkg_names = []
420 self.uiautomator = False
421 self.email_id = None
422 self.password = None
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800423 self._chrome = None
Victor Hsieh2eba8922016-08-17 12:54:14 -0700424 if os.path.exists(_SCREENSHOT_DIR_PATH):
425 shutil.rmtree(_SCREENSHOT_DIR_PATH)
426 self.register_before_iteration_hook(_before_iteration_hook)
427 self.register_after_iteration_hook(_after_iteration_hook)
428 # Keep track of the number of debug screenshots taken and keep the
429 # total number sane to avoid issues.
430 self.num_screenshots = 0
431
432 def initialize(self, extension_path=None,
433 arc_mode=arc_common.ARC_MODE_ENABLED, **chrome_kargs):
434 """Log in to a test account."""
435 extension_paths = [extension_path] if extension_path else []
436 self._chrome = chrome.Chrome(extension_paths=extension_paths,
Victor Hsieh2eba8922016-08-17 12:54:14 -0700437 arc_mode=arc_mode,
438 **chrome_kargs)
439 if extension_path:
440 self._extension = self._chrome.get_extension(extension_path)
441 else:
442 self._extension = None
443 # With ARC enabled, Chrome will wait until container to boot up
444 # before returning here, see chrome.py.
445 self.initialized = True
Victor Hsieh2eba8922016-08-17 12:54:14 -0700446 try:
447 if is_android_container_alive():
448 self.arc_setup()
449 else:
450 logging.error('Container is alive?')
451 except Exception as err:
452 self.cleanup()
453 raise error.TestFail(err)
454
455 def after_run_once(self):
456 """Executed after run_once() only if there were no errors.
457
458 This function marks the run as finished with a flag. If there was a
459 failure the flag won't be set and the failure can then be detected by
460 testing the run_once_finished flag.
461 """
462 logging.info('After run_once')
463 self.run_once_finished = True
464
465 def cleanup(self):
466 """Log out of Chrome."""
467 if not self.initialized:
468 logging.info('Skipping ARC cleanup: not initialized')
469 return
470 logging.info('Starting ARC cleanup')
471 try:
472 if is_android_container_alive():
473 self.arc_teardown()
474 except Exception as err:
475 raise error.TestFail(err)
476 finally:
477 try:
478 self._stop_logcat()
479 finally:
Chen-Hao Chang@google.com1d6f3b42016-09-26 15:17:57 +0800480 if self._chrome is not None:
481 self._chrome.close()
Victor Hsieh2eba8922016-08-17 12:54:14 -0700482
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800483 def arc_setup(self, dep_package=None, apks=None, full_pkg_names=[],
484 uiautomator=False, email_id=None, password=None):
485 """ARC test setup: Setup dependencies and install apks.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700486
487 This function disables package verification and enables non-market
488 APK installation. Then, it installs specified APK(s) and uiautomator
489 package and path if required in a test.
490
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800491 @param dep_package: Package name of autotest_deps APK package.
492 @param apks: Array of APK names to be installed in dep_package.
493 @param full_pkg_names: Array of full package names to be removed
494 in teardown.
495 @param uiautomator: uiautomator python package is required or not.
496
497 @param email_id: email id to be attached to the android. Only used
498 when account_util is set to true.
499 @param password: password related to the email_id.
Victor Hsieh2eba8922016-08-17 12:54:14 -0700500 """
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800501 if not self.initialized:
502 logging.info('Skipping ARC setup: not initialized')
503 return
504 logging.info('Starting ARC setup')
505 self.dep_package = dep_package
506 self.apks = apks
507 self.uiautomator = uiautomator
508 self.email_id = email_id
509 self.password = password
510 # Setup dependent packages if required
511 packages = []
512 if dep_package:
513 packages.append(dep_package)
514 if self.uiautomator:
515 packages.append(self._PKG_UIAUTOMATOR)
516 if packages:
517 logging.info('Setting up dependent package(s) %s', packages)
518 self.job.setup_dep(packages)
519
Victor Hsieh2eba8922016-08-17 12:54:14 -0700520 # TODO(b/29341443): Run logcat on non ArcTest test cases too.
521 with open(_VAR_LOGCAT_PATH, 'w') as f:
522 self.logcat_proc = subprocess.Popen(
523 ['android-sh', '-c', 'logcat -v threadtime'],
524 stdout=f,
525 stderr=subprocess.STDOUT,
526 close_fds=True)
527
528 wait_for_adb_ready()
529
530 # package_verifier_user_consent == -1 means to reject Google's
531 # verification on the server side through Play Store. This suppress a
532 # consent dialog from the system.
533 adb_shell('settings put secure package_verifier_user_consent -1')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700534 adb_shell('settings put global package_verifier_enable 0')
535 adb_shell('settings put secure install_non_market_apps 1')
536
537 if self.dep_package:
538 apk_path = os.path.join(self.autodir, 'deps', self.dep_package)
539 if self.apks:
540 for apk in self.apks:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800541 logging.info('Installing %s', apk)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700542 adb_install('%s/%s' % (apk_path, apk))
543 # Verify if package(s) are installed correctly
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800544 if not full_pkg_names:
Victor Hsieh2eba8922016-08-17 12:54:14 -0700545 raise error.TestError('Package names of apks expected')
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800546 for pkg in full_pkg_names:
547 logging.info('Check if %s is installed', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700548 if not is_package_installed(pkg):
549 raise error.TestError('Package %s not found' % pkg)
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800550 # Make sure full_pkg_names contains installed packages only
551 # so arc_teardown() knows what packages to uninstall.
552 self.full_pkg_names.append(pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700553
554 if self.uiautomator:
555 path = os.path.join(self.autodir, 'deps', self._PKG_UIAUTOMATOR)
556 sys.path.append(path)
557
558 def _stop_logcat(self):
559 """Stop the adb logcat process gracefully."""
560 if not self.logcat_proc:
561 return
562 # Running `adb kill-server` should have killed `adb logcat`
563 # process, but just in case also send termination signal.
564 self.logcat_proc.terminate()
565
566 class TimeoutException(Exception):
567 """Termination timeout timed out."""
568
569 try:
570 utils.poll_for_condition(
571 condition=lambda: self.logcat_proc.poll() is not None,
572 exception=TimeoutException,
573 timeout=10,
574 sleep_interval=0.1,
575 desc='Waiting for adb logcat to terminate')
576 except TimeoutException:
577 logging.info('Killing adb logcat due to timeout')
578 self.logcat_proc.kill()
579 self.logcat_proc.wait()
580
581 def arc_teardown(self):
582 """ARC test teardown.
583
584 This function removes all installed packages in arc_setup stage
585 first. Then, it restores package verification and disables non-market
586 APK installation.
587
588 """
589 if self.full_pkg_names:
590 for pkg in self.full_pkg_names:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800591 logging.info('Uninstalling %s', pkg)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700592 if not is_package_installed(pkg):
593 raise error.TestError('Package %s was not installed' % pkg)
594 adb_uninstall(pkg)
595 if self.uiautomator:
Cheng-Yu Leea854fbf2016-09-09 22:25:14 +0800596 logging.info('Uninstalling %s', self._FULL_PKG_NAME_UIAUTOMATOR)
Victor Hsieh2eba8922016-08-17 12:54:14 -0700597 adb_uninstall(self._FULL_PKG_NAME_UIAUTOMATOR)
598 adb_shell('settings put secure install_non_market_apps 0')
599 adb_shell('settings put global package_verifier_enable 1')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700600 adb_shell('settings put secure package_verifier_user_consent 0')
601
602 remove_android_file(_ANDROID_ADB_KEYS_PATH)
603 utils.system_output('adb kill-server')
604
605 def block_outbound(self):
606 """ Blocks the connection from the container to outer network.
607
Chung-yih Wang93f55912017-02-17 16:29:01 +0800608 The iptables settings accept only 192.168.254.2 port 5555 (adb) and
Victor Hsieh2eba8922016-08-17 12:54:14 -0700609 localhost port 9008 (uiautomator)
610 """
611 logging.info('Blocking outbound connection')
612 _android_shell('iptables -I OUTPUT -j REJECT')
Chung-yih Wang93f55912017-02-17 16:29:01 +0800613 _android_shell('iptables -I OUTPUT -p tcp -s 192.168.254.2 --sport 5555 -j ACCEPT')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700614 _android_shell('iptables -I OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
615 _android_shell('iptables -I OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
616
617
618 def unblock_outbound(self):
619 """ Unblocks the connection from the container to outer network.
620
621 The iptables settings are not permanent which means they reset on
622 each instance invocation. But we can still use this function to
623 unblock the outbound connections during the test if needed.
624 """
625 logging.info('Unblocking outbound connection')
626 _android_shell('iptables -D OUTPUT -p tcp -s localhost --sport 9008 -j ACCEPT')
627 _android_shell('iptables -D OUTPUT -p tcp -d localhost --dport 9008 -j ACCEPT')
Chung-yih Wang93f55912017-02-17 16:29:01 +0800628 _android_shell('iptables -D OUTPUT -p tcp -s 192.168.254.2 --sport 5555 -j ACCEPT')
Victor Hsieh2eba8922016-08-17 12:54:14 -0700629 _android_shell('iptables -D OUTPUT -j REJECT')