2012年01月20日
Androidのadbのメモ(4) service
ADBのserviceについてのメモ。
adbのおおまかな機能
- Transport: ホストとターゲットの間の通信経路を確立する
- Service: その通信経路を使って(主に)ホスト側からターゲット側にリモートで何かを実行させる
Transport: ホストとターゲットの間の通信経路を確立する
ホストとターゲットの接続方法はUSBとTCPの2種類があるが、adbがプロキシーの働きをしてそれを隠蔽するので、両端からは単なるsocketのストリームとして扱うことができる。
単にこの機能だけが欲しい場合は adb forward コマンドを使えばよい。
つながっているターゲットがひとつだけの場合は、明示的に通信先を指定する必要がない。
複数ある場合には、USBかTCPかで指定する方法とターゲットのシリアル番号で指定する方法がある。
Service: その通信経路を使って(主に)ホスト側からターゲット側にリモートで何かを実行させる
実際にはserviceはadb serverで処理が完了するものと、adb serverを経由してターゲット側のadbdで処理されるものがある。
ちなみに、Androidの中でも"service"という用語は各レイヤごとに違うものをさす。
init.rcでのservice, binderでのservice, Javaプログラムでのandroid.app.Service, およびこのadbでのserviceは全て異なるもの。私は英語が母国語ではないのでニュアンスが理解できないが、強いてこれらの共通点をあげると、直接自分で行うのでなく、誰かに頼んで後でしてもらう処理を"service"と呼ぶようだ。
ADBのserviceのメモ
system/core/adb/service.c と system/core/adb/commandline.cを見たときのランダムなメモ。
system/core/adb/SERVICES.txtも参照。
ターゲット側で実行される各serviceはadbdでスレッドまたはサブプロセスを起動してそこで実行される。
/system/bin/shをサブプロセスとして起動するときに擬似端末を使用している。/dev/ptmx, grantpt, unlockpt, ptsname などの使用方法が参考になる。
adb root, adb usb, adb tcpip などadbdのリスタートをともなうものは、システムプロパティに書き込むことで、initにリスタートを依頼している。つまりAndroidのinitに依存しているので、adbdを他のOSに移植を考えている場合はこれを変更する必要がある。
adb reboot または adb reboot-bootloader のときはターゲット側でsync();の後に/system/bin/vdc コマンドをfork & execして外部ストレージの強制アンマウントを依頼し、その終了を待つ。その後でシステムコールのrebootが使われる。
adb install はクライアント側のcommandline.cでファイルの転送とshellコマンドの実行に分割して実現されている。パッケージのファイルを転送したあとにターゲット側実行するコマンドはpm。/system/bin/pmはshellスクリプトであり、Javaで書かれたhttp://com.android.commands.pm.Pm を新たにDalvikVMを起動して実行する。adb uninstall も同様にターゲット側でpmコマンドを実行する。
adb backup, adb restore というコマンドがAndroid 4.0から追加されている。ファイルに保存されている状態も含めて、アプリケーションの保存、復帰ができるようだ。
"framebuffer:" DDMSでスクリーンショットを撮るときには、このサービスが使われる。以前はadbdが直接フレームバッファのデバイスファイルを読んでいたが、Andorid4.0からはscreencapコマンドをfork & exec するようになった。
DDMSからadbの通信を行う部分のソースコードは、sdk/ddms/libs/ddmlib/src/com/android/ddmlib/Adbhelper.java ここで、"framebuffer:" や "log:"など通常のadbコマンドでは使用することがないserviceが使われていた。
"dns:" 唯一ホスト側で実行されるローカルサービス。gethostbynameでホスト名からIPアドレスを引く。SERVICES.TXTによれば、デバイスからUSBでホストを経由してのネットワーク接続(つまり、テザリングの逆)を実装するときに使われるらしい。通常のadbコマンドではこのサービスを利用するコードはみつからない。
"recover:"というサービスがあるが、どこから使用されるのか見つけられなかった。過去の遺物かも。
関連するページ
Android Builders SummitでADBの話をしました
Androidのadbのメモ(1) adb serverの観察
Androidのadbのメモ(5) adb shell lsを実行したときのログ
Androidのemulator consoleに簡単にコマンドを送る方法
Androidのadbのメモ(6) 直接adb serverと通信するrubyスクリプト
Androidのadbのメモ(7) Androidデバイス側でadbを動かす
Androidのadbのメモ(8) Android以外でadbを使う実験
Androidのadbのメモ(9) Android端末同士をadbでつなぐ
Androidのadbのメモ(10) adbdの起動のトリガー
Androidのadbのメモ(11) adbdのsecureモード