2011年12月12日

Android2.3でSurfaceflingerを独立したプロセスで動かす

Android2.3まではSurfaceflingerはSystemServerの中のスレッドとして動作していましたが、Android4.0では独立したプロセスになっていました。

システムの各種の資源を節約するには、SystemServerの中で動かす方がよいと思いますが、Surfaceflingerにデバッガをあてて調べるには独立したプロセスになっているほうが好都合です。



init.rcの変更

実は以前からSurfaceflingerは独立したプロセスで動かすことが可能になっていました。Android 2.3でも/system/bin/surfaceflinger という実行コマンドはビルドされてインストールされています。

そのため、以下のようにinit.rcを変更するだけで、Surfaceflingerを独立したプロセスで動かすことができました。

$ diff -u init.rc.org init.rc
--- init.rc.org	2011-12-12 09:55:31.000000000 +0900
+++ init.rc	2011-12-12 10:02:00.000000000 +0900
@@ -273,6 +273,9 @@
     setprop net.tcp.buffersize.edge    4093,26280,35040,4096,16384,35040
     setprop net.tcp.buffersize.gprs    4092,8760,11680,4096,8760,11680
 
+# Set this property so surfaceflinger is not started by system_init
+    setprop system_init.startsurfaceflinger 0
+
     class_start default
 
 ## Daemon processes to be run by init.
@@ -324,6 +327,11 @@
     user root
     group radio cache inet misc audio sdcard_rw
 
+service surfaceflinger /system/bin/surfaceflinger
+    user system
+    group graphics
+    onrestart restart zygote
+
 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
     socket zygote stream 666
     onrestart write /sys/android_power/request_state wake

ただし、これだけだとタイミングによってはデバイスファイルのopenに失敗して一度Surfaceflingerは終了し、その後initによって再起動されることがあるようです。(GPU用のカーネルモジュールをロードして、そのデバイスファイルが準備できる前に、Surfaceflingerがそれをopenしようとしてしまう時があるらしい。)

参考:SystemServerでsurfaceflingerを起動するところ

SystemServerでsurfaceflingerを起動するときにsystem_init.startsurfaceflingerのプロパティを見ています。

frameworks/base/cmds/system_server/library/system_init.cpp

extern "C" status_t system_init()
{
    LOGI("Entered system_init()");
    
    sp proc(ProcessState::self());
    
    sp sm = defaultServiceManager();
    LOGI("ServiceManager: %p\n", sm.get());
    
    sp grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
    
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();
    }

    // Start the sensor service
    SensorService::instantiate();

   ...

以前書いたAndroidのSystemServerの起動シーケンス(メモ)も参照してください。

おまけ: surfaceflingerでのシステムコール呼び出しをstraceで調べる

#service surfaceflinger /system/bin/surfaceflinger
service surfaceflinger /system/xbin/strace -ff -o /data/local/tmp/strace.log /system/bin/surfaceflinger
    user system
    group graphics
    onrestart restart zygote

あらかじめ /data/local/tmp のディレクトリを作って書き込み可能にしておきます。

おまけ2:Android4.0でSurfaceflingerをSystemServerの中のスレッドとして動かす

逆に以下のようにinit.rcをコメントアウトすれば、Android4.0でSurfaceflingerをSystemServerの中のスレッドとして動かすことができます。

$ sudo diff -u init.rc.org init.rc
--- init.rc.org	2011-12-12 10:16:40.000000000 +0900
+++ init.rc	2011-12-12 10:16:59.000000000 +0900
@@ -261,7 +261,7 @@
     setprop net.tcp.buffersize.gprs    4092,8760,11680,4096,8760,11680
 
 # Set this property so surfaceflinger is not started by system_init
-    setprop system_init.startsurfaceflinger 0
+#    setprop system_init.startsurfaceflinger 0
 
     class_start core
     class_start main
@@ -400,11 +400,11 @@
     user root
     group radio cache inet misc audio sdcard_rw log
 
-service surfaceflinger /system/bin/surfaceflinger
-    class main
-    user system
-    group graphics
-    onrestart restart zygote
+#service surfaceflinger /system/bin/surfaceflinger
+#    class main
+#    user system
+#    group graphics
+#    onrestart restart zygote
 
 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
     class main


トラックバックURL

コメントする

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

QRコード
QRコード