Sunday, December 23, 2012

Adb Is the Swiss-Army Knife of Android Development


Okay, I've now been shoved onto two projects with very tight deadlines, so I haven't had a chance to learn anything, even at lunch.

This is bad. "I'm too busy sawing to sharpen the saw."

I'm on Christmas vacation -- which I had to take or lose it -- so I can pause between obligations daily, go to a coffee shop, and exercise my brain.

I'll try shaking off some rust, and take a little closer look at adb.

What do I know?

  • adb shell gets me into the box over the serial line,
  • adb kill-server gets me out of situations where the adb server is confused,
  • adb logcat dumps out logs,

but there's more to it, so I'll read the man page and do some experiments to firm up my mental model.

The host adb client talks to the target adb daemon (adbd), therough the host adb server.
If no server is running, any use of adb creates a new one. I can convince myself like this:

$ adb kill-server # kill any server that might be running
$ ps ajax | grep [a]db  # no output
$ adb shell ps | grep adbd # daemon running on the target
root      67    1     3416   172   ffffffff 00008294 S /sbin/adbd
$ ps ajax | grep [a]db # 'adb shell' started a new host server
1  7161  7158  3629 pts/4     7201 Sl    1000   0:00 adb fork-server server
$ adb kill-server # kill host server again
$ ps ajax | grep [a]db  # no output
$ adb shell ps | grep adbd # target daemon target still running
root      67    1     3416   172   ffffffff 00008294 S /sbin/adbd
$ adb kill-server # but now there's a new server, again started by 'adb shell'
1  7240  7237  3629 pts/4     7249 Sl    1000   0:00 adb fork-server server

adb shell creates a new shell on the target, launched by adbd, and talks to it over port 5037.

A quick peek at the help (adb --help) shows many other sub-commands.

  • adb forward does port forwarding
  • adb backup dumps over 10,000 lines of info
  • adb push pushes files to the device
  • adb pull pulls them off

What would you pay? But wait. There's more.

  • adb get-serialno prints the device name, "0123456789ABCDEF"
  • adb get-state prints "device"
  • adb get-devpath prints "usb:1-1.2"
  • adb devices -l gives all of these, together

  List of devices attached 
  0123456789ABCDEF       device usb:1-1.2

It's also a monitoring and exploration tool. adb status-window prints "device", switches to "unknown" when I unplug it, then back to "device" when I plug it back in.
If I reboot, the switch to "device" is coincident with the announcement by Network Manager that the connection has been established.

"Established" doesn't mean the device is pingable. For that, I need to bring the network up. Again, the tool is adb.

I could do what I want by connecting to the target, with adb shell, then executing commands.
I could also create a script and push it over with adb push, and modify the remote startup files to execute it at board bring-up.

But adb shell [cmd] lets me do it all on the host, like this:
$ adb shell 'netcfg eth0 up'$ adb shell 'ifconfig eth0 192.168.1.1 netmask 255.255.255.0'
and now I can ping 192.168.1.1!

Similarly,
$ adb shell androidvncserver &> /tmp/androidvncserver.log &
brings up the remote vncserver and lets me connect to it from my VNC client on the host.

Note that the command, above, puts the job in the background on the host.  I can't yet figure out how to bring up this job from the host so it's running in the background on the target, so killing the server kills the connection. (I can, of course, still adb shell directly into the box and launch it in the background on the target itself.)

There's a lot of stuff here to figure out, even just about adb.

On coming up, the target vnc server says it's listening on for VNC connections on port 5901. I can connect over ethernet, but if I don't have an ethernet cable handy, I can even use adb to tunnel all traffic over the serial line between the VNC ports on the host and the target, like this:
$ adb forward tcp:5901 tcp:5901
The target vnc server also says it's listening for http connections on 5801. Sure enough, if I browse to http:192.168.1.1:5801 in a browser, I do get connected. Sadly, the browser just displays "File Not Found" so I don't yet have this piece all figured out, either.

Here are some other things I can't yet get to work, either:

  • adb reboot bootloader says it should reboot and stop in the bootloader. It  reboots, but completely. If I want to stop in u-boot, I still need to use minicom to get in over the serial line, and press a key while u-boot is running to stop the automatic reboot.
  • Setting ANDROID_LOG_TAGS is supposed to filter the adb logcat output. That would be useful but, again, I can't figure out how to make it work.
  • adb connect <host>[:<port>] is supposed to make a network connection. Me I can't make heads or tails of it yet.

The list of things I'm at sea with is still long. Maybe tomorrow it'll all make sense.

No comments:

Post a Comment