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

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

Issue 715853002: Migrate device utils WriteFile to AdbWrapper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed edge cases Created 6 years, 1 month 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 logging
12 import multiprocessing 12 import multiprocessing
13 import os 13 import os
14 import re 14 import re
15 import sys 15 import sys
16 import tempfile 16 import tempfile
17 import time 17 import time
18 import zipfile 18 import zipfile
19 19
20 import pylib.android_commands 20 import pylib.android_commands
21 from pylib import cmd_helper 21 from pylib import cmd_helper
22 from pylib.device import adb_wrapper 22 from pylib.device import adb_wrapper
23 from pylib.device import decorators 23 from pylib.device import decorators
24 from pylib.device import device_errors 24 from pylib.device import device_errors
25 from pylib.device.commands import install_commands 25 from pylib.device.commands import install_commands
26 from pylib.utils import apk_helper 26 from pylib.utils import apk_helper
27 from pylib.utils import device_temp_file
27 from pylib.utils import host_utils 28 from pylib.utils import host_utils
28 from pylib.utils import parallelizer 29 from pylib.utils import parallelizer
29 from pylib.utils import timeout_retry 30 from pylib.utils import timeout_retry
30 31
31 _DEFAULT_TIMEOUT = 30 32 _DEFAULT_TIMEOUT = 30
32 _DEFAULT_RETRIES = 3 33 _DEFAULT_RETRIES = 3
33 34
34 35
35 @decorators.WithExplicitTimeoutAndRetries( 36 @decorators.WithExplicitTimeoutAndRetries(
36 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) 37 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 # the implementation switch, and if file not found should raise exception. 860 # the implementation switch, and if file not found should raise exception.
860 if as_root: 861 if as_root:
861 if not self.old_interface.CanAccessProtectedFileContents(): 862 if not self.old_interface.CanAccessProtectedFileContents():
862 raise device_errors.CommandFailedError( 863 raise device_errors.CommandFailedError(
863 'Cannot read from %s with root privileges.' % device_path) 864 'Cannot read from %s with root privileges.' % device_path)
864 return self.old_interface.GetProtectedFileContents(device_path) 865 return self.old_interface.GetProtectedFileContents(device_path)
865 else: 866 else:
866 return self.old_interface.GetFileContents(device_path) 867 return self.old_interface.GetFileContents(device_path)
867 868
868 @decorators.WithTimeoutAndRetriesFromInstance() 869 @decorators.WithTimeoutAndRetriesFromInstance()
869 def WriteFile(self, device_path, contents, as_root=False, timeout=None, 870 def WriteFile(self, device_path, contents, as_root=False, force_push=False,
870 retries=None): 871 timeout=None, retries=None):
871 """Writes |contents| to a file on the device. 872 """Writes |contents| to a file on the device.
872 873
873 Args: 874 Args:
874 device_path: A string containing the absolute path to the file to write 875 device_path: A string containing the absolute path to the file to write
875 on the device. 876 on the device.
876 contents: A string containing the data to write to the device. 877 contents: A string containing the data to write to the device.
877 as_root: A boolean indicating whether the write should be executed with 878 as_root: A boolean indicating whether the write should be executed with
878 root privileges. 879 root privileges (if available).
880 force_push: A boolean indicating whether to force the operation to be
Sami 2014/11/12 14:14:14 Is force_push needed by anything other than tests?
perezju 2014/11/12 17:37:03 Well, yes, certainly it's useful for testing, but
881 performed by pushing a file to the device. The default is, when the
882 contents are short, to pass the contents using a shell script instead.
879 timeout: timeout in seconds 883 timeout: timeout in seconds
880 retries: number of retries 884 retries: number of retries
881 885
882 Raises: 886 Raises:
883 CommandFailedError if the file could not be written on the device. 887 CommandFailedError if the file could not be written on the device.
884 CommandTimeoutError on timeout. 888 CommandTimeoutError on timeout.
885 DeviceUnreachableError on missing device. 889 DeviceUnreachableError on missing device.
886 """ 890 """
887 if as_root: 891 if len(contents) < 512 and not force_push:
888 if not self.old_interface.CanAccessProtectedFileContents(): 892 # When as_root=True and su is needed, trying to execute
889 raise device_errors.CommandFailedError( 893 # su -c echo -n {contents} > {device_path}
890 'Cannot write to %s with root privileges.' % device_path) 894 # won't work, because echo is interpreted by the shell and not an actual
Sami 2014/11/12 14:14:14 nit: I presume it's not the echo that gets execute
perezju 2014/11/12 17:37:02 No. "su -c cmd > /some/file" works fine, because t
891 self.old_interface.SetProtectedFileContents(device_path, contents) 895 # command on the device. So instead we must make sure that in those cases
896 # the command to execute becomes:
897 # su -c sh -c 'echo -n {contents}' > {device_path}
898 cmd = 'echo -n %s' % cmd_helper.SingleQuote(contents)
899 sh_cmd = 'sh -c %s > %s' % (cmd_helper.SingleQuote(cmd),
900 cmd_helper.SingleQuote(device_path))
901 self.RunShellCommand(sh_cmd, as_root=as_root, check_return=True)
perezju 2014/11/12 01:31:24 Not sure why this never hit us before! Probably Wr
jbudorick 2014/11/12 01:42:37 Wow, nice catch. This is a nasty little corner cas
perezju 2014/11/12 17:37:03 Indeed, echo (and sometimes with as_root=True!) is
892 else: 902 else:
893 self.old_interface.SetFileContents(device_path, contents) 903 with tempfile.NamedTemporaryFile() as host_temp:
894 904 host_temp.write(contents)
895 @decorators.WithTimeoutAndRetriesFromInstance() 905 host_temp.flush()
896 def WriteTextFile(self, device_path, text, as_root=False, timeout=None, 906 if as_root and self.NeedsSU():
897 retries=None): 907 with device_temp_file.DeviceTempFile(self) as device_temp:
898 """Writes |text| to a file on the device. 908 self.adb.Push(host_temp.name, device_temp.name)
899 909 # Here we need 'cp' rather than 'mv' because the temp and
900 Assuming that |text| is a small string, this is typically more efficient 910 # destination files might be on different file systems (e.g.
901 than |WriteFile|, as no files are pushed into the device. 911 # on internal storage and an external sd card)
902 912 self.RunShellCommand(['cp', device_temp.name, device_path],
903 Args: 913 as_root=True, check_return=True)
perezju 2014/11/12 01:31:24 So, I had to resort to 'cp' rather than 'mv' in th
jbudorick 2014/11/12 01:42:37 While I think we should try to move away from usin
904 device_path: A string containing the absolute path to the file to write 914 else:
905 on the device. 915 self.adb.Push(host_temp.name, device_path)
906 text: A short string of text to write to the file on the device.
907 as_root: A boolean indicating whether the write should be executed with
908 root privileges.
909 timeout: timeout in seconds
910 retries: number of retries
911
912 Raises:
913 CommandFailedError if the file could not be written on the device.
914 CommandTimeoutError on timeout.
915 DeviceUnreachableError on missing device.
916 """
917 cmd = 'echo %s > %s' % (cmd_helper.SingleQuote(text),
918 cmd_helper.SingleQuote(device_path))
919 self.RunShellCommand(cmd, as_root=as_root, check_return=True)
920 916
921 @decorators.WithTimeoutAndRetriesFromInstance() 917 @decorators.WithTimeoutAndRetriesFromInstance()
922 def Ls(self, device_path, timeout=None, retries=None): 918 def Ls(self, device_path, timeout=None, retries=None):
923 """Lists the contents of a directory on the device. 919 """Lists the contents of a directory on the device.
924 920
925 Args: 921 Args:
926 device_path: A string containing the path of the directory on the device 922 device_path: A string containing the path of the directory on the device
927 to list. 923 to list.
928 timeout: timeout in seconds 924 timeout: timeout in seconds
929 retries: number of retries 925 retries: number of retries
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 Returns: 1146 Returns:
1151 A Parallelizer operating over |devices|. 1147 A Parallelizer operating over |devices|.
1152 """ 1148 """
1153 if not devices or len(devices) == 0: 1149 if not devices or len(devices) == 0:
1154 devices = pylib.android_commands.GetAttachedDevices() 1150 devices = pylib.android_commands.GetAttachedDevices()
1155 parallelizer_type = (parallelizer.Parallelizer if async 1151 parallelizer_type = (parallelizer.Parallelizer if async
1156 else parallelizer.SyncParallelizer) 1152 else parallelizer.SyncParallelizer)
1157 return parallelizer_type([ 1153 return parallelizer_type([
1158 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 1154 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
1159 for d in devices]) 1155 for d in devices])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698