diff options
author | Jukka Jylänki <jujjyl@gmail.com> | 2014-06-09 04:09:15 +0300 |
---|---|---|
committer | Jukka Jylänki <jujjyl@gmail.com> | 2014-06-09 04:09:41 +0300 |
commit | dbb10274be5e2193f823b38f6dc710a27f86bee8 (patch) | |
tree | 5f7696e510d1648e754334b3d9a958ef04c23e69 /tools | |
parent | 2fe530336f840b08b771e155a7e70902a350a742 (diff) |
Improved error messages printed from tools/ffdb.py. Added new commands 'get', 'set', 'unset', 'hide-prompt' and 'restore-prompt' to ffdb.
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/ffdb.py | 108 |
1 files changed, 105 insertions, 3 deletions
diff --git a/tools/ffdb.py b/tools/ffdb.py index 2171cb0e..b98814f7 100755 --- a/tools/ffdb.py +++ b/tools/ffdb.py @@ -2,6 +2,7 @@ import socket, json, sys, uuid, datetime, time, logging, cgi, zipfile, os, tempfile, atexit, subprocess, re, base64, struct, imghdr +ADB = 'adb' # Path to the adb executable LOG_VERBOSE = False # Verbose printing enabled with --verbose HOST = 'localhost' # The remote host to connect to the B2G device PORT = 6000 # The port on the host on which the B2G device listens on @@ -62,7 +63,14 @@ def logv(msg): # Returns a JSON dictionary of the received message. def read_b2g_response(print_errors_to_console = True): global read_queue, b2g_socket - read_queue += b2g_socket.recv(65536*2) + try: + read_queue += b2g_socket.recv(65536*2) + except Exception, e: + if e[0] == 57: # Socket is not connected + print 'Error! Failed to receive data from the device: socket is not connected!' + sys.exit(1) + else: + raise payload = '' while ':' in read_queue: semicolon = read_queue.index(':') @@ -150,8 +158,60 @@ def print_applist(applist, running_app_manifests, print_removable): num_printed += 1 return num_printed +def adb_devices(): + try: + devices = subprocess.check_output([ADB, 'devices']) + devices = devices.strip().split('\n')[1:] + devices = map(lambda x: x.strip().split('\t'), devices) + return devices + except Exception, e: + return [] + +def b2g_get_prefs_filename(): + return subprocess.check_output([ADB, 'shell', 'echo', '-n', '/data/b2g/mozilla/*.default/prefs.js']) + +def b2g_get_prefs_data(): + return subprocess.check_output([ADB, 'shell', 'cat', '/data/b2g/mozilla/*.default/prefs.js']) + +def b2g_get_pref(sub): + prefs_data = b2g_get_prefs_data().split('\n') + # Filter to find all prefs that have the substring 'sub' in them. + r = re.compile('user_pref\w*\(\w*"([^"]*)"\w*,\w*([^\)]*)') + for line in prefs_data: + m = r.match(line) + if m and (sub is None or sub in m.group(1)): + print m.group(1) + ': ' + m.group(2).strip() + +def b2g_set_pref(pref, value): + prefs_data = b2g_get_prefs_data().split('\n') + # Remove any old value of this pref. + r = re.compile('user_pref\w*\(\w*"([^"]*)"\w*,\w*([^\)]*)') + new_prefs_data = [] + for line in prefs_data: + m = r.match(line) + if not m or m.group(1) != pref: + new_prefs_data += [line] + + if value != None: + print 'Setting pref "' + pref + '" = ' + value + new_prefs_data += ['user_pref("' + pref + '", ' + value + ');'] + else: + print 'Unsetting pref "' + pref + '"' + (oshandle, tempfilename) = tempfile.mkstemp(suffix='.js', prefix='ffdb_temp_') + os.write(oshandle, '\n'.join(new_prefs_data)); + + # Write the new pref + subprocess.check_output([ADB, 'shell', 'stop', 'b2g']) + subprocess.check_output([ADB, 'push', tempfilename, b2g_get_prefs_filename()]) + subprocess.check_output([ADB, 'shell', 'start', 'b2g']) + print 'Rebooting phone...' + + def delete_temp_file(): + os.remove(tempfilename) + atexit.register(delete_temp_file) + def main(): - global b2g_socket, webappsActorName, HOST, PORT, VERBOSE + global b2g_socket, webappsActorName, HOST, PORT, VERBOSE, ADB if len(sys.argv) < 2 or '--help' in sys.argv or 'help' in sys.argv or '-v' in sys.argv: print '''Firefox OS Debug Bridge, a tool for automating FFOS device tasks from the command line. @@ -171,6 +231,13 @@ def main(): screenshot [filename.png]: Takes a screenshot of the current contents displayed on the device. If an optional filename is specified, the screenshot is saved to that file. Otherwise the filename will be autogenerated. + get <pref>: Fetches the value of the given developer pref option from the FFOS device and prints it to console. + set <pref> <value>: Writes the given pref option to the FFOS device and restarts the B2G process on it for the change to take effect. + unset <pref>: Removes the given pref option from the FFOS device and restarts the B2G process on it for the change to take effect. + + hide-prompt: Permanently removes the remote debugging connection dialog from showing up, and reboots the phone. This command is + provided for conveniency, and is the same as calling './ffdb.py set devtools.debugger.prompt-connection false' + restore-prompt: Restores the remote debugging connection dialog prompt to its default state. Options: Additionally, the following options may be passed to control FFDB execution: @@ -209,13 +276,23 @@ def main(): sys.argv = filter(lambda x: len(x) > 0, sys.argv) + # Double-check that the device is found via adb: + if (HOST == 'localhost' or HOST == '127.0.0.1') and not connect_to_simulator: + devices = adb_devices() + if len(devices) == 0: + print 'Error! Failed to connect to B2G device debugger socket at address ' + HOST + ':' + str(PORT) + ' and no devices were detected via adb. Please double-check the following and try again: ' + print ' 1) The device is powered on and connected to the computer with an USB cable.' + print ' 2) ADB and DevTools debugging is enabled on the device. (Settings -> Developer -> Debugging via USB: "ADB and DevTools"' + print ' 3) The device is listed when you run "adb devices" on the command line.' + print ' 4) When launching ffdb, remember to acknowledge the "incoming debug connection" dialog if it pops up on the device.' + sys.exit(1) b2g_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: b2g_socket.connect((HOST, PORT)) except Exception, e: if e[0] == 61: # Connection refused if (HOST == 'localhost' or HOST == '127.0.0.1') and not connect_to_simulator: - cmd = ['adb', 'forward', 'tcp:'+str(PORT), 'localfilesystem:/data/local/debugger-socket'] + cmd = [ADB, 'forward', 'tcp:'+str(PORT), 'localfilesystem:/data/local/debugger-socket'] print 'Connection to ' + HOST + ':' + str(PORT) + ' refused, attempting to forward device debugger-socket to local address by calling ' + str(cmd) + ':' else: print 'Error! Failed to connect to B2G ' + ('simulator' if connect_to_simulator else 'device') + ' debugger socket at address ' + HOST + ':' + str(PORT) + '!' @@ -242,6 +319,9 @@ def main(): logv('Connected. Handshake: ' + str(handshake)) data = send_b2g_cmd('root', 'listTabs') + if not 'deviceActor' in data: + print 'Error! Debugging connection was not available, deviceActor was not found!' + sys.exit(1) deviceActorName = data['deviceActor'] logv('deviceActor: ' + deviceActorName) webappsActorName = data['webappsActor'] @@ -441,6 +521,28 @@ def main(): print >> sys.stderr, "Wrote " + sizeof_fmt(len(binary_data)) + " to file '" + filename + "', but the contents may be corrupted!" else: print "Wrote " + sizeof_fmt(len(binary_data)) + " to file '" + filename + "' (" + str(width) + 'x' + str(height) + ' pixels).' + elif sys.argv[1] == 'get': + b2g_get_pref(sys.argv[2] if len(sys.argv) >= 3 else None) + elif sys.argv[1] == 'set': + if len(sys.argv) < 3: + print 'Error! No pref name to set given! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <pref> <value>' + sys.exit(1) + if len(sys.argv) < 4: + print 'Error! No value given to set! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <pref> <value>' + sys.exit(1) + if len(sys.argv) > 4: + print 'Error! Too many arguments given (' + str(sys.argv) + '), need exactly four! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <pref> <value>' + sys.exit(1) + b2g_set_pref(sys.argv[2], sys.argv[3]) + elif sys.argv[1] == 'unset': + if len(sys.argv) < 3: + print 'Error! No pref name given! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <pref>' + sys.exit(1) + b2g_set_pref(sys.argv[2], None) + elif sys.argv[1] == 'hide-prompt': + b2g_set_pref('devtools.debugger.prompt-connection', 'false') + elif sys.argv[1] == 'restore-prompt': + b2g_set_pref('devtools.debugger.prompt-connection', None) else: print "Unknown command '" + sys.argv[1] + "'! Pass --help for instructions." |