aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJukka Jylänki <jujjyl@gmail.com>2014-06-09 04:09:15 +0300
committerJukka Jylänki <jujjyl@gmail.com>2014-06-09 04:09:41 +0300
commitdbb10274be5e2193f823b38f6dc710a27f86bee8 (patch)
tree5f7696e510d1648e754334b3d9a958ef04c23e69 /tools
parent2fe530336f840b08b771e155a7e70902a350a742 (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-xtools/ffdb.py108
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."