• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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