12eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh# Copyright 2015 The Chromium OS Authors. All rights reserved.
22eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh# Use of this source code is governed by a BSD-style license that can be
32eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh# found in the LICENSE file.
42eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
52eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport glob
62eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport logging
72eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport os
82eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport pipes
92eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport re
102eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport shutil
112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport subprocess
122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport sys
132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehimport tempfile
142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehfrom autotest_lib.client.bin import test, utils
162eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehfrom autotest_lib.client.common_lib import error
172eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehfrom autotest_lib.client.common_lib.cros import chrome, arc_common
182eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
192eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_ADB_KEYS_PATH = '/tmp/adb_keys'
202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_ADB_VENDOR_KEYS = 'ADB_VENDOR_KEYS'
2155a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato_ANDROID_CONTAINER_PID_PATH = '/var/run/containers/android_*/container.pid'
222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_SCREENSHOT_DIR_PATH = '/var/log/arc-screenshots'
232eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_SCREENSHOT_BASENAME = 'arc-screenshot'
242eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_MAX_SCREENSHOT_NUM = 10
252eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_SDCARD_PID_PATH = '/var/run/arc/sdcard.pid'
262eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_ANDROID_ADB_KEYS_PATH = '/data/misc/adb/adb_keys'
272eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_PROCESS_CHECK_INTERVAL_SECONDS = 1
282eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_WAIT_FOR_ADB_READY = 60
292eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_WAIT_FOR_ANDROID_PROCESS_SECONDS = 60
304ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh_WAIT_FOR_DATA_MOUNTED_SECONDS = 60
312eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh_VAR_LOGCAT_PATH = '/var/log/logcat'
322eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
332eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
342eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef setup_adb_host():
352eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Setup ADB host keys.
362eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
37ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel    This sets up the files and environment variables that wait_for_adb_ready()
38ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel    needs"""
392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if _ADB_VENDOR_KEYS in os.environ:
402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        return
412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if not os.path.exists(_ADB_KEYS_PATH):
422eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        os.mkdir(_ADB_KEYS_PATH)
432eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # adb expects $HOME to be writable.
442eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    os.environ['HOME'] = _ADB_KEYS_PATH
452eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
462eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # Generate and save keys for adb if needed
472eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    key_path = os.path.join(_ADB_KEYS_PATH, 'test_key')
482eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if not os.path.exists(key_path):
492eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        utils.system('adb keygen ' + pipes.quote(key_path))
502eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    os.environ[_ADB_VENDOR_KEYS] = key_path
512eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
522eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
532eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_connect():
542eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Attempt to connect ADB to the Android container.
552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    Returns true if successful. Do not call this function directly. Call
572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    wait_for_adb_ready() instead."""
582eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if not is_android_booted():
592eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        return False
605c2745d57902e68bbfdd4cfb953740faef645944Ricky Zhou    if utils.system('adb connect localhost:22', ignore_status=True) != 0:
615c2745d57902e68bbfdd4cfb953740faef645944Ricky Zhou        return False
622eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return is_adb_connected()
632eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
642eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
652eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef is_adb_connected():
662eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Return true if adb is connected to the container."""
675c2745d57902e68bbfdd4cfb953740faef645944Ricky Zhou    output = utils.system_output('adb get-state', ignore_status=True)
682eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    logging.debug('adb get-state: %s', output)
692eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return output.strip() == 'device'
702eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
712eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
724ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsiehdef is_partial_boot_enabled():
734ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    """Return true if partial boot is enabled.
744ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
754ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    When partial boot is enabled, Android is started at login screen without
764ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    any persistent state (e.g. /data is not mounted).
774ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    """
784ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    return _android_shell('getprop ro.boot.partial_boot') == '1'
794ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
804ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
814ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsiehdef _is_android_data_mounted():
824ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    """Return true if Android's /data is mounted with partial boot enabled."""
834ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    return _android_shell('getprop ro.data_mounted') == '1'
844ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
854ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
864ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsiehdef _wait_for_data_mounted(timeout=_WAIT_FOR_DATA_MOUNTED_SECONDS):
874ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    utils.poll_for_condition(
884ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh            condition=_is_android_data_mounted,
894ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh            desc='Wait for /data mounted',
904ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh            timeout=timeout,
914ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh            sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
924ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
934ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
942eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef wait_for_adb_ready(timeout=_WAIT_FOR_ADB_READY):
95a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Wait for the ADB client to connect to the ARC container.
96a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
97a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param timeout: Timeout in seconds.
98a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
994ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    # When partial boot is enabled, although adbd is started at login screen,
1004ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    # we still need /data to be mounted to set up key-based authentication.
1014ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    # /data should be mounted once the user has logged in.
1024ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh    if is_partial_boot_enabled():
1034ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh        _wait_for_data_mounted()
1044ed69e0c716645ea9217db90bb7a2617d51d5655Victor Hsieh
1052eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    setup_adb_host()
1062eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if is_adb_connected():
1072eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh      return
1082eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1092eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # Push keys for adb.
1102eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    pubkey_path = os.environ[_ADB_VENDOR_KEYS] + '.pub'
1112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    with open(pubkey_path, 'r') as f:
1122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        _write_android_file(_ANDROID_ADB_KEYS_PATH, f.read())
1132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    _android_shell('restorecon ' + pipes.quote(_ANDROID_ADB_KEYS_PATH))
1142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # This starts adbd.
1162eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    _android_shell('setprop sys.usb.config mtp,adb')
1172eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1182eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # Kill existing adb server to ensure that a full reconnect is performed.
1195c2745d57902e68bbfdd4cfb953740faef645944Ricky Zhou    utils.system('adb kill-server', ignore_status=True)
1202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1212eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    exception = error.TestFail('adb is not ready in %d seconds.' % timeout)
1222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    utils.poll_for_condition(adb_connect,
1232eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             exception,
1242eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             timeout)
1252eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1262eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
12721cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiangdef grant_permissions(package, permissions):
12821cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang    """Grants permissions to a package.
12921cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang
13021cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang    @param package: Package name.
13121cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang    @param permissions: A list of permissions.
13221cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang
13321cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang    """
13421cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang    for permission in permissions:
13521cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang        adb_shell('pm grant %s android.permission.%s' % (
13621cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang                  pipes.quote(package), pipes.quote(permission)))
13721cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang
13821cf23a3a5efa367da90602246cdb713584d9749Cheng-Yi Chiang
13957761dd68c881dc2ea2a5a82d7ec6cf8f4a82363Chung-yih Wangdef adb_cmd(cmd, **kwargs):
140a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Executed cmd using adb. Must wait for adb ready.
141a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
142a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param cmd: Command to run.
143a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
1442eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    wait_for_adb_ready()
14557761dd68c881dc2ea2a5a82d7ec6cf8f4a82363Chung-yih Wang    return utils.system_output('adb %s' % cmd, **kwargs)
1462eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1472eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1482eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_shell(cmd, **kwargs):
149a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Executed shell command with adb.
150a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
151a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param cmd: Command to run.
152a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
1532eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    output = adb_cmd('shell %s' % pipes.quote(cmd), **kwargs)
1542eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # Some android commands include a trailing CRLF in their output.
1552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if kwargs.pop('strip_trailing_whitespace', True):
1562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh      output = output.rstrip()
1572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return output
1582eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1592eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1602eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_install(apk):
161a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Install an apk into container. You must connect first.
162a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
163a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param apk: Package to install.
164a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
1652eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return adb_cmd('install -r %s' % apk)
1662eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1672eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1682eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_uninstall(apk):
169a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Remove an apk from container. You must connect first.
170a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
171a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param apk: Package to uninstall.
172a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
1732eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return adb_cmd('uninstall %s' % apk)
1742eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1762eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_reboot():
1772eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Reboots the container. You must connect first."""
1782eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    adb_root()
1792eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return adb_cmd('reboot', ignore_status=True)
1802eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1812eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1822eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef adb_root():
1832eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Restart adbd with root permission."""
1842eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    adb_cmd('root')
1852eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1862eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1872eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_container_root():
1882eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns path to Android container root directory.
1892eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
1902eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    Raises:
1912eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh      TestError if no container root directory is found, or
1922eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh      more than one container root directories are found.
1932eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
19455a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    # Find the PID file rather than the android_XXXXXX/ directory to ignore
19555a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    # stale and empty android_XXXXXX/ directories when they exist.
19655a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    # TODO(yusukes): Investigate why libcontainer sometimes fails to remove
19755a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    # the directory. See b/63376749 for more details.
19855a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    arc_container_pid_files = glob.glob(_ANDROID_CONTAINER_PID_PATH)
19955a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato
20055a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    if len(arc_container_pid_files) == 0:
20155a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato        raise error.TestError('Android container not available')
20255a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato
20355a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    if len(arc_container_pid_files) > 1:
20455a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato        raise error.TestError('Multiple Android containers found: %r. '
20555a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato                              'Reboot your DUT to recover.' % (
20655a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato                                  arc_container_pid_files))
20755a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato
20855a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    return os.path.dirname(arc_container_pid_files[0])
2092eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2102eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_job_pid(job_name):
2122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns the PID of an upstart job."""
2132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    status = utils.system_output('status %s' % job_name)
2142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    match = re.match(r'^%s start/running, process (\d+)$' % job_name,
2152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                     status)
2162eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if not match:
2172eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        raise error.TestError('Unexpected status: "%s"' % status)
2182eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return match.group(1)
2192eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2212eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_container_pid():
2222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns the PID of the container."""
2232eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    container_root = get_container_root()
2242eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    pid_path = os.path.join(container_root, 'container.pid')
2252eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.read_one_line(pid_path)
2262eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2272eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2282eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_sdcard_pid():
2292eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns the PID of the sdcard container."""
2302eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.read_one_line(_SDCARD_PID_PATH)
2312eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2322eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2332eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_removable_media_pid():
2342eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns the PID of the arc-removable-media FUSE daemon."""
2352eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    job_pid = get_job_pid('arc-removable-media')
2362eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # |job_pid| is the minijail process, obtain the PID of the process running
2372eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # inside the mount namespace.
2382eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    # FUSE process is the only process running as chronos in the process group.
2392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.system_output('pgrep -u chronos -g %s' % job_pid)
2402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2422eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef get_obb_mounter_pid():
2432eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Returns the PID of the OBB mounter."""
2442eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.system_output('pgrep -f -u root ^/usr/bin/arc-obb-mounter')
2452eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2462eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2472eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef is_android_booted():
2482eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Return whether Android has completed booting."""
249c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi    # We used to check sys.boot_completed system property to detect Android has
250c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi    # booted in Android M, but in Android N it is set long before BOOT_COMPLETED
251c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi    # intent is broadcast. So we read event logs instead.
252c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi    log = _android_shell(
253c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi        'logcat -d -b events *:S arc_system_event', ignore_status=True)
254c96aea6105f1b6838540659bc8ec9c44c487b6abShuhei Takahashi    return 'ArcAppLauncher:started' in log
2552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef is_android_process_running(process_name):
258a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Return whether Android has completed booting.
259a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
260a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param process_name: Process name.
261a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
262c4127418e8f61c1a0bec85fe3aa09e1379e2a6c7Shuhei Takahashi    output = adb_shell('ps | grep %s' % pipes.quote(' %s$' % process_name))
263c4127418e8f61c1a0bec85fe3aa09e1379e2a6c7Shuhei Takahashi    return bool(output)
2642eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2652eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2661d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.comdef check_android_file_exists(filename):
2671d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    """Checks whether the given file exists in the Android filesystem
2681d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
2691d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    @param filename: File to check.
2701d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    """
2711d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    return adb_shell('test -e {} && echo FileExists'.format(
2721d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com            pipes.quote(filename))).find("FileExists") >= 0
2731d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
2741d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
2752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef read_android_file(filename):
276a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Reads a file in Android filesystem.
277a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
278a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param filename: File to read.
279a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
2802eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    with tempfile.NamedTemporaryFile() as tmpfile:
281ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel        adb_cmd('pull %s %s' % (pipes.quote(filename),
282ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                                pipes.quote(tmpfile.name)))
2832eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        with open(tmpfile.name) as f:
2842eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            return f.read()
2852eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2862eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return None
2872eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2882eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
2892eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef write_android_file(filename, data):
290a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Writes to a file in Android filesystem.
291a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
292a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param filename: File to write.
293a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param data: Data to write.
294a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
2952eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    with tempfile.NamedTemporaryFile() as tmpfile:
2962eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        tmpfile.write(data)
2972eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        tmpfile.flush()
2982eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
299ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel        adb_cmd('push %s %s' % (pipes.quote(tmpfile.name),
300ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                                pipes.quote(filename)))
3012eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3022eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3032eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef _write_android_file(filename, data):
3042eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Writes to a file in Android filesystem.
3052eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3062eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    This is an internal function used to bootstrap adb.
3072eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    Tests should use write_android_file instead.
3082eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
3092eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    android_cmd = 'cat > %s' % pipes.quote(filename)
3102eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    cros_cmd = 'android-sh -c %s' % pipes.quote(android_cmd)
3112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    utils.run(cros_cmd, stdin=data)
3122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef remove_android_file(filename):
315a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Removes a file in Android filesystem.
316a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
317a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param filename: File to remove.
318a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
3192eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    adb_shell('rm -f %s' % pipes.quote(filename))
3202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3212eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef wait_for_android_boot(timeout=None):
323a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Sleep until Android has completed booting or timeout occurs.
324a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
325a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param timeout: Timeout in seconds.
326a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
3272eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    arc_common.wait_for_android_boot(timeout)
3282eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3292eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3302eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef wait_for_android_process(process_name,
3312eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             timeout=_WAIT_FOR_ANDROID_PROCESS_SECONDS):
332a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Sleep until an Android process is running or timeout occurs.
333a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
334a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param process_name: Process name.
335a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param timeout: Timeout in seconds.
336a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
3372eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    condition = lambda: is_android_process_running(process_name)
3382eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    utils.poll_for_condition(condition=condition,
3392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             desc='%s is running' % process_name,
3402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             timeout=timeout,
3412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                             sleep_interval=_PROCESS_CHECK_INTERVAL_SECONDS)
3422eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3432eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3442eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef _android_shell(cmd, **kwargs):
3452eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Execute cmd instead the Android container.
3462eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3472eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    This function is strictly for internal use only, as commands do not run in a
3482eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    fully consistent Android environment. Prefer adb_shell instead.
3492eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
3502eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.system_output('android-sh -c {}'.format(pipes.quote(cmd)),
3512eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                               **kwargs)
3522eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3532eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3542eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef is_android_container_alive():
3552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Check if android container is alive."""
3562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    try:
3572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        container_pid = get_container_pid()
35855a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato    except Exception, e:
35955a8100078f89aa2f9b74e2808b402398c29547eYusuke Sato        logging.error('is_android_container_alive failed: %r', e)
3602eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        return False
3612eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return utils.pid_is_alive(int(container_pid))
3622eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3632eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3642eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef is_package_installed(package):
365a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """Check if a package is installed. adb must be ready.
366a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
367a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    @param package: Package in request.
368a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    """
3692eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    packages = adb_shell('pm list packages').splitlines()
3702eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    package_entry = 'package:{}'.format(package)
3712eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    return package_entry in packages
3722eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3732eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3742eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef _before_iteration_hook(obj):
3752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Executed by parent class before every iteration.
3762eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3772eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    This function resets the run_once_finished flag before every iteration
3782eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    so we can detect failure on every single iteration.
3792eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3802eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    Args:
3812eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        obj: the test itself
3822eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
3832eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    obj.run_once_finished = False
3842eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3852eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3862eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehdef _after_iteration_hook(obj):
3872eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """Executed by parent class after every iteration.
3882eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3892eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    The parent class will handle exceptions and failures in the run and will
3902eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    always call this hook afterwards. Take a screenshot if the run has not
3912eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    been marked as finished (i.e. there was a failure/exception).
3922eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
3932eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    Args:
3942eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        obj: the test itself
3952eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
3962eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    if not obj.run_once_finished:
3972eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if not os.path.exists(_SCREENSHOT_DIR_PATH):
3982eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            os.mkdir(_SCREENSHOT_DIR_PATH, 0755)
3992eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        obj.num_screenshots += 1
4002eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if obj.num_screenshots <= _MAX_SCREENSHOT_NUM:
4012eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            logging.warning('Iteration %d failed, taking a screenshot.',
4022eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                            obj.iteration)
403557946d18d625f8c14e0a1bf6a23d91b17d70f1dJoe Kniss            from cros.graphics.gbm import crtcScreenshot
404ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel            try:
405ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                image = crtcScreenshot()
406ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                image.save('{}/{}_iter{}.png'.format(_SCREENSHOT_DIR_PATH,
407ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                                                     _SCREENSHOT_BASENAME,
408ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                                                     obj.iteration))
409ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel            except Exception:
410ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                e = sys.exc_info()[0]
411ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                logging.warning('Unable to capture screenshot. %s' % e)
4122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        else:
4132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            logging.warning('Too many failures, no screenshot taken')
4142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4161d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.comdef send_keycode(keycode):
4171d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    """Sends the given keycode to the container
4181d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
4191d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    @param keycode: keycode to send.
4201d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    """
4211d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com    adb_shell('input keyevent {}'.format(keycode))
4221d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
4231d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com
4248f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashidef get_android_sdk_version():
4258f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    """Returns the Android SDK version.
4268f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi
4278f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    This function can be called before Android container boots.
4288f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    """
4298f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    with open('/etc/lsb-release') as f:
4308f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi        values = dict(line.split('=', 1) for line in f.read().splitlines())
4318f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    try:
4328f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi        return int(values['CHROMEOS_ARC_ANDROID_SDK_VERSION'])
4338f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi    except (KeyError, ValueError):
4348f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi        raise error.TestError('Could not determine Android SDK version')
4358f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi
4368f8524dd50b26463435d0431c2913ab00f111575Shuhei Takahashi
4372eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsiehclass ArcTest(test.test):
4382eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """ Base class of ARC Test.
4392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    This class could be used as super class of an ARC test for saving
4412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    redundant codes for container bringup, autotest-dep package(s) including
4422eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    uiautomator setup if required, and apks install/remove during
443a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    arc_setup/arc_teardown, respectively. By default arc_setup() is called in
444a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    initialize() after Android have been brought up. It could also be overridden
445a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    to perform non-default tasks. For example, a simple ArcHelloWorldTest can be
446a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    just implemented with print 'HelloWorld' in its run_once() and no other
447a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    functions are required. We could expect ArcHelloWorldTest would bring up
448a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    browser and  wait for container up, then print 'Hello World', and shutdown
449a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    browser after. As a precaution, if you overwrite initialize(), arc_setup(),
450a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    or cleanup() function(s) in ARC test, remember to call the corresponding
451a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee    function(s) in this base class as well.
4522eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4532eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    """
4542eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    version = 1
4552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    _PKG_UIAUTOMATOR = 'uiautomator'
4562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    _FULL_PKG_NAME_UIAUTOMATOR = 'com.github.uiautomator'
4572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4582eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def __init__(self, *args, **kwargs):
4592eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """Initialize flag setting."""
4602eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        super(ArcTest, self).__init__(*args, **kwargs)
4612eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.initialized = False
4622eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # Set the flag run_once_finished to detect if a test is executed
4632eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # successfully without any exception thrown. Otherwise, generate
4642eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # a screenshot in /var/log for debugging.
4652eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.run_once_finished = False
4662eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.logcat_proc = None
467a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.dep_package = None
468a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.apks = None
469a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.full_pkg_names = []
470a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.uiautomator = False
471a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.email_id = None
472a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.password = None
4731d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com        self._chrome = None
4742eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if os.path.exists(_SCREENSHOT_DIR_PATH):
4752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            shutil.rmtree(_SCREENSHOT_DIR_PATH)
4762eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.register_before_iteration_hook(_before_iteration_hook)
4772eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.register_after_iteration_hook(_after_iteration_hook)
4782eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # Keep track of the number of debug screenshots taken and keep the
4792eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # total number sane to avoid issues.
4802eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.num_screenshots = 0
4812eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
4822eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def initialize(self, extension_path=None,
4832eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                   arc_mode=arc_common.ARC_MODE_ENABLED, **chrome_kargs):
4842eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """Log in to a test account."""
4852eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        extension_paths = [extension_path] if extension_path else []
4862eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self._chrome = chrome.Chrome(extension_paths=extension_paths,
4872eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                                     arc_mode=arc_mode,
4882eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                                     **chrome_kargs)
4892eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if extension_path:
4902eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self._extension = self._chrome.get_extension(extension_path)
4912eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        else:
4922eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self._extension = None
4932eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # With ARC enabled, Chrome will wait until container to boot up
4942eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # before returning here, see chrome.py.
4952eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.initialized = True
4962eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        try:
4972eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            if is_android_container_alive():
4982eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                self.arc_setup()
4992eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            else:
5002eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                logging.error('Container is alive?')
5012eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        except Exception as err:
5022eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self.cleanup()
5032eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            raise error.TestFail(err)
5042eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5052eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def after_run_once(self):
5062eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """Executed after run_once() only if there were no errors.
5072eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5082eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        This function marks the run as finished with a flag. If there was a
5092eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        failure the flag won't be set and the failure can then be detected by
5102eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        testing the run_once_finished flag.
5112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """
5122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        logging.info('After run_once')
5132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.run_once_finished = True
5142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def cleanup(self):
5162eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """Log out of Chrome."""
5172eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if not self.initialized:
5182eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            logging.info('Skipping ARC cleanup: not initialized')
5192eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            return
5202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        logging.info('Starting ARC cleanup')
5212eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        try:
5222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            if is_android_container_alive():
5232eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                self.arc_teardown()
5242eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        except Exception as err:
5252eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            raise error.TestFail(err)
5262eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        finally:
5272eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            try:
5282eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                self._stop_logcat()
5292eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            finally:
5301d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com                if self._chrome is not None:
5311d6f3b4433872f6c1330f6e6a67fc482c005c0fbChen-Hao Chang@google.com                    self._chrome.close()
5322eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
533ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel    def arc_setup(self, dep_package=None, apks=None, full_pkg_names=None,
534a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang                  uiautomator=False, email_id=None, password=None,
535a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang                  block_outbound=False):
536a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        """ARC test setup: Setup dependencies and install apks.
5372eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5382eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        This function disables package verification and enables non-market
5392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        APK installation. Then, it installs specified APK(s) and uiautomator
5402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        package and path if required in a test.
5412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
542a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param dep_package: Package name of autotest_deps APK package.
543a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param apks: Array of APK names to be installed in dep_package.
544a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param full_pkg_names: Array of full package names to be removed
545a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                               in teardown.
546a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param uiautomator: uiautomator python package is required or not.
547a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
548a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param email_id: email id to be attached to the android. Only used
549a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                         when  account_util is set to true.
550a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        @param password: password related to the email_id.
551a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang        @param block_outbound: block outbound network traffic during a test.
5522eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """
553a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        if not self.initialized:
554a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            logging.info('Skipping ARC setup: not initialized')
555a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            return
556a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        logging.info('Starting ARC setup')
557a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.dep_package = dep_package
558a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.apks = apks
559a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.uiautomator = uiautomator
560a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.email_id = email_id
561a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        self.password = password
562a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        # Setup dependent packages if required
563a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        packages = []
564a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        if dep_package:
565a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            packages.append(dep_package)
566a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        if self.uiautomator:
567a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            packages.append(self._PKG_UIAUTOMATOR)
568a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee        if packages:
569a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            logging.info('Setting up dependent package(s) %s', packages)
570a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            self.job.setup_dep(packages)
571a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee
5722eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # TODO(b/29341443): Run logcat on non ArcTest test cases too.
5732eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        with open(_VAR_LOGCAT_PATH, 'w') as f:
5742eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self.logcat_proc = subprocess.Popen(
5752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                ['android-sh', '-c', 'logcat -v threadtime'],
5762eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                stdout=f,
5772eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                stderr=subprocess.STDOUT,
5782eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                close_fds=True)
5792eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5802eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        wait_for_adb_ready()
5812eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5822eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # package_verifier_user_consent == -1 means to reject Google's
5832eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # verification on the server side through Play Store.  This suppress a
5842eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # consent dialog from the system.
5852eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put secure package_verifier_user_consent -1')
5862eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put global package_verifier_enable 0')
5872eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put secure install_non_market_apps 1')
5882eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
5892eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if self.dep_package:
5902eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            apk_path = os.path.join(self.autodir, 'deps', self.dep_package)
5912eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            if self.apks:
5922eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                for apk in self.apks:
593a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                    logging.info('Installing %s', apk)
5942eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                    adb_install('%s/%s' % (apk_path, apk))
5952eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                # Verify if package(s) are installed correctly
596a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                if not full_pkg_names:
5972eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                    raise error.TestError('Package names of apks expected')
598a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                for pkg in full_pkg_names:
599a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                    logging.info('Check if %s is installed', pkg)
6002eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                    if not is_package_installed(pkg):
6012eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                        raise error.TestError('Package %s not found' % pkg)
602a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                    # Make sure full_pkg_names contains installed packages only
603a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                    # so arc_teardown() knows what packages to uninstall.
604a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                    self.full_pkg_names.append(pkg)
6052eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6062eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if self.uiautomator:
6072eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            path = os.path.join(self.autodir, 'deps', self._PKG_UIAUTOMATOR)
6082eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            sys.path.append(path)
609a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang        if block_outbound:
610a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang            self.block_outbound()
6112eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6122eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def _stop_logcat(self):
6132eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """Stop the adb logcat process gracefully."""
6142eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if not self.logcat_proc:
6152eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            return
6162eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # Running `adb kill-server` should have killed `adb logcat`
6172eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        # process, but just in case also send termination signal.
6182eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        self.logcat_proc.terminate()
6192eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6202eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        class TimeoutException(Exception):
6212eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            """Termination timeout timed out."""
6222eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6232eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        try:
6242eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            utils.poll_for_condition(
6252eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                condition=lambda: self.logcat_proc.poll() is not None,
6262eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                exception=TimeoutException,
6272eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                timeout=10,
6282eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                sleep_interval=0.1,
6292eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                desc='Waiting for adb logcat to terminate')
6302eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        except TimeoutException:
6312eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            logging.info('Killing adb logcat due to timeout')
6322eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self.logcat_proc.kill()
6332eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            self.logcat_proc.wait()
6342eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6352eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def arc_teardown(self):
6362eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """ARC test teardown.
6372eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6382eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        This function removes all installed packages in arc_setup stage
6392eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        first. Then, it restores package verification and disables non-market
6402eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        APK installation.
6412eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6422eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """
6432eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if self.full_pkg_names:
6442eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            for pkg in self.full_pkg_names:
645a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee                logging.info('Uninstalling %s', pkg)
6462eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                if not is_package_installed(pkg):
6472eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                    raise error.TestError('Package %s was not installed' % pkg)
6482eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh                adb_uninstall(pkg)
6492eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        if self.uiautomator:
650a854fbf43f5273f9c1e9700c05d8173e9ca4177dCheng-Yu Lee            logging.info('Uninstalling %s', self._FULL_PKG_NAME_UIAUTOMATOR)
6512eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            adb_uninstall(self._FULL_PKG_NAME_UIAUTOMATOR)
6522eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put secure install_non_market_apps 0')
6532eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put global package_verifier_enable 1')
6542eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        adb_shell('settings put secure package_verifier_user_consent 0')
6552eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6562eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        remove_android_file(_ANDROID_ADB_KEYS_PATH)
6572eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        utils.system_output('adb kill-server')
6582eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6592eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def block_outbound(self):
6602eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """ Blocks the connection from the container to outer network.
6612eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
662b3b206f919b133ce2031ee6c00d44063a9ede7a3Abhishek Bhardwaj            The iptables settings accept only 100.115.92.2 port 5555 (adb) and
663a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang            all local connections, e.g. uiautomator.
6642eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """
6652eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        logging.info('Blocking outbound connection')
6662eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        _android_shell('iptables -I OUTPUT -j REJECT')
667ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel        _android_shell('iptables -I OUTPUT -p tcp -s 100.115.92.2 --sport 5555 '
668ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                       '-j ACCEPT')
669a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang        _android_shell('iptables -I OUTPUT -p tcp -d localhost -j ACCEPT')
6702eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6712eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh    def unblock_outbound(self):
6722eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """ Unblocks the connection from the container to outer network.
6732eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh
6742eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            The iptables settings are not permanent which means they reset on
6752eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            each instance invocation. But we can still use this function to
6762eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh            unblock the outbound connections during the test if needed.
6772eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        """
6782eba892985ce86df60b4a1a04f84a9683eec6349Victor Hsieh        logging.info('Unblocking outbound connection')
679a67fce0314539fb284fea8c99c5475351cc122adChung-yih Wang        _android_shell('iptables -D OUTPUT -p tcp -d localhost -j ACCEPT')
680ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel        _android_shell('iptables -D OUTPUT -p tcp -s 100.115.92.2 --sport 5555 '
681ce8ebd68a9dfbc41cead33e9dc594a2b40f0c6d0Ilja H. Friedel                       '-j ACCEPT')
682c58c7ab39145fc526b2b580ad6626e9096ae7344Chung-yih Wang        _android_shell('iptables -D OUTPUT -j REJECT')
683