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

Side by Side Diff: mojo/tools/mopy/android.py

Issue 1138933004: Fix apptest builds and runner on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make PrepareShellRun only serve with origin=='localhost'; cleanup. Created 5 years, 7 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 | « mojo/tools/apptest_runner.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 import atexit 5 import atexit
6 import datetime 6 import datetime
7 import email.utils 7 import email.utils
8 import hashlib 8 import hashlib
9 import itertools 9 import itertools
10 import json 10 import json
(...skipping 19 matching lines...) Expand all
30 'MojoMain', 30 'MojoMain',
31 'MojoShellActivity', 31 'MojoShellActivity',
32 'MojoShellApplication', 32 'MojoShellApplication',
33 'chromium', 33 'chromium',
34 ] 34 ]
35 35
36 MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell' 36 MOJO_SHELL_PACKAGE_NAME = 'org.chromium.mojo.shell'
37 37
38 MAPPING_PREFIX = '--map-origin=' 38 MAPPING_PREFIX = '--map-origin='
39 39
40 DEFAULT_BASE_PORT = 31337
41
42 ZERO = datetime.timedelta(0) 40 ZERO = datetime.timedelta(0)
43 41
44 class UTC_TZINFO(datetime.tzinfo): 42 class UTC_TZINFO(datetime.tzinfo):
45 """UTC time zone representation.""" 43 """UTC time zone representation."""
46 44
47 def utcoffset(self, _): 45 def utcoffset(self, _):
48 return ZERO 46 return ZERO
49 47
50 def tzname(self, _): 48 def tzname(self, _):
51 return "UTC" 49 return "UTC"
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 263
266 def _UnmapPort(): 264 def _UnmapPort():
267 subprocess.Popen(unmap_command) 265 subprocess.Popen(unmap_command)
268 atexit.register(_UnmapPort) 266 atexit.register(_UnmapPort)
269 return device_port 267 return device_port
270 268
271 def _StartHttpServerForDirectory(self, path, port=0): 269 def _StartHttpServerForDirectory(self, path, port=0):
272 """Starts an http server serving files from |path|. Returns the local 270 """Starts an http server serving files from |path|. Returns the local
273 url.""" 271 url."""
274 assert path 272 assert path
275 print 'starting http for', path
276 httpd = _SilentTCPServer(('127.0.0.1', 0), _GetHandlerClassForPath(path)) 273 httpd = _SilentTCPServer(('127.0.0.1', 0), _GetHandlerClassForPath(path))
277 atexit.register(httpd.shutdown) 274 atexit.register(httpd.shutdown)
278 275
279 http_thread = threading.Thread(target=httpd.serve_forever) 276 http_thread = threading.Thread(target=httpd.serve_forever)
280 http_thread.daemon = True 277 http_thread.daemon = True
281 http_thread.start() 278 http_thread.start()
282 279
283 print 'local port=%d' % httpd.server_address[1] 280 print 'Hosting %s at http://127.0.0.1:%d' % (path, httpd.server_address[1])
284 return 'http://127.0.0.1:%d/' % self._MapPort(port, httpd.server_address[1]) 281 return 'http://127.0.0.1:%d/' % self._MapPort(port, httpd.server_address[1])
285 282
286 def _StartHttpServerForOriginMapping(self, mapping, port): 283 def _StartHttpServerForOriginMapping(self, mapping, port):
287 """If |mapping| points at a local file starts an http server to serve files 284 """If |mapping| points at a local file starts an http server to serve files
288 from the directory and returns the new mapping. 285 from the directory and returns the new mapping.
289 286
290 This is intended to be called for every --map-origin value.""" 287 This is intended to be called for every --map-origin value."""
291 parts = mapping.split('=') 288 parts = mapping.split('=')
292 if len(parts) != 2: 289 if len(parts) != 2:
293 return mapping 290 return mapping
294 dest = parts[1] 291 dest = parts[1]
295 # If the destination is a url, don't map it. 292 # If the destination is a url, don't map it.
296 if urlparse.urlparse(dest)[0]: 293 if urlparse.urlparse(dest)[0]:
297 return mapping 294 return mapping
298 # Assume the destination is a local file. Start a local server that 295 # Assume the destination is a local file. Start a local server that
299 # redirects to it. 296 # redirects to it.
300 localUrl = self._StartHttpServerForDirectory(dest, port) 297 localUrl = self._StartHttpServerForDirectory(dest, port)
301 print 'started server at %s for %s' % (dest, localUrl) 298 print 'started server at %s for %s' % (dest, localUrl)
302 return parts[0] + '=' + localUrl 299 return parts[0] + '=' + localUrl
303 300
304 def _StartHttpServerForOriginMappings(self, map_parameters, fixed_port): 301 def _StartHttpServerForOriginMappings(self, map_parameters):
305 """Calls _StartHttpServerForOriginMapping for every --map-origin 302 """Calls _StartHttpServerForOriginMapping for every --map-origin
306 argument.""" 303 argument."""
307 if not map_parameters: 304 if not map_parameters:
308 return [] 305 return []
309 306
310 original_values = list(itertools.chain( 307 original_values = list(itertools.chain(
311 *map(lambda x: x[len(MAPPING_PREFIX):].split(','), map_parameters))) 308 *map(lambda x: x[len(MAPPING_PREFIX):].split(','), map_parameters)))
312 sorted(original_values) 309 sorted(original_values)
313 result = [] 310 result = []
314 for i, value in enumerate(original_values): 311 for value in original_values:
315 result.append(self._StartHttpServerForOriginMapping( 312 result.append(self._StartHttpServerForOriginMapping(value, 0))
316 value, DEFAULT_BASE_PORT + 1 + i if fixed_port else 0))
317 return [MAPPING_PREFIX + ','.join(result)] 313 return [MAPPING_PREFIX + ','.join(result)]
318 314
319 def PrepareShellRun(self, origin=None, fixed_port=True): 315 def PrepareShellRun(self, origin=None):
320 """ Prepares for StartShell: runs adb as root and installs the apk. If no 316 """ Prepares for StartShell: runs adb as root and installs the apk. If the
321 --origin is specified, local http server will be set up to serve files from 317 origin specified is 'localhost', a local http server will be set up to serve
322 the build directory along with port forwarding. 318 files from the build directory along with port forwarding.
323 319
324 Returns arguments that should be appended to shell argument list.""" 320 Returns arguments that should be appended to shell argument list."""
325 if 'cannot run as root' in subprocess.check_output( 321 if 'cannot run as root' in subprocess.check_output(
326 self._CreateADBCommand(['root'])): 322 self._CreateADBCommand(['root'])):
327 raise Exception("Unable to run adb as root.") 323 raise Exception("Unable to run adb as root.")
328 subprocess.check_call( 324 subprocess.check_call(
329 self._CreateADBCommand(['install', '-r', self.shell_apk_path, '-i', 325 self._CreateADBCommand(['install', '-r', self.shell_apk_path, '-i',
330 self.target_package])) 326 self.target_package]))
331 atexit.register(self.StopShell) 327 atexit.register(self.StopShell)
332 328
333 extra_shell_args = [] 329 extra_shell_args = []
330 if origin is 'localhost':
331 origin = self._StartHttpServerForDirectory(self.local_dir, 0)
334 if origin: 332 if origin:
335 origin_url = origin if origin else self._StartHttpServerForDirectory( 333 extra_shell_args.append("--origin=" + origin)
336 self.local_dir, DEFAULT_BASE_PORT if fixed_port else 0)
337 extra_shell_args.append("--origin=" + origin_url)
338
339 return extra_shell_args 334 return extra_shell_args
340 335
341 def StartShell(self, 336 def StartShell(self,
342 arguments, 337 arguments,
343 stdout=None, 338 stdout=None,
344 on_application_stop=None, 339 on_application_stop=None):
345 fixed_port=True):
346 """ 340 """
347 Starts the mojo shell, passing it the given arguments. 341 Starts the mojo shell, passing it the given arguments.
348 342
349 The |arguments| list must contain the "--origin=" arg from PrepareShellRun. 343 The |arguments| list must contain the "--origin=" arg from PrepareShellRun.
350 If |stdout| is not None, it should be a valid argument for subprocess.Popen. 344 If |stdout| is not None, it should be a valid argument for subprocess.Popen.
351 """ 345 """
352 STDOUT_PIPE = "/data/data/%s/stdout.fifo" % self.target_package 346 STDOUT_PIPE = "/data/data/%s/stdout.fifo" % self.target_package
353 347
354 cmd = self._CreateADBCommand([ 348 cmd = self._CreateADBCommand([
355 'shell', 349 'shell',
356 'am', 350 'am',
357 'start', 351 'start',
358 '-S', 352 '-S',
359 '-a', 'android.intent.action.VIEW', 353 '-a', 'android.intent.action.VIEW',
360 '-n', '%s/%s.MojoShellActivity' % (self.target_package, 354 '-n', '%s/%s.MojoShellActivity' % (self.target_package,
361 MOJO_SHELL_PACKAGE_NAME)]) 355 MOJO_SHELL_PACKAGE_NAME)])
362 356
363 parameters = [] 357 parameters = []
364 if stdout or on_application_stop: 358 if stdout or on_application_stop:
365 subprocess.check_call(self._CreateADBCommand( 359 subprocess.check_call(self._CreateADBCommand(
366 ['shell', 'rm', '-f', STDOUT_PIPE])) 360 ['shell', 'rm', '-f', STDOUT_PIPE]))
367 parameters.append('--fifo-path=%s' % STDOUT_PIPE) 361 parameters.append('--fifo-path=%s' % STDOUT_PIPE)
368 self._ReadFifo(STDOUT_PIPE, stdout, on_application_stop) 362 self._ReadFifo(STDOUT_PIPE, stdout, on_application_stop)
369 363
370 # Extract map-origin arguments. 364 # Extract map-origin arguments.
371 map_parameters, other_parameters = _Split(arguments, _IsMapOrigin) 365 map_parameters, other_parameters = _Split(arguments, _IsMapOrigin)
372 parameters += other_parameters 366 parameters += other_parameters
373 parameters += self._StartHttpServerForOriginMappings(map_parameters, 367 parameters += self._StartHttpServerForOriginMappings(map_parameters)
374 fixed_port)
375 368
376 if parameters: 369 if parameters:
377 encodedParameters = json.dumps(parameters) 370 encodedParameters = json.dumps(parameters)
378 cmd += ['--es', 'encodedParameters', encodedParameters] 371 cmd += ['--es', 'encodedParameters', encodedParameters]
379 372
380 with open(os.devnull, 'w') as devnull: 373 with open(os.devnull, 'w') as devnull:
381 subprocess.Popen(cmd, stdout=devnull).wait() 374 subprocess.Popen(cmd, stdout=devnull).wait()
382 375
383 def StopShell(self): 376 def StopShell(self):
384 """ 377 """
(...skipping 16 matching lines...) Expand all
401 394
402 Returns the process responsible for reading the logs. 395 Returns the process responsible for reading the logs.
403 """ 396 """
404 logcat = subprocess.Popen(self._CreateADBCommand([ 397 logcat = subprocess.Popen(self._CreateADBCommand([
405 'logcat', 398 'logcat',
406 '-s', 399 '-s',
407 ' '.join(LOGCAT_TAGS)]), 400 ' '.join(LOGCAT_TAGS)]),
408 stdout=sys.stdout) 401 stdout=sys.stdout)
409 atexit.register(_ExitIfNeeded, logcat) 402 atexit.register(_ExitIfNeeded, logcat)
410 return logcat 403 return logcat
OLDNEW
« no previous file with comments | « mojo/tools/apptest_runner.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698