Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / backends / adb_commands.py
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
6 thin(ish) wrapper around adb."""
7
8 import logging
9 import os
10 import shutil
11 import stat
12 import sys
13
14 from telemetry.core import util
15 from telemetry.core.platform.profiler import android_prebuilt_profiler_helper
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
21 util.AddDirToPythonPath(util.GetChromiumSrcDir(), 'build', 'android')
22 try:
23   from pylib import android_commands  # pylint: disable=F0401
24   from pylib import constants  # pylint: disable=F0401
25   from pylib import ports  # pylint: disable=F0401
26   from pylib.utils import apk_helper  # pylint: disable=F0401
27   from pylib.utils import test_environment  # pylint: disable=F0401
28 except Exception:
29   android_commands = None
30
31
32 def IsAndroidSupported():
33   return android_commands != None
34
35
36 def GetAttachedDevices():
37   """Returns a list of attached, online android devices.
38
39   If a preferred device has been set with ANDROID_SERIAL, it will be first in
40   the returned list."""
41   return android_commands.GetAttachedDevices()
42
43
44 def CleanupLeftoverProcesses():
45   test_environment.CleanupLeftoverProcesses()
46
47
48 def AllocateTestServerPort():
49   return ports.AllocateTestServerPort()
50
51
52 def ResetTestServerPortAllocation():
53   return ports.ResetTestServerPortAllocation()
54
55
56 class AdbCommands(object):
57   """A thin wrapper around ADB"""
58
59   def __init__(self, device):
60     self._adb = android_commands.AndroidCommands(device, api_strict_mode=True)
61     self._device = device
62
63   def device(self):
64     return self._device
65
66   @property
67   def system_properties(self):
68     return self._adb.system_properties
69
70   def Adb(self):
71     return self._adb
72
73   def Forward(self, local, remote):
74     ret = self._adb.Adb().SendCommand('forward %s %s' % (local, remote))
75     assert ret == ''
76
77   def RunShellCommand(self, command, timeout_time=20, log_result=False):
78     """Send a command to the adb shell and return the result.
79
80     Args:
81       command: String containing the shell command to send. Must not include
82                the single quotes as we use them to escape the whole command.
83       timeout_time: Number of seconds to wait for command to respond before
84         retrying, used by AdbInterface.SendShellCommand.
85       log_result: Boolean to indicate whether we should log the result of the
86                   shell command.
87
88     Returns:
89       list containing the lines of output received from running the command
90     """
91     return self._adb.RunShellCommand(command, timeout_time, log_result)
92
93   def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
94     return self._adb.RunShellCommandWithSU(command, timeout_time, log_result)
95
96   def CloseApplication(self, package):
97     """Attempt to close down the application, using increasing violence.
98
99     Args:
100       package: Name of the process to kill off, e.g.
101       com.google.android.apps.chrome
102     """
103     self._adb.CloseApplication(package)
104
105   def KillAll(self, process):
106     """Android version of killall, connected via adb.
107
108     Args:
109       process: name of the process to kill off
110
111     Returns:
112       the number of processess killed
113     """
114     return self._adb.KillAll(process)
115
116   def ExtractPid(self, process_name):
117     """Extracts Process Ids for a given process name from Android Shell.
118
119     Args:
120       process_name: name of the process on the device.
121
122     Returns:
123       List of all the process ids (as strings) that match the given name.
124       If the name of a process exactly matches the given name, the pid of
125       that process will be inserted to the front of the pid list.
126     """
127     return self._adb.ExtractPid(process_name)
128
129   def Install(self, apk_path):
130     """Installs specified package if necessary.
131
132     Args:
133       apk_path: Path to .apk file to install.
134     """
135
136     if (os.path.exists(os.path.join(
137         constants.GetOutDirectory('Release'), 'md5sum_bin_host'))):
138       constants.SetBuildType('Release')
139     elif (os.path.exists(os.path.join(
140         constants.GetOutDirectory('Debug'), 'md5sum_bin_host'))):
141       constants.SetBuildType('Debug')
142
143     apk_package_name = apk_helper.GetPackageName(apk_path)
144     return self._adb.ManagedInstall(apk_path, package_name=apk_package_name)
145
146   def StartActivity(self, package, activity, wait_for_completion=False,
147                     action='android.intent.action.VIEW',
148                     category=None, data=None,
149                     extras=None, trace_file_name=None,
150                     flags=None):
151     """Starts |package|'s activity on the device.
152
153     Args:
154       package: Name of package to start (e.g. 'com.google.android.apps.chrome').
155       activity: Name of activity (e.g. '.Main' or
156         'com.google.android.apps.chrome.Main').
157       wait_for_completion: wait for the activity to finish launching (-W flag).
158       action: string (e.g. 'android.intent.action.MAIN'). Default is VIEW.
159       category: string (e.g. 'android.intent.category.HOME')
160       data: Data string to pass to activity (e.g. 'http://www.example.com/').
161       extras: Dict of extras to pass to activity. Values are significant.
162       trace_file_name: If used, turns on and saves the trace to this file name.
163     """
164     return self._adb.StartActivity(package, activity, wait_for_completion,
165                     action,
166                     category, data,
167                     extras, trace_file_name,
168                     flags)
169
170   def Push(self, local, remote):
171     return self._adb.Adb().Push(local, remote)
172
173   def Pull(self, remote, local):
174     return self._adb.Adb().Pull(remote, local)
175
176   def FileExistsOnDevice(self, file_name):
177     return self._adb.FileExistsOnDevice(file_name)
178
179   def IsRootEnabled(self):
180     return self._adb.IsRootEnabled()
181
182   def GoHome(self):
183     return self._adb.GoHome()
184
185   def RestartAdbdOnDevice(self):
186     return self._adb.RestartAdbdOnDevice()
187
188   def IsUserBuild(self):
189     return self._adb.GetBuildType() == 'user'
190
191
192 def GetBuildTypeOfPath(path):
193   if not path:
194     return None
195   for build_dir, build_type in util.GetBuildDirectories():
196     if os.path.join(build_dir, build_type) in path:
197       return build_type
198   return None
199
200
201 def SetupPrebuiltTools(adb):
202   # TODO(bulach): build the host tools for mac, and the targets for x86/mips.
203   # Prebuilt tools from r226197.
204   has_prebuilt = sys.platform.startswith('linux')
205   if has_prebuilt:
206     abi = adb.system_properties['ro.product.cpu.abi']
207     has_prebuilt = abi.startswith('armeabi')
208   if not has_prebuilt:
209     logging.error(
210         'Prebuilt android tools only available for Linux host and ARM device.')
211     return False
212
213   prebuilt_tools = [
214       'bitmaptools',
215       'file_poller',
216       'forwarder_dist/device_forwarder',
217       'host_forwarder',
218       'md5sum_dist/md5sum_bin',
219       'md5sum_bin_host',
220       'purge_ashmem',
221   ]
222   build_type = None
223   for t in prebuilt_tools:
224     src = os.path.basename(t)
225     android_prebuilt_profiler_helper.GetIfChanged(src)
226     bin_path = util.FindSupportBinary(t)
227     if not build_type:
228       build_type = GetBuildTypeOfPath(bin_path) or 'Release'
229       constants.SetBuildType(build_type)
230     dest = os.path.join(constants.GetOutDirectory(), t)
231     if not bin_path:
232       logging.warning('Setting up prebuilt %s', dest)
233       if not os.path.exists(os.path.dirname(dest)):
234         os.makedirs(os.path.dirname(dest))
235       prebuilt_path = android_prebuilt_profiler_helper.GetHostPath(src)
236       if not os.path.exists(prebuilt_path):
237         raise NotImplementedError("""
238 %s must be checked into cloud storage.
239 Instructions:
240 http://www.chromium.org/developers/telemetry/upload_to_cloud_storage
241 """ % t)
242       shutil.copyfile(prebuilt_path, dest)
243       os.chmod(dest, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
244   return True