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

Unified Diff: sky/tools/skydb

Issue 816693006: Fix skydb to work for android (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« sky/tools/debugger/prompt/prompt.cc ('K') | « sky/tools/debugger/prompt/prompt.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/tools/skydb
diff --git a/sky/tools/skydb b/sky/tools/skydb
index a84db8782d5ab21627ccbd25ba1d37ab7c162f2d..ff906784fa7b2396051e73ed64664dafc4d62012 100755
--- a/sky/tools/skydb
+++ b/sky/tools/skydb
@@ -9,12 +9,18 @@ import argparse
import json
import logging
import os
+import pipes
import requests
import signal
-import skypy.configuration as configuration
import subprocess
-import urlparse
+import sys
import time
+import urlparse
+
+sys.path.insert(0, os.path.join(Paths('ignored').src_root, 'build', 'android'))
eseidel 2015/01/09 22:58:50 As I note in the description, we could *almost* re
+from pylib import android_commands
+from pylib import constants
+from pylib import forwarder
SUPPORTED_MIME_TYPES = [
@@ -29,6 +35,21 @@ PID_FILE_PATH = "/tmp/skydb.pids"
DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky"
+# FIXME: Move this into mopy.config
+def gn_args_from_build_dir(build_dir):
+ gn_cmd = [
+ 'gn', 'args',
+ build_dir,
+ '--list', '--short'
+ ]
+ config = {}
+ for line in subprocess.check_output(gn_cmd).strip().split('\n'):
+ # FIXME: This doesn't handle = in values.
+ key, value = line.split(' = ')
+ config[key] = value
+ return config
+
+
class SkyDebugger(object):
def __init__(self):
self.paths = None
@@ -48,48 +69,114 @@ class SkyDebugger(object):
def _in_chromoting(self):
return os.environ.get('CHROME_REMOTE_DESKTOP_SESSION', False)
- def _build_mojo_shell_command(self, args):
- self.paths = Paths(os.path.join('out', args.configuration))
+ def _wrap_for_android(self, shell_args):
+ build_dir_url = SkyServer.url_for_path(
+ self.pids['remote_sky_server_port'],
+ self.pids['sky_server_root'],
+ self.pids['build_dir'])
+ shell_args += ['--origin=%s' % build_dir_url]
+
+ # am shell --esa: (someone shoot me now)
+ # [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
+ # (to embed a comma into a string escape it using "\,")
+ escaped_args = map(lambda arg: arg.replace(',', '\\,'), shell_args)
+ return [
+ 'adb', 'shell',
+ 'am', 'start',
+ '-W',
+ '-S',
+ '-a', 'android.intent.action.VIEW',
+ '-n', 'org.chromium.mojo.shell/.MojoShellActivity',
+ # FIXME: This quoting is very error-prone. Perhaps we should read
+ # our args from a file instead?
+ '--esa', 'parameters', ','.join(escaped_args),
+ ]
+ def _build_mojo_shell_command(self, args):
content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer')
for mime_type in SUPPORTED_MIME_TYPES]
- shell_command = [
- self.paths.mojo_shell_path,
+
+ remote_command_port = self.pids.get('remote_sky_command_port', self.pids['sky_command_port'])
+
+ shell_args = [
'--v=1',
'--content-handlers=%s' % ','.join(content_handlers),
'--url-mappings=mojo:window_manager=mojo:sky_debugger',
- '--args-for=mojo:sky_debugger_prompt %d' % args.command_port,
+ '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port,
'mojo:window_manager',
]
+ # FIXME: This probably is wrong for android?
if args.use_osmesa:
- shell_command.append('--args-for=mojo:native_viewport_service --use-osmesa')
+ shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa')
+
+ if 'remote_sky_server_port' in self.pids:
+ shell_command = self._wrap_for_android(shell_args)
+ else:
+ shell_command = [self.paths.mojo_shell_path] + shell_args
+ # FIXME: This doesn't work for android
if args.gdb:
shell_command = ['gdb', '--args'] + shell_command
return shell_command
+ def _connect_to_device(self):
+ device = android_commands.AndroidCommands(
+ android_commands.GetAttachedDevices()[0])
+ device.EnableAdbRoot()
+ return device
+
+ def sky_server_for_args(self, args):
+ # FIXME: This is a hack. sky_server should just take a build_dir
+ # not a magical "configuration" name.
+ configuration = os.path.basename(os.path.normpath(args.build_dir))
+ server_root = self._server_root_for_url(args.url_or_path)
+ sky_server = SkyServer(self.paths, SKY_SERVER_PORT,
+ configuration, server_root)
+ return sky_server
+
def start_command(self, args):
- shell_command = self._build_mojo_shell_command(args)
- if args.show_command:
eseidel 2015/01/09 22:58:50 I removed support for --show-command. Sorry Hans.
- print " ".join(shell_command)
- return
+ # FIXME: Lame that we use self for a command-specific variable.
+ self.paths = Paths(args.build_dir)
self.stop_command(None) # Quit any existing process.
+ self.pids = {} # Clear out our pid file.
- print args.url_or_path
- # We only start a server for paths:
- if not urlparse.urlparse(args.url_or_path).scheme:
- server_root = self._server_root_for_url(args.url_or_path)
- sky_server = SkyServer(self.paths, SKY_SERVER_PORT,
- args.configuration, server_root)
- self.pids['sky_server_pid'] = sky_server.start()
- self.pids['sky_server_port'] = sky_server.port
- self.pids['sky_server_root'] = sky_server.root
+ # FIXME: This is probably not the right way to compute is_android
+ # from the build directory?
+ gn_args = gn_args_from_build_dir(args.build_dir)
+ is_android = 'android_sdk_version' in gn_args
- self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid
+ sky_server = self.sky_server_for_args(args)
+ self.pids['sky_server_pid'] = sky_server.start()
+ self.pids['sky_server_port'] = sky_server.port
+ self.pids['sky_server_root'] = sky_server.root
+
+ self.pids['build_dir'] = args.build_dir
self.pids['sky_command_port'] = args.command_port
+ if is_android:
+ # Pray to the build/android gods in their misspelled tongue.
+ constants.SetOutputDirectort(args.build_dir)
+
+ device = self._connect_to_device()
+ self.pids['device_serial'] = device.GetDevice()
+
+ forwarder.Forwarder.Map([(0, sky_server.port)], device)
+ device_http_port = forwarder.Forwarder.DevicePortForHostPort(
+ sky_server.port)
+ self.pids['remote_sky_server_port'] = device_http_port
+
+ port_string = 'tcp:%s' % args.command_port
+ subprocess.check_call([
+ 'adb', 'forward', port_string, port_string
+ ])
+ self.pids['remote_sky_command_port'] = args.command_port
+
+ shell_command = self._build_mojo_shell_command(args)
+ print ' '.join(map(pipes.quote, shell_command))
+ self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid
+
if not self._wait_for_sky_command_port():
logging.error('Failed to start sky')
self.stop_command(None)
@@ -108,14 +195,31 @@ class SkyDebugger(object):
logging.info('%s (%s) already gone.' % (name, pid))
def stop_command(self, args):
- # FIXME: Send /quit to sky prompt instead of killing.
- # self._send_command_to_sky('/quit')
+ try:
+ self._send_command_to_sky('/quit')
+ except:
+ pass
+ # Kill the mojo process for good measure. :)
self._kill_if_exists('mojo_shell_pid', 'mojo_shell')
+
self._kill_if_exists('sky_server_pid', 'sky_server')
+ # We could be much more surgical here:
+ if 'remote_sky_command_port' in self.pids:
+ device = android_commands.AndroidCommands(
+ self.pids['device_serial'])
+ forwarder.Forwarder.UnmapAllDevicePorts(device)
+
+ if 'remote_sky_command_port' in self.pids:
+ # adb forward --remove takes the *host* port, not the remote port.
+ port_string = 'tcp:%s' % self.pids['sky_command_port']
+ subprocess.call(['adb', 'forward', '--remove', port_string])
def load_command(self, args):
if not urlparse.urlparse(args.url_or_path).scheme:
- url = SkyServer.url_for_path(self.pids['sky_server_port'],
+ # The load happens on the remote device, use the remote port.
+ remote_sky_server_port = self.pids.get('remote_sky_server_port',
+ self.pids['sky_server_port'])
+ url = SkyServer.url_for_path(remote_sky_server_port,
self.pids['sky_server_root'], args.url_or_path)
else:
url = args.url_or_path
@@ -146,7 +250,7 @@ class SkyDebugger(object):
def _write_pid_file(self, path, pids):
try:
with open(path, 'w') as pid_file:
- json.dump(pids, pid_file)
+ json.dump(pids, pid_file, indent=2, sort_keys=True)
except:
logging.warn('Failed to write pid file: %s' % path)
@@ -172,6 +276,7 @@ class SkyDebugger(object):
def main(self):
logging.basicConfig(level=logging.INFO)
+ logging.getLogger("requests").setLevel(logging.WARNING)
self.pids = self._load_pid_file(PID_FILE_PATH)
@@ -180,12 +285,12 @@ class SkyDebugger(object):
start_parser = subparsers.add_parser('start',
help='launch a new mojo_shell with sky')
- configuration.add_arguments(start_parser)
start_parser.add_argument('--gdb', action='store_true')
start_parser.add_argument('--command-port', type=int,
default=DEFAULT_SKY_COMMAND_PORT)
start_parser.add_argument('--use-osmesa', action='store_true',
default=self._in_chromoting())
+ start_parser.add_argument('build_dir', type=str)
start_parser.add_argument('url_or_path', nargs='?', type=str,
default=DEFAULT_URL)
start_parser.add_argument('--show-command', action='store_true',
« sky/tools/debugger/prompt/prompt.cc ('K') | « sky/tools/debugger/prompt/prompt.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698