Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1260)

Side by Side Diff: build/android/pylib/android_commands.py

Issue 287513002: [Android] Build android tools as PIE and add a wrapper for ICS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/android/provision_devices.py ('k') | build/android/pylib/forwarder.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Provides an interface to communicate with the device via the adb command. 5 """Provides an interface to communicate with the device via the adb command.
6 6
7 Assumes adb binary is currently on system path. 7 Assumes adb binary is currently on system path.
8 """ 8 """
9 # pylint: disable-all 9 # pylint: disable-all
10 10
11 import collections 11 import collections
12 import datetime 12 import datetime
13 import inspect 13 import inspect
14 import json
15 import logging 14 import logging
16 import os 15 import os
17 import re 16 import re
18 import shlex 17 import shlex
19 import signal 18 import signal
20 import subprocess 19 import subprocess
21 import sys 20 import sys
22 import tempfile 21 import tempfile
23 import time 22 import time
24 23
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 KEYCODE_HOME = 3 58 KEYCODE_HOME = 3
60 KEYCODE_BACK = 4 59 KEYCODE_BACK = 4
61 KEYCODE_DPAD_UP = 19 60 KEYCODE_DPAD_UP = 19
62 KEYCODE_DPAD_DOWN = 20 61 KEYCODE_DPAD_DOWN = 20
63 KEYCODE_DPAD_RIGHT = 22 62 KEYCODE_DPAD_RIGHT = 22
64 KEYCODE_ENTER = 66 63 KEYCODE_ENTER = 66
65 KEYCODE_MENU = 82 64 KEYCODE_MENU = 82
66 65
67 MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/' 66 MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/'
68 MD5SUM_DEVICE_PATH = MD5SUM_DEVICE_FOLDER + 'md5sum_bin' 67 MD5SUM_DEVICE_PATH = MD5SUM_DEVICE_FOLDER + 'md5sum_bin'
69 MD5SUM_LD_LIBRARY_PATH = 'LD_LIBRARY_PATH=%s' % MD5SUM_DEVICE_FOLDER 68
69 PIE_WRAPPER_PATH = constants.TEST_EXECUTABLE_DIR + '/run_pie'
70 70
71 CONTROL_USB_CHARGING_COMMANDS = [ 71 CONTROL_USB_CHARGING_COMMANDS = [
72 { 72 {
73 # Nexus 4 73 # Nexus 4
74 'witness_file': '/sys/module/pm8921_charger/parameters/disabled', 74 'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
75 'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled', 75 'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
76 'disable_command': 76 'disable_command':
77 'echo 1 > /sys/module/pm8921_charger/parameters/disabled', 77 'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
78 }, 78 },
79 ] 79 ]
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 self._external_storage = '' 288 self._external_storage = ''
289 self._util_wrapper = '' 289 self._util_wrapper = ''
290 self._system_properties = system_properties.SystemProperties(self.Adb()) 290 self._system_properties = system_properties.SystemProperties(self.Adb())
291 self._push_if_needed_cache = {} 291 self._push_if_needed_cache = {}
292 self._control_usb_charging_command = { 292 self._control_usb_charging_command = {
293 'command': None, 293 'command': None,
294 'cached': False, 294 'cached': False,
295 } 295 }
296 self._protected_file_access_method_initialized = None 296 self._protected_file_access_method_initialized = None
297 self._privileged_command_runner = None 297 self._privileged_command_runner = None
298 self._pie_wrapper = None
298 299
299 @property 300 @property
300 def system_properties(self): 301 def system_properties(self):
301 return self._system_properties 302 return self._system_properties
302 303
303 def _LogShell(self, cmd): 304 def _LogShell(self, cmd):
304 """Logs the adb shell command.""" 305 """Logs the adb shell command."""
305 if self._device: 306 if self._device:
306 device_repr = self._device[-4:] 307 device_repr = self._device[-4:]
307 else: 308 else:
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 641
641 base_command = shlex.split(command)[0].strip(';') 642 base_command = shlex.split(command)[0].strip(';')
642 if (base_command in preferred_apis and 643 if (base_command in preferred_apis and
643 (base_command not in whitelisted_callers or 644 (base_command not in whitelisted_callers or
644 whitelisted_callers[base_command] not in [ 645 whitelisted_callers[base_command] not in [
645 f[3] for f in inspect.stack()])): 646 f[3] for f in inspect.stack()])):
646 error_msg = ('%s should not be run directly. Instead use: %s' % 647 error_msg = ('%s should not be run directly. Instead use: %s' %
647 (base_command, preferred_apis[base_command])) 648 (base_command, preferred_apis[base_command]))
648 raise ValueError(error_msg) 649 raise ValueError(error_msg)
649 650
651 def GetAndroidToolStatusAndOutput(self, command, lib_path=None, *args, **kw):
652 """Runs a native Android binary, wrapping the command as necessary.
653
654 This is a specialization of GetShellCommandStatusAndOutput, which is meant
655 for running tools/android/ binaries and handle properly: (1) setting the
656 lib path (for component=shared_library), (2) using the PIE wrapper on ICS.
657 See crbug.com/373219 for more context.
658
659 Args:
660 command: String containing the command to send.
661 lib_path: (optional) path to the folder containing the dependent libs.
662 Same other arguments of GetCmdStatusAndOutput.
663 """
664 # The first time this command is run the device is inspected to check
665 # whether a wrapper for running PIE executable is needed (only Android ICS)
666 # or not. The results is cached, so the wrapper is pushed only once.
667 if self._pie_wrapper is None:
668 # None: did not check; '': did check and not needed; '/path': use /path.
669 self._pie_wrapper = ''
670 if self.GetBuildId().startswith('I'): # Ixxxx = Android ICS.
671 run_pie_dist_path = os.path.join(constants.GetOutDirectory(), 'run_pie')
672 assert os.path.exists(run_pie_dist_path), 'Please build run_pie'
673 # The PIE loader must be pushed manually (i.e. no PushIfNeeded) because
674 # PushIfNeeded requires md5sum and md5sum requires the wrapper as well.
675 command = 'push %s %s' % (run_pie_dist_path, PIE_WRAPPER_PATH)
676 assert _HasAdbPushSucceeded(self._adb.SendCommand(command))
677 self._pie_wrapper = PIE_WRAPPER_PATH
678
679 if self._pie_wrapper:
680 command = '%s %s' % (self._pie_wrapper, command)
681 if lib_path:
682 command = 'LD_LIBRARY_PATH=%s %s' % (lib_path, command)
683 return self.GetShellCommandStatusAndOutput(command, *args, **kw)
684
650 # It is tempting to turn this function into a generator, however this is not 685 # It is tempting to turn this function into a generator, however this is not
651 # possible without using a private (local) adb_shell instance (to ensure no 686 # possible without using a private (local) adb_shell instance (to ensure no
652 # other command interleaves usage of it), which would defeat the main aim of 687 # other command interleaves usage of it), which would defeat the main aim of
653 # being able to reuse the adb shell instance across commands. 688 # being able to reuse the adb shell instance across commands.
654 def RunShellCommand(self, command, timeout_time=20, log_result=False): 689 def RunShellCommand(self, command, timeout_time=20, log_result=False):
655 """Send a command to the adb shell and return the result. 690 """Send a command to the adb shell and return the result.
656 691
657 Args: 692 Args:
658 command: String containing the shell command to send. Must not include 693 command: String containing the shell command to send. Must not include
659 the single quotes as we use them to escape the whole command. 694 the single quotes as we use them to escape the whole command.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 Returns: 952 Returns:
918 A tuple containing lists of the host and device md5sum results as 953 A tuple containing lists of the host and device md5sum results as
919 created by _ParseMd5SumOutput(). 954 created by _ParseMd5SumOutput().
920 """ 955 """
921 md5sum_dist_path = os.path.join(constants.GetOutDirectory(), 956 md5sum_dist_path = os.path.join(constants.GetOutDirectory(),
922 'md5sum_dist') 957 'md5sum_dist')
923 assert os.path.exists(md5sum_dist_path), 'Please build md5sum.' 958 assert os.path.exists(md5sum_dist_path), 'Please build md5sum.'
924 command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER) 959 command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER)
925 assert _HasAdbPushSucceeded(self._adb.SendCommand(command)) 960 assert _HasAdbPushSucceeded(self._adb.SendCommand(command))
926 961
927 cmd = (MD5SUM_LD_LIBRARY_PATH + ' ' + self._util_wrapper + ' ' + 962 (_, md5_device_output) = self.GetAndroidToolStatusAndOutput(
928 MD5SUM_DEVICE_PATH + ' ' + device_path) 963 self._util_wrapper + ' ' + MD5SUM_DEVICE_PATH + ' ' + device_path,
929 device_hash_tuples = _ParseMd5SumOutput( 964 lib_path=MD5SUM_DEVICE_FOLDER,
930 self.RunShellCommand(cmd, timeout_time=2 * 60)) 965 timeout_time=2 * 60)
966 device_hash_tuples = _ParseMd5SumOutput(md5_device_output)
931 assert os.path.exists(host_path), 'Local path not found %s' % host_path 967 assert os.path.exists(host_path), 'Local path not found %s' % host_path
932 md5sum_output = cmd_helper.GetCmdOutput( 968 md5sum_output = cmd_helper.GetCmdOutput(
933 [os.path.join(constants.GetOutDirectory(), 'md5sum_bin_host'), 969 [os.path.join(constants.GetOutDirectory(), 'md5sum_bin_host'),
934 host_path]) 970 host_path])
935 host_hash_tuples = _ParseMd5SumOutput(md5sum_output.splitlines()) 971 host_hash_tuples = _ParseMd5SumOutput(md5sum_output.splitlines())
936 return (host_hash_tuples, device_hash_tuples) 972 return (host_hash_tuples, device_hash_tuples)
937 973
938 def GetFilesChanged(self, host_path, device_path, ignore_filenames=False): 974 def GetFilesChanged(self, host_path, device_path, ignore_filenames=False):
939 """Compares the md5sum of a host path against a device path. 975 """Compares the md5sum of a host path against a device path.
940 976
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 """ 1960 """
1925 def __init__(self, output): 1961 def __init__(self, output):
1926 self._output = output 1962 self._output = output
1927 1963
1928 def write(self, data): 1964 def write(self, data):
1929 data = data.replace('\r\r\n', '\n') 1965 data = data.replace('\r\r\n', '\n')
1930 self._output.write(data) 1966 self._output.write(data)
1931 1967
1932 def flush(self): 1968 def flush(self):
1933 self._output.flush() 1969 self._output.flush()
OLDNEW
« no previous file with comments | « build/android/provision_devices.py ('k') | build/android/pylib/forwarder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698