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

Side by Side Diff: build/android/pylib/device/device_utils.py

Issue 655723003: [Android] Don't use zip pushing if not built or on user builds. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 a variety of device interactions based on adb. 5 """Provides a variety of device interactions based on adb.
6 6
7 Eventually, this will be based on adb_wrapper. 7 Eventually, this will be based on adb_wrapper.
8 """ 8 """
9 # pylint: disable=W0613 9 # pylint: disable=W0613
10 10
11 import logging
11 import multiprocessing 12 import multiprocessing
12 import os 13 import os
13 import pipes 14 import pipes
14 import sys 15 import sys
15 import tempfile 16 import tempfile
16 import time 17 import time
17 import zipfile 18 import zipfile
18 19
19 import pylib.android_commands 20 import pylib.android_commands
20 from pylib.device import adb_wrapper 21 from pylib.device import adb_wrapper
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 self.adb = device 77 self.adb = device
77 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) 78 self.old_interface = pylib.android_commands.AndroidCommands(str(device))
78 elif isinstance(device, pylib.android_commands.AndroidCommands): 79 elif isinstance(device, pylib.android_commands.AndroidCommands):
79 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) 80 self.adb = adb_wrapper.AdbWrapper(device.GetDevice())
80 self.old_interface = device 81 self.old_interface = device
81 elif not device: 82 elif not device:
82 self.adb = adb_wrapper.AdbWrapper('') 83 self.adb = adb_wrapper.AdbWrapper('')
83 self.old_interface = pylib.android_commands.AndroidCommands() 84 self.old_interface = pylib.android_commands.AndroidCommands()
84 else: 85 else:
85 raise ValueError('Unsupported type passed for argument "device"') 86 raise ValueError('Unsupported type passed for argument "device"')
86 self._commands_installed = False 87 self._commands_installed = None
87 self._default_timeout = default_timeout 88 self._default_timeout = default_timeout
88 self._default_retries = default_retries 89 self._default_retries = default_retries
89 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) 90 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR))
90 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) 91 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR))
91 92
92 @decorators.WithTimeoutAndRetriesFromInstance() 93 @decorators.WithTimeoutAndRetriesFromInstance()
93 def IsOnline(self, timeout=None, retries=None): 94 def IsOnline(self, timeout=None, retries=None):
94 """Checks whether the device is online. 95 """Checks whether the device is online.
95 96
96 Args: 97 Args:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 139
139 Raises: 140 Raises:
140 CommandFailedError if root could not be enabled. 141 CommandFailedError if root could not be enabled.
141 CommandTimeoutError on timeout. 142 CommandTimeoutError on timeout.
142 """ 143 """
143 if not self.old_interface.EnableAdbRoot(): 144 if not self.old_interface.EnableAdbRoot():
144 raise device_errors.CommandFailedError( 145 raise device_errors.CommandFailedError(
145 'Could not enable root.', device=str(self)) 146 'Could not enable root.', device=str(self))
146 147
147 @decorators.WithTimeoutAndRetriesFromInstance() 148 @decorators.WithTimeoutAndRetriesFromInstance()
149 def IsUserBuild(self, timeout=None, retries=None):
150 """Checks whether or not the device is running a user build.
151
152 Args:
153 timeout: timeout in seconds
154 retries: number of retries
155
156 Returns:
157 True if the device is running a user build, False otherwise (i.e. if
158 it's running a userdebug build).
159
160 Raises:
161 CommandTimeoutError on timeout.
162 DeviceUnreachableError on missing device.
163 """
164 return self._GetPropImpl('ro.build.type') == 'user'
165
166 @decorators.WithTimeoutAndRetriesFromInstance()
148 def GetExternalStoragePath(self, timeout=None, retries=None): 167 def GetExternalStoragePath(self, timeout=None, retries=None):
149 """Get the device's path to its SD card. 168 """Get the device's path to its SD card.
150 169
151 Args: 170 Args:
152 timeout: timeout in seconds 171 timeout: timeout in seconds
153 retries: number of retries 172 retries: number of retries
154 173
155 Returns: 174 Returns:
156 The device's path to its SD card. 175 The device's path to its SD card.
157 176
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h)) 540 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
522 else: 541 else:
523 dir_file_count += 1 542 dir_file_count += 1
524 543
525 push_duration = self._ApproximateDuration( 544 push_duration = self._ApproximateDuration(
526 file_count, file_count, size, False) 545 file_count, file_count, size, False)
527 dir_push_duration = self._ApproximateDuration( 546 dir_push_duration = self._ApproximateDuration(
528 len(host_device_tuples), dir_file_count, dir_size, False) 547 len(host_device_tuples), dir_file_count, dir_size, False)
529 zip_duration = self._ApproximateDuration(1, 1, size, True) 548 zip_duration = self._ApproximateDuration(1, 1, size, True)
530 549
531 if dir_push_duration < push_duration and dir_push_duration < zip_duration: 550 self._InstallCommands()
551
552 if dir_push_duration < push_duration and (
553 dir_push_duration < zip_duration or not self._commands_installed):
532 self._PushChangedFilesIndividually(host_device_tuples) 554 self._PushChangedFilesIndividually(host_device_tuples)
533 elif push_duration < zip_duration: 555 elif push_duration < zip_duration or not self._commands_installed:
534 self._PushChangedFilesIndividually(files) 556 self._PushChangedFilesIndividually(files)
535 else: 557 else:
536 self._PushChangedFilesZipped(files) 558 self._PushChangedFilesZipped(files)
537 self._RunShellCommandImpl( 559 self._RunShellCommandImpl(
538 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 560 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
539 as_root=True) 561 as_root=True)
540 562
541 def _GetChangedFilesImpl(self, host_path, device_path): 563 def _GetChangedFilesImpl(self, host_path, device_path):
542 real_host_path = os.path.realpath(host_path) 564 real_host_path = os.path.realpath(host_path)
543 try: 565 try:
(...skipping 21 matching lines...) Expand all
565 to_push = [] 587 to_push = []
566 for host_hash, host_abs_path in ( 588 for host_hash, host_abs_path in (
567 (h.hash, h.path) for h in host_hash_tuples): 589 (h.hash, h.path) for h in host_hash_tuples):
568 device_abs_path = '%s/%s' % ( 590 device_abs_path = '%s/%s' % (
569 real_device_path, os.path.relpath(host_abs_path, real_host_path)) 591 real_device_path, os.path.relpath(host_abs_path, real_host_path))
570 if (device_abs_path not in device_tuple_dict 592 if (device_abs_path not in device_tuple_dict
571 or device_tuple_dict[device_abs_path] != host_hash): 593 or device_tuple_dict[device_abs_path] != host_hash):
572 to_push.append((host_abs_path, device_abs_path)) 594 to_push.append((host_abs_path, device_abs_path))
573 return to_push 595 return to_push
574 596
597 def _InstallCommands(self):
598 if self._commands_installed is None:
599 try:
600 if not install_commands.Installed(self):
601 install_commands.InstallCommands(self)
602 self._commands_installed = True
603 except Exception as e:
604 logging.warning('unzip not available: %s' % str(e))
605 self._commands_installed = False
606
575 @staticmethod 607 @staticmethod
576 def _ApproximateDuration(adb_calls, file_count, byte_count, is_zipping): 608 def _ApproximateDuration(adb_calls, file_count, byte_count, is_zipping):
577 # We approximate the time to push a set of files to a device as: 609 # We approximate the time to push a set of files to a device as:
578 # t = c1 * a + c2 * f + c3 + b / c4 + b / (c5 * c6), where 610 # t = c1 * a + c2 * f + c3 + b / c4 + b / (c5 * c6), where
579 # t: total time (sec) 611 # t: total time (sec)
580 # c1: adb call time delay (sec) 612 # c1: adb call time delay (sec)
581 # a: number of times adb is called (unitless) 613 # a: number of times adb is called (unitless)
582 # c2: push time delay (sec) 614 # c2: push time delay (sec)
583 # f: number of files pushed via adb (unitless) 615 # f: number of files pushed via adb (unitless)
584 # c3: zip time delay (sec) 616 # c3: zip time delay (sec)
(...skipping 21 matching lines...) Expand all
606 return (adb_call_time + adb_push_setup_time + zip_time + transfer_time) 638 return (adb_call_time + adb_push_setup_time + zip_time + transfer_time)
607 639
608 def _PushChangedFilesIndividually(self, files): 640 def _PushChangedFilesIndividually(self, files):
609 for h, d in files: 641 for h, d in files:
610 self.adb.Push(h, d) 642 self.adb.Push(h, d)
611 643
612 def _PushChangedFilesZipped(self, files): 644 def _PushChangedFilesZipped(self, files):
613 if not files: 645 if not files:
614 return 646 return
615 647
616 self._InstallCommands()
617
618 with tempfile.NamedTemporaryFile(suffix='.zip') as zip_file: 648 with tempfile.NamedTemporaryFile(suffix='.zip') as zip_file:
619 zip_proc = multiprocessing.Process( 649 zip_proc = multiprocessing.Process(
620 target=DeviceUtils._CreateDeviceZip, 650 target=DeviceUtils._CreateDeviceZip,
621 args=(zip_file.name, files)) 651 args=(zip_file.name, files))
622 zip_proc.start() 652 zip_proc.start()
623 zip_proc.join() 653 zip_proc.join()
624 654
625 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl() 655 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl()
626 try: 656 try:
627 self.adb.Push(zip_file.name, zip_on_device) 657 self.adb.Push(zip_file.name, zip_on_device)
628 self._RunShellCommandImpl( 658 self._RunShellCommandImpl(
629 ['unzip', zip_on_device], 659 ['unzip', zip_on_device],
630 as_root=True, check_return=True, 660 as_root=True, check_return=True,
631 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}) 661 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR})
632 finally: 662 finally:
633 if zip_proc.is_alive(): 663 if zip_proc.is_alive():
634 zip_proc.terminate() 664 zip_proc.terminate()
635 if self._IsOnlineImpl(): 665 if self._IsOnlineImpl():
636 self._RunShellCommandImpl(['rm', zip_on_device]) 666 self._RunShellCommandImpl(['rm', zip_on_device])
637 667
638 def _InstallCommands(self):
639 if not self._commands_installed and not install_commands.Installed(self):
640 install_commands.InstallCommands(self)
641 self._commands_installed = True
642
643 @staticmethod 668 @staticmethod
644 def _CreateDeviceZip(zip_path, host_device_tuples): 669 def _CreateDeviceZip(zip_path, host_device_tuples):
645 with zipfile.ZipFile(zip_path, 'w') as zip_file: 670 with zipfile.ZipFile(zip_path, 'w') as zip_file:
646 for host_path, device_path in host_device_tuples: 671 for host_path, device_path in host_device_tuples:
647 if os.path.isfile(host_path): 672 if os.path.isfile(host_path):
648 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED) 673 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED)
649 else: 674 else:
650 for hd, _, files in os.walk(host_path): 675 for hd, _, files in os.walk(host_path):
651 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd)) 676 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd))
652 zip_file.write(hd, dd, zipfile.ZIP_STORED) 677 zip_file.write(hd, dd, zipfile.ZIP_STORED)
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 the device. 849 the device.
825 timeout: timeout in seconds 850 timeout: timeout in seconds
826 retries: number of retries 851 retries: number of retries
827 852
828 Returns: 853 Returns:
829 The value of the device's |property_name| property. 854 The value of the device's |property_name| property.
830 855
831 Raises: 856 Raises:
832 CommandTimeoutError on timeout. 857 CommandTimeoutError on timeout.
833 """ 858 """
859 return self._GetPropImpl(property_name)
860
861 def _GetPropImpl(self, property_name):
834 return self.old_interface.system_properties[property_name] 862 return self.old_interface.system_properties[property_name]
835 863
836 @decorators.WithTimeoutAndRetriesFromInstance() 864 @decorators.WithTimeoutAndRetriesFromInstance()
837 def SetProp(self, property_name, value, timeout=None, retries=None): 865 def SetProp(self, property_name, value, timeout=None, retries=None):
838 """Sets a property on the device. 866 """Sets a property on the device.
839 867
840 Args: 868 Args:
841 property_name: A string containing the name of the property to set on 869 property_name: A string containing the name of the property to set on
842 the device. 870 the device.
843 value: A string containing the value to set to the property on the 871 value: A string containing the value to set to the property on the
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 A Parallelizer operating over |devices|. 993 A Parallelizer operating over |devices|.
966 """ 994 """
967 if not devices or len(devices) == 0: 995 if not devices or len(devices) == 0:
968 devices = pylib.android_commands.GetAttachedDevices() 996 devices = pylib.android_commands.GetAttachedDevices()
969 parallelizer_type = (parallelizer.Parallelizer if async 997 parallelizer_type = (parallelizer.Parallelizer if async
970 else parallelizer.SyncParallelizer) 998 else parallelizer.SyncParallelizer)
971 return parallelizer_type([ 999 return parallelizer_type([
972 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 1000 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
973 for d in devices]) 1001 for d in devices])
974 1002
OLDNEW
« no previous file with comments | « build/android/pylib/device/commands/install_commands.py ('k') | build/android/pylib/device/device_utils_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698