OLD | NEW |
1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2015 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 """Utility library for running a startup profile on an Android device. | 5 """Utility library for running a startup profile on an Android device. |
6 | 6 |
7 Sets up a device for cygprofile, disables sandboxing permissions, and sets up | 7 Sets up a device for cygprofile, disables sandboxing permissions, and sets up |
8 support for web page replay, device forwarding, and fake certificate authority | 8 support for web page replay, device forwarding, and fake certificate authority |
9 to make runs repeatable. | 9 to make runs repeatable. |
10 """ | 10 """ |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 def RunCygprofileTests(self): | 211 def RunCygprofileTests(self): |
212 """Run the cygprofile unit tests suite on the device. | 212 """Run the cygprofile unit tests suite on the device. |
213 | 213 |
214 Args: | 214 Args: |
215 path_to_tests: The location on the host machine with the compiled | 215 path_to_tests: The location on the host machine with the compiled |
216 cygprofile test binary. | 216 cygprofile test binary. |
217 Returns: | 217 Returns: |
218 The exit code for the tests. | 218 The exit code for the tests. |
219 """ | 219 """ |
220 device_path = '/data/local/tmp/cygprofile_unittests' | 220 device_path = '/data/local/tmp/cygprofile_unittests' |
221 self._device.PushChangedFiles([(self._cygprofile_tests, device_path)]) | 221 self._device.old_interface.PushIfNeeded( |
222 try: | 222 self._cygprofile_tests, device_path) |
223 self._device.RunShellCommand(device_path, check_return=True) | 223 (exit_code, _) = ( |
224 except device_errors.CommandFailedError: | 224 self._device.old_interface.GetShellCommandStatusAndOutput( |
225 # TODO(jbudorick): Let the exception propagate up once clients can | 225 command=device_path, log_result=True)) |
226 # handle it. | 226 return exit_code |
227 logging.exception('Failure while running cygprofile_unittests:') | |
228 return 1 | |
229 return 0 | |
230 | 227 |
231 def CollectProfile(self, apk, package_info): | 228 def CollectProfile(self, apk, package_info): |
232 """Run a profile and collect the log files. | 229 """Run a profile and collect the log files. |
233 | 230 |
234 Args: | 231 Args: |
235 apk: The location of the chrome apk to profile. | 232 apk: The location of the chrome apk to profile. |
236 package_info: A PackageInfo structure describing the chrome apk, | 233 package_info: A PackageInfo structure describing the chrome apk, |
237 as from pylib/constants. | 234 as from pylib/constants. |
238 Returns: | 235 Returns: |
239 A list of cygprofile data files. | 236 A list of cygprofile data files. |
240 Raises: | 237 Raises: |
241 NoCyglogDataError: No data was found on the device. | 238 NoCyglogDataError: No data was found on the device. |
242 """ | 239 """ |
243 self._Install(apk) | 240 self._Install(apk, package_info) |
| 241 |
244 try: | 242 try: |
245 changer = self._SetChromeFlags(package_info) | 243 changer = self._SetChromeFlags(package_info) |
246 self._SetUpDeviceFolders() | 244 self._SetUpDeviceFolders() |
247 # Start up chrome once with a blank page, just to get the one-off | 245 # Start up chrome once with a blank page, just to get the one-off |
248 # activities out of the way such as apk resource extraction and profile | 246 # activities out of the way such as apk resource extraction and profile |
249 # creation. | 247 # creation. |
250 self._StartChrome(package_info, 'about:blank') | 248 self._StartChrome(package_info, 'about:blank') |
251 time.sleep(15) | 249 time.sleep(15) |
252 self._KillChrome(package_info) | 250 self._KillChrome(package_info) |
253 self._SetUpDeviceFolders() | 251 self._SetUpDeviceFolders() |
254 with WprManager(self._WPR_ARCHIVE, self._device, | 252 with WprManager(self._WPR_ARCHIVE, self._device, |
255 package_info.cmdline_file): | 253 package_info.cmdline_file): |
256 self._StartChrome(package_info, self._TEST_URL) | 254 self._StartChrome(package_info, self._TEST_URL) |
257 time.sleep(90) | 255 time.sleep(90) |
258 self._KillChrome(package_info) | 256 self._KillChrome(package_info) |
259 finally: | 257 finally: |
260 self._RestoreChromeFlags(changer) | 258 self._RestoreChromeFlags(changer) |
261 | 259 |
262 data = self._PullCyglogData() | 260 data = self._PullCyglogData() |
263 self._DeleteDeviceData() | 261 self._DeleteDeviceData() |
264 return data | 262 return data |
265 | 263 |
266 def Cleanup(self): | 264 def Cleanup(self): |
267 """Delete all local and device files left over from profiling. """ | 265 """Delete all local and device files left over from profiling. """ |
268 self._DeleteDeviceData() | 266 self._DeleteDeviceData() |
269 self._DeleteHostData() | 267 self._DeleteHostData() |
270 | 268 |
271 def _Install(self, apk): | 269 def _Install(self, apk, package_info): |
272 """Installs Chrome.apk on the device. | 270 """Installs Chrome.apk on the device. |
273 Args: | 271 Args: |
274 apk: The location of the chrome apk to profile. | 272 apk: The location of the chrome apk to profile. |
275 package_info: A PackageInfo structure describing the chrome apk, | 273 package_info: A PackageInfo structure describing the chrome apk, |
276 as from pylib/constants. | 274 as from pylib/constants. |
277 """ | 275 """ |
278 print 'Installing apk...' | 276 print 'Installing apk...' |
279 self._device.Install(apk) | 277 self._device.old_interface.ManagedInstall(apk, package_info.package) |
280 | 278 |
281 def _SetUpDevice(self): | 279 def _SetUpDevice(self): |
282 """When profiling, files are output to the disk by every process. This | 280 """When profiling, files are output to the disk by every process. This |
283 means running without sandboxing enabled. | 281 means running without sandboxing enabled. |
284 """ | 282 """ |
285 # We need to have adb root in order to pull cyglog data | 283 # We need to have adb root in order to pull cyglog data |
286 try: | 284 try: |
287 print 'Enabling root...' | 285 print 'Enabling root...' |
288 self._device.EnableRoot() | 286 self._device.EnableRoot() |
289 # SELinux need to be in permissive mode, otherwise the process cannot | 287 # SELinux need to be in permissive mode, otherwise the process cannot |
290 # write the log files. | 288 # write the log files. |
291 print 'Putting SELinux in permissive mode...' | 289 print 'Putting SELinux in permissive mode...' |
292 self._device.RunShellCommand(['setenforce' '0'], check_return=True) | 290 self._device.old_interface.RunShellCommand('setenforce 0') |
293 except device_errors.CommandFailedError as e: | 291 except device_errors.CommandFailedError as e: |
294 # TODO(jbudorick) Handle this exception appropriately once interface | 292 # TODO(jbudorick) Handle this exception appropriately once interface |
295 # conversions are finished. | 293 # conversions are finished. |
296 logging.error(str(e)) | 294 logging.error(str(e)) |
297 | 295 |
298 def _SetChromeFlags(self, package_info): | 296 def _SetChromeFlags(self, package_info): |
299 print 'Setting Chrome flags...' | 297 print 'Setting Chrome flags...' |
300 changer = flag_changer.FlagChanger( | 298 changer = flag_changer.FlagChanger( |
301 self._device, package_info.cmdline_file) | 299 self._device, package_info.cmdline_file) |
302 changer.AddFlags(['--no-sandbox', '--disable-fre']) | 300 changer.AddFlags(['--no-sandbox', '--disable-fre']) |
303 return changer | 301 return changer |
304 | 302 |
305 def _RestoreChromeFlags(self, changer): | 303 def _RestoreChromeFlags(self, changer): |
306 print 'Restoring Chrome flags...' | 304 print 'Restoring Chrome flags...' |
307 if changer: | 305 if changer: |
308 changer.Restore() | 306 changer.Restore() |
309 | 307 |
310 def _SetUpDeviceFolders(self): | 308 def _SetUpDeviceFolders(self): |
311 """Creates folders on the device to store cyglog data. """ | 309 """Creates folders on the device to store cyglog data. """ |
312 print 'Setting up device folders...' | 310 print 'Setting up device folders...' |
313 self._DeleteDeviceData() | 311 self._DeleteDeviceData() |
314 self._device.RunShellCommand( | 312 self._device.old_interface.RunShellCommand( |
315 ['mkdir', '-p', str(self._DEVICE_CYGLOG_DIR)], | 313 'mkdir -p %s' % self._DEVICE_CYGLOG_DIR) |
316 check_return=True) | |
317 | 314 |
318 def _DeleteDeviceData(self): | 315 def _DeleteDeviceData(self): |
319 """Clears out cyglog storage locations on the device. """ | 316 """Clears out cyglog storage locations on the device. """ |
320 self._device.RunShellCommand( | 317 self._device.old_interface.RunShellCommand( |
321 ['rm', '-rf', str(self._DEVICE_CYGLOG_DIR)], | 318 'rm -rf %s' % self._DEVICE_CYGLOG_DIR) |
322 check_return=True) | |
323 | 319 |
324 def _StartChrome(self, package_info, url): | 320 def _StartChrome(self, package_info, url): |
325 print 'Launching chrome...' | 321 print 'Launching chrome...' |
326 self._device.StartActivity( | 322 self._device.StartActivity( |
327 intent.Intent(package=package_info.package, | 323 intent.Intent(package=package_info.package, |
328 activity=package_info.activity, | 324 activity=package_info.activity, |
329 data=url, | 325 data=url, |
330 extras={'create_new_tab' : True}), | 326 extras={'create_new_tab' : True}), |
331 blocking=True, force_stop=True) | 327 blocking=True, force_stop=True) |
332 | 328 |
(...skipping 11 matching lines...) Expand all Loading... |
344 def _PullCyglogData(self): | 340 def _PullCyglogData(self): |
345 """Pull the cyglog data off of the device. | 341 """Pull the cyglog data off of the device. |
346 | 342 |
347 Returns: | 343 Returns: |
348 A list of cyglog data files which were pulled. | 344 A list of cyglog data files which were pulled. |
349 Raises: | 345 Raises: |
350 NoCyglogDataError: No data was found on the device. | 346 NoCyglogDataError: No data was found on the device. |
351 """ | 347 """ |
352 print 'Pulling cyglog data...' | 348 print 'Pulling cyglog data...' |
353 self._SetUpHostFolders() | 349 self._SetUpHostFolders() |
354 self._device.PullFile( | 350 self._device.old_interface.Adb().Pull( |
355 self._DEVICE_CYGLOG_DIR, self._host_cyglog_dir) | 351 self._DEVICE_CYGLOG_DIR, self._host_cyglog_dir) |
356 files = os.listdir(self._host_cyglog_dir) | 352 files = os.listdir(self._host_cyglog_dir) |
357 | 353 |
358 if len(files) == 0: | 354 if len(files) == 0: |
359 raise NoCyglogDataError('No cyglog data was collected') | 355 raise NoCyglogDataError('No cyglog data was collected') |
360 | 356 |
361 return [os.path.join(self._host_cyglog_dir, x) for x in files] | 357 return [os.path.join(self._host_cyglog_dir, x) for x in files] |
OLD | NEW |