OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Utility for reading / writing command-line flag files on device(s).""" | 6 """Utility for reading / writing command-line flag files on device(s).""" |
7 | 7 |
8 import argparse | 8 import argparse |
9 import os | 9 import os |
| 10 import posixpath |
10 import sys | 11 import sys |
11 | 12 |
12 import devil_chromium | 13 import devil_chromium |
13 | 14 |
14 from devil.android import device_utils | 15 from devil.android import device_utils |
15 from devil.android import device_errors | 16 from devil.android import flag_changer |
16 from devil.utils import cmd_helper | 17 from devil.utils import cmd_helper |
17 | 18 |
18 | 19 |
19 def main(): | 20 def main(): |
20 parser = argparse.ArgumentParser(description=__doc__) | 21 parser = argparse.ArgumentParser(description=__doc__) |
21 parser.usage = '''%(prog)s --device-path PATH [--device SERIAL] [flags...] | 22 parser.usage = '''%(prog)s --name FILENAME [--device SERIAL] [flags...] |
22 | 23 |
23 No flags: Prints existing command-line file. | 24 No flags: Prints existing command-line file. |
24 Empty string: Deletes command-line file. | 25 Empty string: Deletes command-line file. |
25 Otherwise: Writes command-line file. | 26 Otherwise: Writes command-line file. |
26 | 27 |
27 ''' | 28 ''' |
28 parser.add_argument('-d', '--device', dest='devices', action='append', | 29 parser.add_argument('-d', '--device', dest='devices', action='append', |
29 default=[], help='Target device serial (repeatable).') | 30 default=[], help='Target device serial (repeatable).') |
30 parser.add_argument('--device-path', required=True, | 31 parser.add_argument('--name', required=True, |
31 help='Remote path to flags file.') | 32 help='Name of file where to store flags on the device.') |
| 33 parser.add_argument('--device-path', help='(deprecated) No longer needed to' |
| 34 ' supply a device path.') |
32 parser.add_argument('-e', '--executable', dest='executable', default='chrome', | 35 parser.add_argument('-e', '--executable', dest='executable', default='chrome', |
33 help='Name of the executable.') | 36 help='(deprecated) No longer used.') |
34 parser.add_argument('--adb-path', type=os.path.abspath, | 37 parser.add_argument('--adb-path', type=os.path.abspath, |
35 help='Path to the adb binary.') | 38 help='Path to the adb binary.') |
36 args, remote_args = parser.parse_known_args() | 39 args, remote_args = parser.parse_known_args() |
37 | 40 |
| 41 if args.device_path: |
| 42 args.name = posixpath.basename(args.device_path) |
| 43 print ('warning: --device-path option is deprecated,' |
| 44 ' --name %s is now enough.' |
| 45 % cmd_helper.SingleQuote(args.name)) |
| 46 |
38 devil_chromium.Initialize(adb_path=args.adb_path) | 47 devil_chromium.Initialize(adb_path=args.adb_path) |
39 | 48 |
40 as_root = not args.device_path.startswith('/data/local/tmp/') | |
41 | |
42 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices, | 49 devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices, |
43 default_retries=0) | 50 default_retries=0) |
44 all_devices = device_utils.DeviceUtils.parallel(devices) | 51 all_devices = device_utils.DeviceUtils.parallel(devices) |
45 | 52 |
46 def print_args(): | 53 if not remote_args: |
47 def read_flags(device): | 54 # No args == do not update, just print flags. |
48 try: | 55 remote_args = None |
49 return device.ReadFile(args.device_path, as_root=as_root).rstrip() | 56 action = '' |
50 except device_errors.CommandFailedError: | 57 elif len(remote_args) == 1 and not remote_args[0]: |
51 return '' # File might not exist. | 58 # Single empty string arg == delete flags |
| 59 remote_args = [] |
| 60 action = 'Deleted command line file. ' |
| 61 else: |
| 62 action = 'Wrote command line file. ' |
52 | 63 |
53 descriptions = all_devices.pMap(lambda d: d.build_description).pGet(None) | 64 def update_flags(device): |
54 flags = all_devices.pMap(read_flags).pGet(None) | 65 changer = flag_changer.FlagChanger(device, args.name) |
55 for d, desc, flags in zip(devices, descriptions, flags): | 66 if remote_args is not None: |
56 print ' %s (%s): %r' % (d, desc, flags) | 67 flags = changer.ReplaceFlags(remote_args) |
| 68 else: |
| 69 flags = changer.GetCurrentFlags() |
| 70 return (device, device.build_description, flags) |
57 | 71 |
58 # No args == print flags. | 72 updated_values = all_devices.pMap(update_flags).pGet(None) |
59 if not remote_args: | |
60 print 'Existing flags (in %s):' % args.device_path | |
61 print_args() | |
62 return 0 | |
63 | 73 |
64 # Empty string arg == delete flags file. | 74 print '%sCurrent flags (in %s):' % (action, args.name) |
65 if len(remote_args) == 1 and not remote_args[0]: | 75 for d, desc, flags in updated_values: |
66 def delete_flags(device): | 76 if flags: |
67 device.RunShellCommand(['rm', '-f', args.device_path], as_root=as_root) | 77 # Shell-quote flags for easy copy/paste as new args on the terminal. |
68 all_devices.pMap(delete_flags).pGet(None) | 78 quoted_flags = ' '.join(cmd_helper.SingleQuote(f) for f in sorted(flags)) |
69 print 'Deleted %s' % args.device_path | 79 else: |
70 return 0 | 80 quoted_flags = '( empty )' |
| 81 print ' %s (%s): %s' % (d, desc, quoted_flags) |
71 | 82 |
72 # Set flags. | |
73 quoted_args = ' '.join(cmd_helper.SingleQuote(x) for x in remote_args) | |
74 flags_str = ' '.join([args.executable, quoted_args]) | |
75 | |
76 def write_flags(device): | |
77 device.WriteFile(args.device_path, flags_str, as_root=as_root) | |
78 device.RunShellCommand(['chmod', '0664', args.device_path], as_root=as_root) | |
79 | |
80 all_devices.pMap(write_flags).pGet(None) | |
81 print 'Wrote flags to %s' % args.device_path | |
82 print_args() | |
83 return 0 | 83 return 0 |
84 | 84 |
85 | 85 |
86 if __name__ == '__main__': | 86 if __name__ == '__main__': |
87 sys.exit(main()) | 87 sys.exit(main()) |
OLD | NEW |