1# Copyright 2016 The Chromium 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"""Utility functions for interacting with devices supporting adb commands. The
6functions only work with an Autotest instance setup, e.g., in a lab.
7
8The functions here calls methods in afe_utils to get host attributes and other
9information through AFE RPC. Therefore, they are not included in adb_host.py.
10For methods does not rely on AFE RPC, they should be included in ADBHost class.
11"""
12
13
14import os
15import logging
16
17import common
18from autotest_lib.client.common_lib import error
19from autotest_lib.client.common_lib.cros import dev_server
20from autotest_lib.server import afe_utils
21
22
23def install_apk_from_build(host, apk, build_artifact, package_name=None,
24                           force_reinstall=False, build_name=None):
25    """Install the specific apk from given build artifact.
26
27    @param host: An ADBHost object to install apk.
28    @param apk: Name of the apk to install, e.g., sl4a.apk
29    @param build_artifact: Name of the build artifact, e.g., test_zip. Note
30            that it's not the name of the artifact file. Refer to
31            artifact_info.py in devserver code for the mapping between
32            artifact name to a build artifact.
33    @param package_name: Name of the package, e.g., com.android.phone.
34            If package_name is given, it checks if the package exists before
35            trying to install it, unless force_reinstall is set to True.
36    @param force_reinstall: True to reinstall the apk even if it's already
37            installed. Default is set to False.
38    @param build_name: None unless DUT is CrOS with ARC++ container. build_name
39            points to ARC++ build artifacts.
40    """
41    # Check if apk is already installed.
42    if package_name and not force_reinstall:
43        if host.is_apk_installed(package_name):
44            logging.info('Package %s is already installed.', package_name)
45            return
46    if build_name:
47        # Pull devserver_url given ARC++ enabled host
48        host_devserver_url = dev_server.AndroidBuildServer.resolve(build_name,
49                host.hostname).url()
50        # Return devserver_url given Android build path
51        job_repo_url = os.path.join(host_devserver_url, build_name)
52    else:
53        job_repo_url = afe_utils.get_host_attribute(
54                host, host.job_repo_url_attribute)
55    if not job_repo_url:
56        raise error.AutoservError(
57                'The host %s has no attribute %s. `install_apk_from_build` '
58                'only works for test with image specified.' %
59                (host.hostname, host.job_repo_url_attribute))
60    devserver_url = dev_server.AndroidBuildServer.get_server_url(job_repo_url)
61    devserver = dev_server.AndroidBuildServer(devserver_url)
62    build_info = host.get_build_info_from_build_url(job_repo_url)
63    devserver.trigger_download(build_info['target'], build_info['build_id'],
64                               build_info['branch'], build_artifact,
65                               synchronous=True)
66    build_info['os_type'] = 'android'
67    apk_url = devserver.locate_file(apk, build_artifact, None, build_info)
68    logging.debug('Found apk at: %s', apk_url)
69
70    tmp_dir = host.teststation.get_tmp_dir()
71    try:
72        host.download_file(apk_url, apk, tmp_dir)
73        result = host.install_apk(os.path.join(tmp_dir, apk),
74                                  force_reinstall=force_reinstall)
75        logging.debug(result.stdout)
76        if package_name and not host.is_apk_installed(package_name):
77            raise error.AutoservError('No package found with name of %s',
78                                      package_name)
79        logging.info('%s is installed successfully.', apk)
80    finally:
81        host.teststation.run('rm -rf %s' % tmp_dir)
82