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

Side by Side Diff: sky/tools/shelldb

Issue 955263004: Make shelldb not crash. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | sky/tools/skypy/skyserver.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env 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 from skypy.skyserver import SkyServer 6 from skypy.skyserver import SkyServer
7 import argparse 7 import argparse
8 import json 8 import json
9 import logging 9 import logging
10 import os 10 import os
11 import subprocess 11 import subprocess
12 import sys 12 import sys
13 import urllib
14 import urlparse 13 import urlparse
15 14
16 SKY_TOOLS_DIR = os.path.dirname(__file__) 15 SKY_TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
17 SKY_ROOT = os.path.dirname(SKY_TOOLS_DIR) 16 SKY_ROOT = os.path.dirname(SKY_TOOLS_DIR)
18 SRC_ROOT = os.path.dirname(SKY_ROOT) 17 SRC_ROOT = os.path.dirname(SKY_ROOT)
19 18
20 SKY_SERVER_PORT = 9888 19 SKY_SERVER_PORT = 9888
21 DEFAULT_URL = "sky://domokit.github.io/home" 20 DEFAULT_URL = "sky://domokit.github.io/home"
22 APK_NAME = 'SkyDemo.apk' 21 APK_NAME = 'SkyDemo.apk'
23 ADB_PATH = os.path.join(SRC_ROOT, 22 ADB_PATH = os.path.join(SRC_ROOT,
24 'third_party/android_tools/sdk/platform-tools/adb') 23 'third_party/android_tools/sdk/platform-tools/adb')
25 24
26 25
27 PID_FILE_PATH = "/tmp/skydemo.pids" 26 PID_FILE_PATH = "/tmp/skydemo.pids"
28 PID_FILE_KEYS = frozenset([ 27 PID_FILE_KEYS = frozenset([
29 'remote_sky_server_port', 28 'remote_sky_server_port',
30 'sky_server_pid', 29 'sky_server_pid',
31 'sky_server_port', 30 'sky_server_port',
32 'sky_server_root', 31 'sky_server_root',
33 'build_dir', 32 'build_dir',
34 ]) 33 ])
35 34
36 # This 'strict dictionary' approach is useful for catching typos. 35 # This 'strict dictionary' approach is useful for catching typos.
37 class Pids(object): 36 class Pids(object):
38 def __init__(self, known_keys, contents=None): 37 def __init__(self, known_keys, contents=None):
39 self._known_keys = known_keys 38 self._known_keys = known_keys
40 self._dict = contents if contents is not None else {} 39 self._dict = contents if contents is not None else {}
41 40
42 def __len__(self): 41 def __len__(self):
43 return len(self._dict) 42 return len(self._dict)
44 43
44 def get(self, key, default=None):
45 assert key in self._known_keys, '%s not in known_keys' % key
46 return self._dict.get(key, default)
47
45 def __getitem__(self, key): 48 def __getitem__(self, key):
46 assert key in self._known_keys, '%s not in known_keys' % key 49 assert key in self._known_keys, '%s not in known_keys' % key
47 return self._dict[key] 50 return self._dict[key]
48 51
49 def __setitem__(self, key, value): 52 def __setitem__(self, key, value):
50 assert key in self._known_keys, '%s not in known_keys' % key 53 assert key in self._known_keys, '%s not in known_keys' % key
51 self._dict[key] = value 54 self._dict[key] = value
52 55
53 def __delitem__(self, key): 56 def __delitem__(self, key):
54 assert key in self._known_keys, '%s not in known_keys' % key 57 assert key in self._known_keys, '%s not in known_keys' % key
55 del self._dict[key] 58 del self._dict[key]
56 59
57 def __iter__(self): 60 def __iter__(self):
58 return iter(self._dict) 61 return iter(self._dict)
59 62
60 def __contains__(self, key): 63 def __contains__(self, key):
61 assert key in self._known_keys, '%s not in allowed_keys' % key 64 assert key in self._known_keys, '%s not in allowed_keys' % key
62 return key in self._dict 65 return key in self._dict
63 66
64 def clear(): 67 def clear(self):
65 self._dict = {} 68 self._dict = {}
66 69
67 @classmethod 70 @classmethod
68 def read_from(cls, path, known_keys): 71 def read_from(cls, path, known_keys):
69 contents = {} 72 contents = {}
70 try: 73 try:
71 with open(path, 'r') as pid_file: 74 with open(path, 'r') as pid_file:
72 contents = json.load(pid_file) 75 contents = json.load(pid_file)
73 except: 76 except:
74 if os.path.exists(path): 77 if os.path.exists(path):
75 logging.warn('Failed to read pid file: %s' % path) 78 logging.warn('Failed to read pid file: %s' % path)
76 return cls(known_keys, contents) 79 return cls(known_keys, contents)
77 80
78 def write_to(self, path): 81 def write_to(self, path):
79 try: 82 try:
80 with open(path, 'w') as pid_file: 83 with open(path, 'w') as pid_file:
81 json.dump(self._dict, pid_file, indent=2, sort_keys=True) 84 json.dump(self._dict, pid_file, indent=2, sort_keys=True)
82 except: 85 except:
83 logging.warn('Failed to write pid file: %s' % path) 86 logging.warn('Failed to write pid file: %s' % path)
84 87
85 88
86 def _convert_to_sky_url(url): 89 def _convert_to_sky_url(url):
87 result = urllib.parse.urlsplit(url) 90 parts = urlparse.urlsplit(url)
88 result.scheme = 'sky' 91 parts = parts._replace(scheme='sky')
89 return urllib.parse.urlunsplit(result) 92 return parts.geturl()
90 93
91 94
92 # A free function for possible future sharing with a 'load' command. 95 # A free function for possible future sharing with a 'load' command.
93 def _url_from_args(args): 96 def _url_from_args(args, pids):
94 if urlparse.urlparse(args.url_or_path).scheme: 97 if urlparse.urlparse(args.url_or_path).scheme:
95 return args.url_or_path 98 return args.url_or_path
96 # The load happens on the remote device, use the remote port. 99 # The load happens on the remote device, use the remote port.
97 remote_sky_server_port = self.pids.get('remote_sky_server_port', 100 remote_sky_server_port = pids.get('remote_sky_server_port',
98 self.pids['sky_server_port']) 101 pids['sky_server_port'])
99 url = SkyServer.url_for_path(remote_sky_server_port, 102 url = SkyServer.url_for_path(remote_sky_server_port,
100 self.pids['sky_server_root'], args.url_or_path) 103 pids['sky_server_root'], args.url_or_path)
101 return _convert_to_sky_url(url) 104 return _convert_to_sky_url(url)
102 105
103 106
104 class StartSky(object): 107 class StartSky(object):
105 def add_subparser(self, subparsers): 108 def add_subparser(self, subparsers):
106 start_parser = subparsers.add_parser('start', 109 start_parser = subparsers.add_parser('start',
107 help='launch SKyShell.apk on the device') 110 help='launch SKyShell.apk on the device')
108 start_parser.add_argument('build_dir', type=str) 111 start_parser.add_argument('build_dir', type=str)
109 start_parser.add_argument('url_or_path', nargs='?', type=str, 112 start_parser.add_argument('url_or_path', nargs='?', type=str,
110 default=DEFAULT_URL) 113 default=DEFAULT_URL)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 149
147 port_string = 'tcp:%s' % sky_server.port 150 port_string = 'tcp:%s' % sky_server.port
148 subprocess.check_call([ 151 subprocess.check_call([
149 ADB_PATH, 'reverse', port_string, port_string 152 ADB_PATH, 'reverse', port_string, port_string
150 ]) 153 ])
151 pids['remote_sky_server_port'] = sky_server.port 154 pids['remote_sky_server_port'] = sky_server.port
152 155
153 subprocess.check_call([ADB_PATH, 'shell', 156 subprocess.check_call([ADB_PATH, 'shell',
154 'am', 'start', 157 'am', 'start',
155 '-a', 'android.intent.action.VIEW', 158 '-a', 'android.intent.action.VIEW',
156 '-d', _url_from_args(args)]) 159 '-d', _url_from_args(args, pids)])
157 160
158 161
159 class StopSky(object): 162 class StopSky(object):
160 def add_subparser(self, subparsers): 163 def add_subparser(self, subparsers):
161 stop_parser = subparsers.add_parser('stop', 164 stop_parser = subparsers.add_parser('stop',
162 help=('kill all running SkyShell.apk processes')) 165 help=('kill all running SkyShell.apk processes'))
163 stop_parser.set_defaults(func=self.run) 166 stop_parser.set_defaults(func=self.run)
164 167
165 def _kill_if_exists(self, pids, key, name): 168 def _kill_if_exists(self, pids, key, name):
166 pid = pids.pop(key, None) 169 pid = pids.pop(key, None)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 args = parser.parse_args() 202 args = parser.parse_args()
200 pids = Pids.read_from(PID_FILE_PATH, PID_FILE_KEYS) 203 pids = Pids.read_from(PID_FILE_PATH, PID_FILE_KEYS)
201 exit_code = args.func(args, pids) 204 exit_code = args.func(args, pids)
202 # We could do this with an at-exit handler instead? 205 # We could do this with an at-exit handler instead?
203 pids.write_to(PID_FILE_PATH) 206 pids.write_to(PID_FILE_PATH)
204 sys.exit(exit_code) 207 sys.exit(exit_code)
205 208
206 209
207 if __name__ == '__main__': 210 if __name__ == '__main__':
208 SkyShellRunner().main() 211 SkyShellRunner().main()
OLDNEW
« no previous file with comments | « no previous file | sky/tools/skypy/skyserver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698