2011年03月29日
AndroidのBinderによるプロセス間のメソッド呼び出し(メモ4:service manager)
今回はservice managerのメモ。
initはZygoteを起動するより先に /system/bin/servicemanagerを起動します。
init.rcを見るとFroyoまでは"critical"に指定されている唯一のサービスでした。
(Gingerbreadではinitから分化した/sbin/ueventd も"critical"になっていました。)
servicemanagerの役割
binderによるプロセス間通信では、まずserviceに対応するハンドラを取得する必要があります。servicemanagerはservice名の文字列とハンドラの対応づけを行っています。いわゆるserviceに関するネームサーバー。
servicemanager自体が、それをserviceとして提供していますが、ハンドラが0に固定されています。
check service, get service
サービス名から、それに対応するハンドラを検索する。
(servicemanagerの側ではこの2つは同じ働きをします。後述。)
add service
サービスを登録する。
list service
サービス名の一覧を得る。(ただし、servicemanagerでは、指定されたn番目のサービスの名前を返すだけ。一覧を得るためにはnをインクリメントさせながら繰り返し呼ぶ必要がある。後述。)
servicemanagerのソース
frameworks/base/cmds/servicemanager/service_manager.c
frameworks/base/cmds/servicemanager/binder.[ch]
シンプルな構成。シングルスレッドなので一度にひとつの処理しかできないようになっている。
/dev/binder を使うところはここと frameworks/base/libs/binder/ProcessState.cpp の2箇所だけ。
なお、framework/base/cmds/runtime でも似たようなコードがありますが、こちらは現在は使われていません。
JavaのServiceManger
frameworks/core/java/androis/os/ServiceManager.java
frameworks/core/java/androis/os/ServiceManagerNative.java
frameworks/core/java/androis/os/IServiceManager.java
android.os.ServiceManager:
- IBinder getService(String name)
- IBinder checkService(String name)
- void addService(String name, IBinder service)
- String[] listServices()
これらのメソッドがJavaから使用するときの切り口になります。これらはstaticメソッドです。IServiceManager.javaはリモートメソッドのinterfaceを定義し、ServiceManagerNative.javaはbinderを呼び出すためのProxyです。(ServiceManagerNativeはabstractクラスですが、これを継承するクラスはありません。)
IServiceManager.cpp
frameworks/libs/binder/IServiceManger.cpp
servicemanagerのプロセスの処理を軽くするために、サービスを呼び出す側が肩代わりしている部分があります。具体的には、C++のBpServiceManagerクラスで
- checkServiceは一度servicemanagerに処理を要求するだけだが、getService は1秒スリープしながら最大4回のリトライを行う。
- listServicesでは、この中でループして得られた文字列をVectorに積み上げている。
アプリケーションからは?
これらのServiceManager関連のクラスはJavadocでhide指定されているので、アプリケーションプログラムからは隠されています。システムで提供されているサービスを利用するために、android.content.ContentWrapper#getSystemService(String name) がありますが、これが内部でServiceManagerを使っています。
訂正
コマンド名に対応させて、service_managerをservicemanagerに置き換えました。(2011.3.29)
関連するページ
AndroidのBinderによるプロセス間のメソッド呼び出し(メモ)
AndroidのBinderによるプロセス間のメソッド呼び出し(メモ2:AIDL)
AndroidのBinderによるプロセス間のメソッド呼び出し(メモ3:Binder Thread)