1 # Copyright 2013 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.
5 """Brings in Chrome Android's android_commands module, which itself is a
6 thin(ish) wrapper around adb."""
13 from telemetry.core import platform
14 from telemetry.core import util
15 from telemetry.util import support_binaries
17 # This is currently a thin wrapper around Chrome Android's
18 # build scripts, located in chrome/build/android. This file exists mainly to
19 # deal with locating the module.
21 util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android')
22 from pylib import android_commands # pylint: disable=F0401
23 from pylib import constants # pylint: disable=F0401
25 from pylib import ports # pylint: disable=F0401
28 from pylib.device import device_utils # pylint: disable=F0401
31 def IsAndroidSupported():
32 return device_utils != None
35 def GetAttachedDevices():
36 """Returns a list of attached, online android devices.
38 If a preferred device has been set with ANDROID_SERIAL, it will be first in
40 return android_commands.GetAttachedDevices()
43 def AllocateTestServerPort():
44 return ports.AllocateTestServerPort()
47 def ResetTestServerPortAllocation():
48 return ports.ResetTestServerPortAllocation()
51 class AdbCommands(object):
52 """A thin wrapper around ADB"""
54 def __init__(self, device):
55 self._device = device_utils.DeviceUtils(device)
56 self._device_serial = device
58 def device_serial(self):
59 return self._device_serial
64 def __getattr__(self, name):
65 """Delegate all unknown calls to the underlying AndroidCommands object."""
66 return getattr(self._device.old_interface, name)
68 def Forward(self, local, remote):
69 ret = self._device.old_interface.Adb().SendCommand(
70 'forward %s %s' % (local, remote))
73 def Install(self, apk_path):
74 """Installs specified package if necessary.
77 apk_path: Path to .apk file to install.
80 if (os.path.exists(os.path.join(
81 constants.GetOutDirectory('Release'), 'md5sum_bin_host'))):
82 constants.SetBuildType('Release')
83 elif (os.path.exists(os.path.join(
84 constants.GetOutDirectory('Debug'), 'md5sum_bin_host'))):
85 constants.SetBuildType('Debug')
87 self._device.Install(apk_path)
89 def IsUserBuild(self):
90 return self._device.GetProp('ro.build.type') == 'user'
93 def GetBuildTypeOfPath(path):
96 for build_dir, build_type in util.GetBuildDirectories():
97 if os.path.join(build_dir, build_type) in path:
102 def SetupPrebuiltTools(adb):
103 """Some of the android pylib scripts we depend on are lame and expect
104 binaries to be in the out/ directory. So we copy any prebuilt binaries there
107 # TODO(bulach): Build the targets for x86/mips.
110 'forwarder_dist/device_forwarder',
111 'md5sum_dist/md5sum_bin',
121 if platform.GetHostPlatform().GetOSName() == 'linux':
122 host_tools.append('host_forwarder')
124 has_device_prebuilt = adb.device().GetProp('ro.product.cpu.abi').startswith(
126 if not has_device_prebuilt:
127 return all([support_binaries.FindLocallyBuiltPath(t) for t in device_tools])
130 for t in device_tools + host_tools:
131 executable = os.path.basename(t)
132 locally_built_path = support_binaries.FindLocallyBuiltPath(t)
134 build_type = GetBuildTypeOfPath(locally_built_path) or 'Release'
135 constants.SetBuildType(build_type)
136 dest = os.path.join(constants.GetOutDirectory(), t)
137 if not locally_built_path:
138 logging.info('Setting up prebuilt %s', dest)
139 if not os.path.exists(os.path.dirname(dest)):
140 os.makedirs(os.path.dirname(dest))
141 platform_name = ('android' if t in device_tools else
142 platform.GetHostPlatform().GetOSName())
143 prebuilt_path = support_binaries.FindPath(executable, platform_name)
144 if not prebuilt_path or not os.path.exists(prebuilt_path):
145 raise NotImplementedError("""
146 %s must be checked into cloud storage.
148 http://www.chromium.org/developers/telemetry/upload_to_cloud_storage
150 shutil.copyfile(prebuilt_path, dest)
151 os.chmod(dest, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)