summaryrefslogtreecommitdiffstats
path: root/build
diff options
context:
space:
mode:
authorpasko@chromium.org <pasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 08:41:06 +0000
committerpasko@chromium.org <pasko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-30 08:41:06 +0000
commit9d402bcaca0b2a1ddd2d5960230362550e797c21 (patch)
tree2e448e5ff6e7ae1be5b9e2522fc04269cef58c95 /build
parent9eaf94b1a50232744d5454eae54fd8139094d963 (diff)
downloadchromium_src-9d402bcaca0b2a1ddd2d5960230362550e797c21.zip
chromium_src-9d402bcaca0b2a1ddd2d5960230362550e797c21.tar.gz
chromium_src-9d402bcaca0b2a1ddd2d5960230362550e797c21.tar.bz2
telemetry: android: use both methods to access protected files
Currently when telemetry asks to read/write a protected file, it attempts doing so with the 'su' command, but not all devices have the 'su' command installed. In this case telemetry ignores all errors and continues silently. This change: 1. chooses the best method to access protected files: 'adb root' or 'su' 2. caches the choice 3. throws warnings each time a protected file cannot be accessed BUG=366640 Review URL: https://codereview.chromium.org/251743003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267137 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'build')
-rw-r--r--build/android/pylib/android_commands.py60
1 files changed, 49 insertions, 11 deletions
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
index 20e9bf5..0a710f9 100644
--- a/build/android/pylib/android_commands.py
+++ b/build/android/pylib/android_commands.py
@@ -297,6 +297,8 @@ class AndroidCommands(object):
'command': None,
'cached': False,
}
+ self._protected_file_access_method_initialized = None
+ self._privileged_command_runner = None
@property
def system_properties(self):
@@ -1105,28 +1107,58 @@ class AndroidCommands(object):
return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)
def CanAccessProtectedFileContents(self):
- """Returns True if Get/SetProtectedFileContents would work via "su".
+ """Returns True if Get/SetProtectedFileContents would work via "su" or adb
+ shell running as root.
Devices running user builds don't have adb root, but may provide "su" which
can be used for accessing protected files.
"""
- r = self.RunShellCommandWithSU('cat /dev/null')
- return r == [] or r[0].strip() == ''
+ return (self._GetProtectedFileCommandRunner() != None)
+
+ def _GetProtectedFileCommandRunner(self):
+ """Finds the best method to access protected files on the device.
+
+ Returns:
+ 1. None when privileged files cannot be accessed on the device.
+ 2. Otherwise: A function taking a single parameter: a string with command
+ line arguments. Running that function executes the command with
+ the appropriate method.
+ """
+ if self._protected_file_access_method_initialized:
+ return self._privileged_command_runner
+
+ self._privileged_command_runner = None
+ self._protected_file_access_method_initialized = True
+
+ for cmd in [self.RunShellCommand, self.RunShellCommandWithSU]:
+ # Get contents of the auxv vector for the init(8) process from a small
+ # binary file that always exists on linux and is always read-protected.
+ contents = cmd('cat /proc/1/auxv')
+ # The leading 4 or 8-bytes of auxv vector is a_type. There are not many
+ # reserved a_type values, hence byte 2 must always be '\0' for a realistic
+ # auxv. See /usr/include/elf.h.
+ if len(contents) > 0 and (contents[0][2] == '\0'):
+ self._privileged_command_runner = cmd
+ break
+ return self._privileged_command_runner
def GetProtectedFileContents(self, filename):
"""Gets contents from the protected file specified by |filename|.
- This is less efficient than GetFileContents, but will work for protected
- files and device files.
+ This is potentially less efficient than GetFileContents.
"""
- # Run the script as root
- return self.RunShellCommandWithSU('cat "%s" 2> /dev/null' % filename)
+ command = 'cat "%s" 2> /dev/null' % filename
+ command_runner = self._GetProtectedFileCommandRunner()
+ if command_runner:
+ return command_runner(command)
+ else:
+ logging.warning('Could not access protected file: %s' % filename)
+ return []
def SetProtectedFileContents(self, filename, contents):
"""Writes |contents| to the protected file specified by |filename|.
- This is less efficient than SetFileContents, but will work for protected
- files and device files.
+ This is less efficient than SetFileContents.
"""
temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
temp_script = self._GetDeviceTempFileName(
@@ -1136,8 +1168,14 @@ class AndroidCommands(object):
self.SetFileContents(temp_file, contents)
# Create a script to copy the file contents to its final destination
self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
- # Run the script as root
- self.RunShellCommandWithSU('sh %s' % temp_script)
+
+ command = 'sh %s' % temp_script
+ command_runner = self._GetProtectedFileCommandRunner()
+ if command_runner:
+ return command_runner(command)
+ else:
+ logging.warning('Could not set contents of protected file: %s' % filename)
+
# And remove the temporary files
self.RunShellCommand('rm ' + temp_file)
self.RunShellCommand('rm ' + temp_script)