Home | History | Annotate | Download | only in cros
      1 # 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 
      5 import glob
      6 import logging
      7 import os
      8 import pipes
      9 import re
     10 import shutil
     11 import subprocess
     12 import sys
     13 import tempfile
     14 
     15 from autotest_lib.client.bin import test, utils
     16 from autotest_lib.client.common_lib import error
     17 from 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_PID_PATH = '/var/run/containers/android_*/container.pid'
     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 _WAIT_FOR_DATA_MOUNTED_SECONDS = 60
     31 _VAR_LOGCAT_PATH = '/var/log/logcat'
     32 
     33 
     34 def setup_adb_host():
     35     """Setup ADB host keys.
     36 
     37     This sets up the files and environment variables that wait_for_adb_ready()
     38     needs"""
     39     if _ADB_VENDOR_KEYS in os.environ:
     40         return
     41     if not os.path.exists(_ADB_KEYS_PATH):
     42         os.mkdir(_ADB_KEYS_PATH)
     43     # adb expects $HOME to be writable.
     44     os.environ['HOME'] = _ADB_KEYS_PATH
     45 
     46     # Generate and save keys for adb if needed
     47     key_path = os.path.join(_ADB_KEYS_PATH, 'test_key')
     48     if not os.path.exists(key_path):
     49         utils.system('adb keygen ' + pipes.quote(key_path))
     50     os.environ[_ADB_VENDOR_KEYS] = key_path
     51 
     52 
     53 def adb_connect():
     54     """Attempt to connect ADB to the Android container.
     55 
     56     Returns true if successful. Do not call this function directly. Call
     57     wait_for_adb_ready() instead."""
     58     if not is_android_booted():
     59         return False
     60     if utils.system('adb connect localhost:22', ignore_status=True) != 0:
     61         return False
     62     return is_adb_connected()
     63 
     64 
     65 def is_adb_connected():
     66     """Return true if adb is connected to the container."""
     67     output = utils.system_output('adb get-state', ignore_status=True)
     68     logging.debug('adb get-state: %s', output)
     69     return output.strip() == 'device'
     70 
     71 
     72 def is_partial_boot_enabled():
     73     """Return true if partial boot is enabled.
     74 
     75     When partial boot is enabled, Android is started at login screen without
     76     any persistent state (e.g. /data is not mounted).
     77     """
     78     return _android_shell('getprop ro.boot.partial_boot') == '1'
     79 
     80 
     81 def _is_android_data_mounted():
     82     """Return true if Android's /data is mounted with partial boot enabled."""
     83     return _android_shell('getprop ro.data_mounted') == '1'
     84 
     85 
     86 def _wait_for_data_mounted(timeout=_WAIT_FOR_DATA_MOUNTED_SECONDS):
     87     utils.poll_for_condition(
     88             condition=_is_android_data_mounted,
     89             desc='Wait for /data mounted',
     90             timeout=timeout,
     91             sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
     92 
     93 
     94 def wait_for_adb_ready(timeout=_WAIT_FOR_ADB_READY):
     95     """Wait for the ADB client to connect to the ARC container.
     96 
     97     @param timeout: Timeout in seconds.
     98     """
     99     # When partial boot is enabled, although adbd is started at login screen,
    100     # we still need /data to be mounted to set up key-based authentication.
    101     # /data should be mounted once the user has logged in.
    102     if is_partial_boot_enabled():
    103         _wait_for_data_mounted()
    104 
    105     setup_adb_host()
    106     if is_adb_connected():
    107       return
    108 
    109     # Push keys for adb.
    110     pubkey_path = os.environ[_ADB_VENDOR_KEYS] + '.pub'
    111     with open(pubkey_path, 'r') as f:
    112         _write_android_file(_ANDROID_ADB_KEYS_PATH, f.read())
    113     _android_shell('restorecon ' + pipes.quote(_ANDROID_ADB_KEYS_PATH))
    114 
    115     # This starts adbd.
    116     _android_shell('setprop sys.usb.config mtp,adb')
    117 
    118     # Kill existing adb server to ensure that a full reconnect is performed.
    119     utils.system('adb kill-server', ignore_status=True)
    120 
    121     exception = error.TestFail('adb is not ready in %d seconds.' % timeout)
    122     utils.poll_for_condition(adb_connect,
    123                              exception,
    124                              timeout)
    125 
    126 
    127 def grant_permissions(package, permissions):
    128     """Grants permissions to a package.
    129 
    130     @param package: Package name.
    131     @param permissions: A list of permissions.
    132 
    133     """
    134     for permission in permissions:
    135         adb_shell('pm grant %s android.permission.%s' % (
    136                   pipes.quote(package), pipes.quote(permission)))
    137 
    138 
    139 def adb_cmd(cmd, **kwargs):
    140     """Executed cmd using adb. Must wait for adb ready.
    141 
    142     @param cmd: Command to run.
    143     """
    144     wait_for_adb_ready()
    145     return utils.system_output('adb %s' % cmd, **kwargs)
    146 
    147 
    148 def adb_shell(cmd, **kwargs):
    149     """Executed shell command with adb.
    150 
    151     @param cmd: Command to run.
    152     """
    153     output = adb_cmd('shell %s' % pipes.quote(cmd), **kwargs)
    154     # Some android commands include a trailing CRLF in their output.
    155     if kwargs.pop('strip_trailing_whitespace', True):
    156       output = output.rstrip()
    157     return output
    158 
    159 
    160 def adb_install(apk):
    161     """Install an apk into container. You must connect first.
    162 
    163     @param apk: Package to install.
    164     """
    165     return adb_cmd('install -r %s' % apk)
    166 
    167 
    168 def adb_uninstall(apk):
    169     """Remove an apk from container. You must connect first.
    170 
    171     @param apk: Package to uninstall.
    172     """
    173     return adb_cmd('uninstall %s' % apk)
    174 
    175 
    176 def adb_reboot():
    177     """Reboots the container. You must connect first."""
    178     adb_root()
    179     return adb_cmd('reboot', ignore_status=True)
    180 
    181 
    182 def adb_root():
    183     """Restart adbd with root permission."""
    184     adb_cmd('root')
    185 
    186 
    187 def get_container_root():
    188     """Returns path to Android container root directory.
    189 
    190     Raises:
    191       TestError if no container root directory is found, or
    192       more than one container root directories are found.
    193     """
    194     # Find the PID file rather than the android_XXXXXX/ directory to ignore
    195     # stale and empty android_XXXXXX/ directories when they exist.
    196     # TODO(yusukes): Investigate why libcontainer sometimes fails to remove
    197     # the directory. See b/63376749 for more details.
    198     arc_container_pid_files = glob.glob(_ANDROID_CONTAINER_PID_PATH)
    199 
    200     if len(arc_container_pid_files) == 0:
    201         raise error.TestError('Android container not available')
    202 
    203     if len(arc_container_pid_files) > 1:
    204         raise error.TestError('Multiple Android containers found: %r. '
    205                               'Reboot your DUT to recover.' % (
    206                                   arc_container_pid_files))
    207 
    208     return os.path.dirname(arc_container_pid_files[0])
    209 
    210 
    211 def get_job_pid(job_name):
    212     """Returns the PID of an upstart job."""
    213     status = utils.system_output('status %s' % job_name)
    214     match = re.match(r'^%s start/running, process (\d+)$' % job_name,
    215                      status)
    216     if not match:
    217         raise error.TestError('Unexpected status: "%s"' % status)
    218     return match.group(1)
    219 
    220 
    221 def get_container_pid():
    222     """Returns the PID of the container."""
    223     container_root = get_container_root()
    224     pid_path = os.path.join(container_root, 'container.pid')
    225     return utils.read_one_line(pid_path)
    226 
    227 
    228 def get_sdcard_pid():
    229     """Returns the PID of the sdcard container."""
    230     return utils.read_one_line(_SDCARD_PID_PATH)
    231 
    232 
    233 def get_removable_media_pid():
    234     """Returns the PID of the arc-removable-media FUSE daemon."""
    235     job_pid = get_job_pid('arc-removable-media')
    236     # |job_pid| is the minijail process, obtain the PID of the process running
    237     # inside the mount namespace.
    238     # FUSE process is the only process running as chronos in the process group.
    239     return utils.system_output('pgrep -u chronos -g %s' % job_pid)
    240 
    241 
    242 def get_obb_mounter_pid():
    243     """Returns the PID of the OBB mounter."""
    244     return utils.system_output('pgrep -f -u root ^/usr/bin/arc-obb-mounter')
    245 
    246 
    247 def is_android_booted():
    248     """Return whether Android has completed booting."""
    249     # We used to check sys.boot_completed system property to detect Android has
    250     # booted in Android M, but in Android N it is set long before BOOT_COMPLETED
    251     # intent is broadcast. So we read event logs instead.
    252     log = _android_shell(
    253         'logcat -d -b events *:S arc_system_event', ignore_status=True)
    254     return 'ArcAppLauncher:started' in log
    255 
    256 
    257 def is_android_process_running(process_name):
    258     """Return whether Android has completed booting.
    259 
    260     @param process_name: Process name.
    261     """
    262     output = adb_shell('ps | grep %s' % pipes.quote(' %s$' % process_name))
    263     return bool(output)
    264 
    265 
    266 def check_android_file_exists(filename):
    267     """Checks whether the given file exists in the Android filesystem
    268 
    269     @param filename: File to check.
    270     """
    271     return adb_shell('test -e {} && echo FileExists'.format(
    272             pipes.quote(filename))).find("FileExists") >= 0
    273 
    274 
    275 def read_android_file(filename):
    276     """Reads a file in Android filesystem.
    277 
    278     @param filename: File to read.
    279     """
    280     with tempfile.NamedTemporaryFile() as tmpfile:
    281         adb_cmd('pull %s %s' % (pipes.quote(filename),
    282                                 pipes.quote(tmpfile.name)))
    283         with open(tmpfile.name) as f:
    284             return f.read()
    285 
    286     return None
    287 
    288 
    289 def write_android_file(filename, data):
    290     """Writes to a file in Android filesystem.
    291 
    292     @param filename: File to write.
    293     @param data: Data to write.
    294     """
    295     with tempfile.NamedTemporaryFile() as tmpfile:
    296         tmpfile.write(data)
    297         tmpfile.flush()
    298 
    299         adb_cmd('push %s %s' % (pipes.quote(tmpfile.name),
    300                                 pipes.quote(filename)))
    301 
    302 
    303 def _write_android_file(filename, data):
    304     """Writes to a file in Android filesystem.
    305 
    306     This is an internal function used to bootstrap adb.
    307     Tests should use write_android_file instead.
    308     """
    309     android_cmd = 'cat > %s' % pipes.quote(filename)
    310     cros_cmd = 'android-sh -c %s' % pipes.quote(android_cmd)
    311     utils.run(cros_cmd, stdin=data)
    312 
    313 
    314 def remove_android_file(filename):
    315     """Removes a file in Android filesystem.
    316 
    317     @param filename: File to remove.
    318     """
    319     adb_shell('rm -f %s' % pipes.quote(filename))
    320 
    321 
    322 def wait_for_android_boot(timeout=None):
    323     """Sleep until Android has completed booting or timeout occurs.
    324 
    325     @param timeout: Timeout in seconds.
    326     """
    327     arc_common.wait_for_android_boot(timeout)
    328 
    329 
    330 def wait_for_android_process(process_name,
    331                              timeout=_WAIT_FOR_ANDROID_PROCESS_SECONDS):
    332     """Sleep until an Android process is running or timeout occurs.
    333 
    334     @param process_name: Process name.
    335     @param timeout: Timeout in seconds.
    336     """
    337     condition = lambda: is_android_process_running(process_name)
    338     utils.poll_for_condition(condition=condition,
    339                              desc='%s is running' % process_name,
    340                              timeout=timeout,
    341                              sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
    342 
    343 
    344 def _android_shell(cmd, **kwargs):
    345     """Execute cmd instead the Android container.
    346 
    347     This function is strictly for internal use only, as commands do not run in a
    348     fully consistent Android environment. Prefer adb_shell instead.
    349     """
    350     return utils.system_output('android-sh -c {}'.format(pipes.quote(cmd)),
    351                                **kwargs)
    352 
    353 
    354 def is_android_container_alive():
    355     """Check if android container is alive."""
    356     try:
    357         container_pid = get_container_pid()
    358     except Exception, e:
    359         logging.error('is_android_container_alive failed: %r', e)
    360         return False
    361     return utils.pid_is_alive(int(container_pid))
    362 
    363 
    364 def is_package_installed(package):
    365     """Check if a package is installed. adb must be ready.
    366 
    367     @param package: Package in request.
    368     """
    369     packages = adb_shell('pm list packages').splitlines()
    370     package_entry = 'package:{}'.format(package)
    371     return package_entry in packages
    372 
    373 
    374 def _before_iteration_hook(obj):
    375     """Executed by parent class before every iteration.
    376 
    377     This function resets the run_once_finished flag before every iteration
    378     so we can detect failure on every single iteration.
    379 
    380     Args:
    381         obj: the test itself
    382     """
    383     obj.run_once_finished = False
    384 
    385 
    386 def _after_iteration_hook(obj):
    387     """Executed by parent class after every iteration.
    388 
    389     The parent class will handle exceptions and failures in the run and will
    390     always call this hook afterwards. Take a screenshot if the run has not
    391     been marked as finished (i.e. there was a failure/exception).
    392 
    393     Args:
    394         obj: the test itself
    395     """
    396     if not obj.run_once_finished:
    397         if not os.path.exists(_SCREENSHOT_DIR_PATH):
    398             os.mkdir(_SCREENSHOT_DIR_PATH, 0755)
    399         obj.num_screenshots += 1
    400         if obj.num_screenshots <= _MAX_SCREENSHOT_NUM:
    401             logging.warning('Iteration %d failed, taking a screenshot.',
    402                             obj.iteration)
    403             from cros.graphics.gbm import crtcScreenshot
    404             try:
    405                 image = crtcScreenshot()
    406                 image.save('{}/{}_iter{}.png'.format(_SCREENSHOT_DIR_PATH,
    407                                                      _SCREENSHOT_BASENAME,
    408                                                      obj.iteration))
    409             except Exception:
    410                 e = sys.exc_info()[0]
    411                 logging.warning('Unable to capture screenshot. %s' % e)
    412         else:
    413             logging.warning('Too many failures, no screenshot taken')
    414 
    415 
    416 def send_keycode(keycode):
    417     """Sends the given keycode to the container
    418 
    419     @param keycode: keycode to send.
    420     """
    421     adb_shell('input keyevent {}'.format(keycode))
    422 
    423 
    424 def get_android_sdk_version():
    425     """Returns the Android SDK version.
    426 
    427     This function can be called before Android container boots.
    428     """
    429     with open('/etc/lsb-release') as f:
    430         values = dict(line.split('=', 1) for line in f.read().splitlines())
    431     try:
    432         return int(values['CHROMEOS_ARC_ANDROID_SDK_VERSION'])
    433     except (KeyError, ValueError):
    434         raise error.TestError('Could not determine Android SDK version')
    435 
    436 
    437 class ArcTest(test.test):
    438     """ Base class of ARC Test.
    439 
    440     This class could be used as super class of an ARC test for saving
    441     redundant codes for container bringup, autotest-dep package(s) including
    442     uiautomator setup if required, and apks install/remove during
    443     arc_setup/arc_teardown, respectively. By default arc_setup() is called in
    444     initialize() after Android have been brought up. It could also be overridden
    445     to perform non-default tasks. For example, a simple ArcHelloWorldTest can be
    446     just implemented with print 'HelloWorld' in its run_once() and no other
    447     functions are required. We could expect ArcHelloWorldTest would bring up
    448     browser and  wait for container up, then print 'Hello World', and shutdown
    449     browser after. As a precaution, if you overwrite initialize(), arc_setup(),
    450     or cleanup() function(s) in ARC test, remember to call the corresponding
    451     function(s) in this base class as well.
    452 
    453     """
    454     version = 1
    455     _PKG_UIAUTOMATOR = 'uiautomator'
    456     _FULL_PKG_NAME_UIAUTOMATOR = 'com.github.uiautomator'
    457 
    458     def __init__(self, *args, **kwargs):
    459         """Initialize flag setting."""
    460         super(ArcTest, self).__init__(*args, **kwargs)
    461         self.initialized = False
    462         # Set the flag run_once_finished to detect if a test is executed
    463         # successfully without any exception thrown. Otherwise, generate
    464         # a screenshot in /var/log for debugging.
    465         self.run_once_finished = False
    466         self.logcat_proc = None
    467         self.dep_package = None
    468         self.apks = None
    469         self.full_pkg_names = []
    470         self.uiautomator = False
    471         self.email_id = None
    472         self.password = None
    473         self._chrome = None
    474         if os.path.exists(_SCREENSHOT_DIR_PATH):
    475             shutil.rmtree(_SCREENSHOT_DIR_PATH)
    476         self.register_before_iteration_hook(_before_iteration_hook)
    477         self.register_after_iteration_hook(_after_iteration_hook)
    478         # Keep track of the number of debug screenshots taken and keep the
    479         # total number sane to avoid issues.
    480         self.num_screenshots = 0
    481 
    482     def initialize(self, extension_path=None,
    483                    arc_mode=arc_common.ARC_MODE_ENABLED, **chrome_kargs):
    484         """Log in to a test account."""
    485         extension_paths = [extension_path] if extension_path else []
    486         self._chrome = chrome.Chrome(extension_paths=extension_paths,
    487                                      arc_mode=arc_mode,
    488                                      **chrome_kargs)
    489         if extension_path:
    490             self._extension = self._chrome.get_extension(extension_path)
    491         else:
    492             self._extension = None
    493         # With ARC enabled, Chrome will wait until container to boot up
    494         # before returning here, see chrome.py.
    495         self.initialized = True
    496         try:
    497             if is_android_container_alive():
    498                 self.arc_setup()
    499             else:
    500                 logging.error('Container is alive?')
    501         except Exception as err:
    502             self.cleanup()
    503             raise error.TestFail(err)
    504 
    505     def after_run_once(self):
    506         """Executed after run_once() only if there were no errors.
    507 
    508         This function marks the run as finished with a flag. If there was a
    509         failure the flag won't be set and the failure can then be detected by
    510         testing the run_once_finished flag.
    511         """
    512         logging.info('After run_once')
    513         self.run_once_finished = True
    514 
    515     def cleanup(self):
    516         """Log out of Chrome."""
    517         if not self.initialized:
    518             logging.info('Skipping ARC cleanup: not initialized')
    519             return
    520         logging.info('Starting ARC cleanup')
    521         try:
    522             if is_android_container_alive():
    523                 self.arc_teardown()
    524         except Exception as err:
    525             raise error.TestFail(err)
    526         finally:
    527             try:
    528                 self._stop_logcat()
    529             finally:
    530                 if self._chrome is not None:
    531                     self._chrome.close()
    532 
    533     def arc_setup(self, dep_package=None, apks=None, full_pkg_names=None,
    534                   uiautomator=False, email_id=None, password=None,
    535                   block_outbound=False):
    536         """ARC test setup: Setup dependencies and install apks.
    537 
    538         This function disables package verification and enables non-market
    539         APK installation. Then, it installs specified APK(s) and uiautomator
    540         package and path if required in a test.
    541 
    542         @param dep_package: Package name of autotest_deps APK package.
    543         @param apks: Array of APK names to be installed in dep_package.
    544         @param full_pkg_names: Array of full package names to be removed
    545                                in teardown.
    546         @param uiautomator: uiautomator python package is required or not.
    547 
    548         @param email_id: email id to be attached to the android. Only used
    549                          when  account_util is set to true.
    550         @param password: password related to the email_id.
    551         @param block_outbound: block outbound network traffic during a test.
    552         """
    553         if not self.initialized:
    554             logging.info('Skipping ARC setup: not initialized')
    555             return
    556         logging.info('Starting ARC setup')
    557         self.dep_package = dep_package
    558         self.apks = apks
    559         self.uiautomator = uiautomator
    560         self.email_id = email_id
    561         self.password = password
    562         # Setup dependent packages if required
    563         packages = []
    564         if dep_package:
    565             packages.append(dep_package)
    566         if self.uiautomator:
    567             packages.append(self._PKG_UIAUTOMATOR)
    568         if packages:
    569             logging.info('Setting up dependent package(s) %s', packages)
    570             self.job.setup_dep(packages)
    571 
    572         # TODO(b/29341443): Run logcat on non ArcTest test cases too.
    573         with open(_VAR_LOGCAT_PATH, 'w') as f:
    574             self.logcat_proc = subprocess.Popen(
    575                 ['android-sh', '-c', 'logcat -v threadtime'],
    576                 stdout=f,
    577                 stderr=subprocess.STDOUT,
    578                 close_fds=True)
    579 
    580         wait_for_adb_ready()
    581 
    582         # package_verifier_user_consent == -1 means to reject Google's
    583         # verification on the server side through Play Store.  This suppress a
    584         # consent dialog from the system.
    585         adb_shell('settings put secure package_verifier_user_consent -1')
    586         adb_shell('settings put global package_verifier_enable 0')
    587         adb_shell('settings put secure install_non_market_apps 1')
    588 
    589         if self.dep_package:
    590             apk_path = os.path.join(self.autodir, 'deps', self.dep_package)
    591             if self.apks:
    592                 for apk in self.apks:
    593                     logging.info('Installing %s', apk)
    594                     adb_install('%s/%s' % (apk_path, apk))
    595                 # Verify if package(s) are installed correctly
    596                 if not full_pkg_names:
    597                     raise error.TestError('Package names of apks expected')
    598                 for pkg in full_pkg_names:
    599                     logging.info('Check if %s is installed', pkg)
    600                     if not is_package_installed(pkg):
    601                         raise error.TestError('Package %s not found' % pkg)
    602                     # Make sure full_pkg_names contains installed packages only
    603                     # so arc_teardown() knows what packages to uninstall.
    604                     self.full_pkg_names.append(pkg)
    605 
    606         if self.uiautomator:
    607             path = os.path.join(self.autodir, 'deps', self._PKG_UIAUTOMATOR)
    608             sys.path.append(path)
    609         if block_outbound:
    610             self.block_outbound()
    611 
    612     def _stop_logcat(self):
    613         """Stop the adb logcat process gracefully."""
    614         if not self.logcat_proc:
    615             return
    616         # Running `adb kill-server` should have killed `adb logcat`
    617         # process, but just in case also send termination signal.
    618         self.logcat_proc.terminate()
    619 
    620         class TimeoutException(Exception):
    621             """Termination timeout timed out."""
    622 
    623         try:
    624             utils.poll_for_condition(
    625                 condition=lambda: self.logcat_proc.poll() is not None,
    626                 exception=TimeoutException,
    627                 timeout=10,
    628                 sleep_interval=0.1,
    629                 desc='Waiting for adb logcat to terminate')
    630         except TimeoutException:
    631             logging.info('Killing adb logcat due to timeout')
    632             self.logcat_proc.kill()
    633             self.logcat_proc.wait()
    634 
    635     def arc_teardown(self):
    636         """ARC test teardown.
    637 
    638         This function removes all installed packages in arc_setup stage
    639         first. Then, it restores package verification and disables non-market
    640         APK installation.
    641 
    642         """
    643         if self.full_pkg_names:
    644             for pkg in self.full_pkg_names:
    645                 logging.info('Uninstalling %s', pkg)
    646                 if not is_package_installed(pkg):
    647                     raise error.TestError('Package %s was not installed' % pkg)
    648                 adb_uninstall(pkg)
    649         if self.uiautomator:
    650             logging.info('Uninstalling %s', self._FULL_PKG_NAME_UIAUTOMATOR)
    651             adb_uninstall(self._FULL_PKG_NAME_UIAUTOMATOR)
    652         adb_shell('settings put secure install_non_market_apps 0')
    653         adb_shell('settings put global package_verifier_enable 1')
    654         adb_shell('settings put secure package_verifier_user_consent 0')
    655 
    656         remove_android_file(_ANDROID_ADB_KEYS_PATH)
    657         utils.system_output('adb kill-server')
    658 
    659     def block_outbound(self):
    660         """ Blocks the connection from the container to outer network.
    661 
    662             The iptables settings accept only 100.115.92.2 port 5555 (adb) and
    663             all local connections, e.g. uiautomator.
    664         """
    665         logging.info('Blocking outbound connection')
    666         _android_shell('iptables -I OUTPUT -j REJECT')
    667         _android_shell('iptables -I OUTPUT -p tcp -s 100.115.92.2 --sport 5555 '
    668                        '-j ACCEPT')
    669         _android_shell('iptables -I OUTPUT -p tcp -d localhost -j ACCEPT')
    670 
    671     def unblock_outbound(self):
    672         """ Unblocks the connection from the container to outer network.
    673 
    674             The iptables settings are not permanent which means they reset on
    675             each instance invocation. But we can still use this function to
    676             unblock the outbound connections during the test if needed.
    677         """
    678         logging.info('Unblocking outbound connection')
    679         _android_shell('iptables -D OUTPUT -p tcp -d localhost -j ACCEPT')
    680         _android_shell('iptables -D OUTPUT -p tcp -s 100.115.92.2 --sport 5555 '
    681                        '-j ACCEPT')
    682         _android_shell('iptables -D OUTPUT -j REJECT')
    683