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

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

Issue 251743003: telemetry: android: use both methods to access protected files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments 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 | « no previous file | no next file » | 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
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 self._potential_push_size = 0 290 self._potential_push_size = 0
291 self._actual_push_size = 0 291 self._actual_push_size = 0
292 self._external_storage = '' 292 self._external_storage = ''
293 self._util_wrapper = '' 293 self._util_wrapper = ''
294 self._system_properties = system_properties.SystemProperties(self.Adb()) 294 self._system_properties = system_properties.SystemProperties(self.Adb())
295 self._push_if_needed_cache = {} 295 self._push_if_needed_cache = {}
296 self._control_usb_charging_command = { 296 self._control_usb_charging_command = {
297 'command': None, 297 'command': None,
298 'cached': False, 298 'cached': False,
299 } 299 }
300 self._protected_file_access_method = None
300 301
301 @property 302 @property
302 def system_properties(self): 303 def system_properties(self):
303 return self._system_properties 304 return self._system_properties
304 305
305 def _LogShell(self, cmd): 306 def _LogShell(self, cmd):
306 """Logs the adb shell command.""" 307 """Logs the adb shell command."""
307 if self._device: 308 if self._device:
308 device_repr = self._device[-4:] 309 device_repr = self._device[-4:]
309 else: 310 else:
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 def _GetDeviceTempFileName(self, base_name): 1097 def _GetDeviceTempFileName(self, base_name):
1097 i = 0 1098 i = 0
1098 while self.FileExistsOnDevice( 1099 while self.FileExistsOnDevice(
1099 self.GetExternalStorage() + '/' + base_name % i): 1100 self.GetExternalStorage() + '/' + base_name % i):
1100 i += 1 1101 i += 1
1101 return self.GetExternalStorage() + '/' + base_name % i 1102 return self.GetExternalStorage() + '/' + base_name % i
1102 1103
1103 def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False): 1104 def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
1104 return self.RunShellCommand('su -c %s' % command, timeout_time, log_result) 1105 return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)
1105 1106
1107 _ACCESS_METHOD_NO_ACCESS = 0
bulach 2014/04/29 10:21:39 nit: you may as well start with 1 (and if you like
1108 _ACCESS_METHOD_AS_ROOT = 1
1109 _ACCESS_METHOD_WITH_SU = 2
1110
1106 def CanAccessProtectedFileContents(self): 1111 def CanAccessProtectedFileContents(self):
1107 """Returns True if Get/SetProtectedFileContents would work via "su". 1112 """Returns True if Get/SetProtectedFileContents would work via "su" or adb
1113 shell running as root.
1108 1114
1109 Devices running user builds don't have adb root, but may provide "su" which 1115 Devices running user builds don't have adb root, but may provide "su" which
1110 can be used for accessing protected files. 1116 can be used for accessing protected files.
1111 """ 1117 """
1112 r = self.RunShellCommandWithSU('cat /dev/null') 1118 return (self._ProtectedFileAccessMethod() !=
1113 return r == [] or r[0].strip() == '' 1119 AndroidCommands._ACCESS_METHOD_NO_ACCESS)
1120
1121 def _ProtectedFileAccessMethod(self):
1122 """Tests for the best method to access protected files on the device.
1123
1124 Returns:
1125 _ACCESS_METHOD_NO_ACCESS: if protected files cannot be accessed
1126 _ACCESS_METHOD_AS_ROOT: if the adb shell has root privileges
1127 _ACCESS_METHOD_WITH_SU: if the 'su' command properly works on the device
1128 """
1129 if self._protected_file_access_method is not None:
1130 return self._protected_file_access_method
1131
1132 def IsValidAuxContents(contents):
bulach 2014/04/29 10:21:39 I'm not sure it'd be more readable, but how about:
pasko 2014/04/29 12:57:38 Maybe. This method is elegant, but introduces a si
1133 # The leading 4 or 8-bytes of auxv vector is a_type. There are not many
1134 # reserved a_type values, hence byte 2 must always be '\0' for a realistic
1135 # auxv. See /usr/include/elf.h.
1136 return len(contents) > 0 and (contents[0][2] == '\0')
1137
1138 self._protected_file_access_method = (
1139 AndroidCommands._ACCESS_METHOD_NO_ACCESS)
1140
1141 # Get contents of the auxv vector for the init(8) process from a small
1142 # binary file that always exists on linux and is always read-protected.
1143 contents = self.RunShellCommand('cat /proc/1/auxv')
1144 if IsValidAuxContents(contents):
1145 # Protected data is available without SU, hence adb is running as root.
1146 self._protected_file_access_method = (
1147 AndroidCommands._ACCESS_METHOD_AS_ROOT)
1148 else:
1149 contents = self.RunShellCommandWithSU('cat /proc/1/auxv')
1150 if IsValidAuxContents(contents):
1151 # Protected data is available when asked with SU.
1152 self._protected_file_access_method = (
1153 AndroidCommands._ACCESS_METHOD_WITH_SU)
1154 return self._protected_file_access_method
1114 1155
1115 def GetProtectedFileContents(self, filename): 1156 def GetProtectedFileContents(self, filename):
1116 """Gets contents from the protected file specified by |filename|. 1157 """Gets contents from the protected file specified by |filename|.
1117 1158
1118 This is less efficient than GetFileContents, but will work for protected 1159 This is potentially less efficient than GetFileContents.
1119 files and device files.
1120 """ 1160 """
1121 # Run the script as root 1161 command = 'cat "%s" 2> /dev/null' % filename
1122 return self.RunShellCommandWithSU('cat "%s" 2> /dev/null' % filename) 1162 access_method = self._ProtectedFileAccessMethod()
1163 if access_method == AndroidCommands._ACCESS_METHOD_WITH_SU:
1164 return self.RunShellCommandWithSU(command)
1165 elif access_method == AndroidCommands._ACCESS_METHOD_AS_ROOT:
1166 return self.RunShellCommand(command)
1167 else:
1168 logging.warning('Could not access protected file: %s' % filename)
1169 return []
1123 1170
1124 def SetProtectedFileContents(self, filename, contents): 1171 def SetProtectedFileContents(self, filename, contents):
1125 """Writes |contents| to the protected file specified by |filename|. 1172 """Writes |contents| to the protected file specified by |filename|.
1126 1173
1127 This is less efficient than SetFileContents, but will work for protected 1174 This is less efficient than SetFileContents.
1128 files and device files.
1129 """ 1175 """
1130 temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT) 1176 temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
1131 temp_script = self._GetDeviceTempFileName( 1177 temp_script = self._GetDeviceTempFileName(
1132 AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT) 1178 AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
1133 1179
1134 # Put the contents in a temporary file 1180 # Put the contents in a temporary file
1135 self.SetFileContents(temp_file, contents) 1181 self.SetFileContents(temp_file, contents)
1136 # Create a script to copy the file contents to its final destination 1182 # Create a script to copy the file contents to its final destination
1137 self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename)) 1183 self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
1138 # Run the script as root 1184
1139 self.RunShellCommandWithSU('sh %s' % temp_script) 1185 command = 'sh %s' % temp_script
1186 access_method = self._ProtectedFileAccessMethod()
1187 if access_method == AndroidCommands._ACCESS_METHOD_WITH_SU:
1188 return self.RunShellCommandWithSU(command)
1189 elif access_method == AndroidCommands._ACCESS_METHOD_AS_ROOT:
1190 return self.RunShellCommand(command)
1191 else:
1192 logging.warning('Could not set contents of protected file: %s' % filename)
1193
1140 # And remove the temporary files 1194 # And remove the temporary files
1141 self.RunShellCommand('rm ' + temp_file) 1195 self.RunShellCommand('rm ' + temp_file)
1142 self.RunShellCommand('rm ' + temp_script) 1196 self.RunShellCommand('rm ' + temp_script)
1143 1197
1144 def RemovePushedFiles(self): 1198 def RemovePushedFiles(self):
1145 """Removes all files pushed with PushIfNeeded() from the device.""" 1199 """Removes all files pushed with PushIfNeeded() from the device."""
1146 for p in self._pushed_files: 1200 for p in self._pushed_files:
1147 self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60) 1201 self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60)
1148 1202
1149 def ListPathContents(self, path): 1203 def ListPathContents(self, path):
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 """ 1978 """
1925 def __init__(self, output): 1979 def __init__(self, output):
1926 self._output = output 1980 self._output = output
1927 1981
1928 def write(self, data): 1982 def write(self, data):
1929 data = data.replace('\r\r\n', '\n') 1983 data = data.replace('\r\r\n', '\n')
1930 self._output.write(data) 1984 self._output.write(data)
1931 1985
1932 def flush(self): 1986 def flush(self):
1933 self._output.flush() 1987 self._output.flush()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698