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. 4 5"""Brings in Chrome Android's android_commands module, which itself is a 6thin(ish) wrapper around adb.""" 7 8import logging 9import os 10import shutil 11import stat 12 13from telemetry.core import platform 14from telemetry.core import util 15from telemetry.util import support_binaries 16 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. 20 21util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android') 22from pylib import android_commands # pylint: disable=F0401 23from pylib import constants # pylint: disable=F0401 24try: 25 from pylib import ports # pylint: disable=F0401 26except Exception: 27 ports = None 28from pylib.device import device_utils # pylint: disable=F0401 29 30 31def IsAndroidSupported(): 32 return device_utils != None 33 34 35def GetAttachedDevices(): 36 """Returns a list of attached, online android devices. 37 38 If a preferred device has been set with ANDROID_SERIAL, it will be first in 39 the returned list.""" 40 return android_commands.GetAttachedDevices() 41 42 43def AllocateTestServerPort(): 44 return ports.AllocateTestServerPort() 45 46 47def ResetTestServerPortAllocation(): 48 return ports.ResetTestServerPortAllocation() 49 50 51class AdbCommands(object): 52 """A thin wrapper around ADB""" 53 54 def __init__(self, device): 55 self._device = device_utils.DeviceUtils(device) 56 self._device_serial = device 57 58 def device_serial(self): 59 return self._device_serial 60 61 def device(self): 62 return self._device 63 64 def __getattr__(self, name): 65 """Delegate all unknown calls to the underlying AndroidCommands object.""" 66 return getattr(self._device.old_interface, name) 67 68 def Forward(self, local, remote): 69 ret = self._device.old_interface.Adb().SendCommand( 70 'forward %s %s' % (local, remote)) 71 assert ret == '' 72 73 def Install(self, apk_path): 74 """Installs specified package if necessary. 75 76 Args: 77 apk_path: Path to .apk file to install. 78 """ 79 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') 86 87 self._device.Install(apk_path) 88 89 def IsUserBuild(self): 90 return self._device.old_interface.GetBuildType() == 'user' 91 92 93def GetBuildTypeOfPath(path): 94 if not path: 95 return None 96 for build_dir, build_type in util.GetBuildDirectories(): 97 if os.path.join(build_dir, build_type) in path: 98 return build_type 99 return None 100 101 102def 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 105 as a prereq.""" 106 107 # TODO(bulach): Build the targets for x86/mips. 108 device_tools = [ 109 'file_poller', 110 'forwarder_dist/device_forwarder', 111 'md5sum_dist/md5sum_bin', 112 'purge_ashmem', 113 'run_pie', 114 ] 115 116 host_tools = [ 117 'bitmaptools', 118 'md5sum_bin_host', 119 ] 120 121 if platform.GetHostPlatform().GetOSName() == 'linux': 122 host_tools.append('host_forwarder') 123 124 has_device_prebuilt = adb.system_properties['ro.product.cpu.abi'].startswith( 125 'armeabi') 126 if not has_device_prebuilt: 127 return all([support_binaries.FindLocallyBuiltPath(t) for t in device_tools]) 128 129 build_type = None 130 for t in device_tools + host_tools: 131 executable = os.path.basename(t) 132 locally_built_path = support_binaries.FindLocallyBuiltPath(t) 133 if not build_type: 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. 147Instructions: 148http://www.chromium.org/developers/telemetry/upload_to_cloud_storage 149""" % t) 150 shutil.copyfile(prebuilt_path, dest) 151 os.chmod(dest, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) 152 return True 153