I promised a few people I’d blog about this, so here you go.
To help with the business of making Android or FirefoxOS devices do our bidding, Mozilla Automation & Tools developed a Python library called mozdevice which allows you to control these devices either using the Android Debug Bridge protocol (which is actually not Android specific: FirefoxOS devices use it too) or the System Under Test protocol (a Mozilla-specific thing).
Anyone familiar with debugging these devices is doubtless familiar with adb, which provides a command line interface that allows you to push/pull files, run a shell, etc. To help test our python code (as well as expand the scope of what’s possible on the command line), I created a similar utility a few months ago called “dm” which provides a command-line interface to the aforementioned mozdevice code. It’s shipped as part of mozdevice, and testing it out is pretty simple if you have virtualenv installed:
virtualenv mozdevice cd mozdevice ./bin/pip install mozdevice source bin/activate dm --help
I generally use this utility for two things:
Testing out mozdevice code. For example, today we discovered an (unfortunate) bug in devicemanagerADB’s killProcess routine. It was easy to verify both the problem and my fix did what I expected by starting my custom build of fennec and running this command:
dm --package-name org.mozilla.fennec_wlach killapp org.mozilla.fennec_wlach
(yes, it’s a bit unfortunate that this bug occurred in the first place: devicemanagerADB really needs unit tests)
Day-to-day menial tasks, like getting device info/status, capturing screenshots, etc. You can get a full list of what this utility is capable of by running –help. E.g.:
``` (mozbase)wlach@eideticker:~/src/eideticker$ dm —help Usage: dm [options] <command> [<args>]
device commands: info [os|id|uptime|systime|screen|memory|processes] - get information on a specified aspect of the device (if no argument given, print all available information) install <file> - push this package file to the device and install it killapp <process name> - kills any processes with a particular name on device launchapp <appname> <activity name> <intent> <URL> - launches application on device ls <remote> - list files on device ps - get information on running processes on device pull <local> [remote] - copy file/dir from device push <local> <remote> - copy file/dir to device rm <remote> - remove file from device rmdir <remote> - recursively remove directory from device screencap <png file> - capture screenshot of device in action shell <command> - run shell command on device
Options: -h, —help show this help message and exit -v, —verbose Verbose output from DeviceManager —host=HOST Device hostname (only if using TCP/IP) -p PORT, —port=PORT Custom device port (if using SUTAgent or adb-over-tcp) -m DMTYPE, —dmtype=DMTYPE DeviceManager type (adb or sut, defaults to adb) -d HWID, —hwid=HWID HWID —package-name=PACKAGENAME Packagename (if using DeviceManagerADB) ```
Before you ask, yes, it’s technically possible to do much of this with the original adb utility. But (1) some of our internal stuff can’t use adb a variety of reasons and (2) some of the tasks above (e.g. launching an app, getting a screenshot) involve considerably more typing with adb than with dm. So it’s still a win. </li> </ol> Happy command-lining!