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)



トラックバックURL

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード