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

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: Created 6 years, 8 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 = "no access"
Sami 2014/04/28 12:55:49 nit: Start with underscore since these probably do
jbudorick 2014/04/28 14:22:52 +1 for using numeric constants.
pasko 2014/04/29 09:42:32 Renaming: Done. Most votes are for numeric constan
pasko 2014/04/29 09:42:32 Done.
1108 ACCESS_METHOD_AS_ROOT = "as root"
1109 ACCESS_METHOD_WITH_SU = "with su"
bulach 2014/04/28 12:21:48 nit: use single quotes
pasko 2014/04/29 09:42:32 thanks, changed to numeric constants
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:
bulach 2014/04/28 12:21:48 nit: s/is not None//
pasko 2014/04/29 09:42:32 I changed this to numeric constants, so to disting
1130 return self._protected_file_access_method
1131
1132 def AuxContentsLookReal(contents):
bulach 2014/04/28 12:21:48 nit: how about "_IsValidContents" ?
jbudorick 2014/04/28 14:22:52 Why check the output rather than the return code?
pasko 2014/04/29 09:42:32 I changed this to IsValidAuxContents(). Since the
pasko 2014/04/29 09:42:32 This is mainly because RunShellCommand() and RunSh
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 = AndroidCommands.ACCESS_METHOD_NO_ACCESS
1139
1140 # Get contents of the auxv vector for the init(8) process from a small
1141 # binary file that always exists on a linux and is always read-protected.
1142 contents = self.RunShellCommand('cat /proc/1/auxv')
Sami 2014/04/28 12:55:49 Neat trick :)
pasko 2014/04/29 09:42:32 thnx)
1143 if AuxContentsLookReal(contents):
1144 # Protected data is available without SU, hence adb is running as root.
1145 self._protected_file_access_method = AndroidCommands.ACCESS_METHOD_AS_ROOT
jbudorick 2014/04/28 14:22:52 FWIW, I've been toying with doing the as_root chec
pasko 2014/04/29 09:42:32 I did not know about this property :)
1146 else:
1147 contents = self.RunShellCommandWithSU('cat /proc/1/auxv')
1148 if AuxContentsLookReal(contents):
1149 # Protected data is available when asked with SU.
1150 self._protected_file_access_method = (
1151 AndroidCommands.ACCESS_METHOD_WITH_SU)
1152 return self._protected_file_access_method
Sami 2014/04/28 12:55:49 Set access method to ACCESS_METHOD_NO_ACCESS here?
pasko 2014/04/29 09:42:32 I've set it above. If I wanted to move it here fro
1114 1153
1115 def GetProtectedFileContents(self, filename): 1154 def GetProtectedFileContents(self, filename):
1116 """Gets contents from the protected file specified by |filename|. 1155 """Gets contents from the protected file specified by |filename|.
1117 1156
1118 This is less efficient than GetFileContents, but will work for protected 1157 This is potentially less efficient than GetFileContents.
1119 files and device files.
1120 """ 1158 """
1121 # Run the script as root 1159 command = 'cat "%s" 2> /dev/null' % filename
1122 return self.RunShellCommandWithSU('cat "%s" 2> /dev/null' % filename) 1160 access_method = self._ProtectedFileAccessMethod()
1161 if access_method == AndroidCommands.ACCESS_METHOD_WITH_SU:
1162 return self.RunShellCommandWithSU(command)
1163 elif access_method == AndroidCommands.ACCESS_METHOD_AS_ROOT:
1164 return self.RunShellCommand(command)
1165 else:
1166 logging.warning('Could not access protected file: %s' % filename)
1167 return []
bulach 2014/04/28 12:21:48 now, if we're going to fix this once and for all :
jbudorick 2014/04/28 14:22:52 I'm ok with this idea in general. I think implemen
pasko 2014/04/29 09:42:32 I'm +1 to jbudorick@ here: it will likely break in
1123 1168
1124 def SetProtectedFileContents(self, filename, contents): 1169 def SetProtectedFileContents(self, filename, contents):
1125 """Writes |contents| to the protected file specified by |filename|. 1170 """Writes |contents| to the protected file specified by |filename|.
1126 1171
1127 This is less efficient than SetFileContents, but will work for protected 1172 This is less efficient than SetFileContents.
1128 files and device files.
1129 """ 1173 """
1130 temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT) 1174 temp_file = self._GetDeviceTempFileName(AndroidCommands._TEMP_FILE_BASE_FMT)
1131 temp_script = self._GetDeviceTempFileName( 1175 temp_script = self._GetDeviceTempFileName(
1132 AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT) 1176 AndroidCommands._TEMP_SCRIPT_FILE_BASE_FMT)
1133 1177
1134 # Put the contents in a temporary file 1178 # Put the contents in a temporary file
1135 self.SetFileContents(temp_file, contents) 1179 self.SetFileContents(temp_file, contents)
1136 # Create a script to copy the file contents to its final destination 1180 # Create a script to copy the file contents to its final destination
1137 self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename)) 1181 self.SetFileContents(temp_script, 'cat %s > %s' % (temp_file, filename))
1138 # Run the script as root 1182
1139 self.RunShellCommandWithSU('sh %s' % temp_script) 1183 command = 'sh %s' % temp_script
1184 access_method = self._ProtectedFileAccessMethod()
Sami 2014/04/28 12:55:49 This could be a little cleaner if access_method wa
pasko 2014/04/29 09:42:32 Do you suggest to check for None and call otherwis
1185 if access_method == AndroidCommands.ACCESS_METHOD_WITH_SU:
1186 return self.RunShellCommandWithSU(command)
1187 elif access_method == AndroidCommands.ACCESS_METHOD_AS_ROOT:
1188 return self.RunShellCommand(command)
1189 else:
1190 logging.warning('Could not set contents of protected file: %s' % filename)
bulach 2014/04/28 12:21:48 ditto.
1191
1140 # And remove the temporary files 1192 # And remove the temporary files
1141 self.RunShellCommand('rm ' + temp_file) 1193 self.RunShellCommand('rm ' + temp_file)
1142 self.RunShellCommand('rm ' + temp_script) 1194 self.RunShellCommand('rm ' + temp_script)
1143 1195
1144 def RemovePushedFiles(self): 1196 def RemovePushedFiles(self):
1145 """Removes all files pushed with PushIfNeeded() from the device.""" 1197 """Removes all files pushed with PushIfNeeded() from the device."""
1146 for p in self._pushed_files: 1198 for p in self._pushed_files:
1147 self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60) 1199 self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60)
1148 1200
1149 def ListPathContents(self, path): 1201 def ListPathContents(self, path):
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 """ 1976 """
1925 def __init__(self, output): 1977 def __init__(self, output):
1926 self._output = output 1978 self._output = output
1927 1979
1928 def write(self, data): 1980 def write(self, data):
1929 data = data.replace('\r\r\n', '\n') 1981 data = data.replace('\r\r\n', '\n')
1930 self._output.write(data) 1982 self._output.write(data)
1931 1983
1932 def flush(self): 1984 def flush(self):
1933 self._output.flush() 1985 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