AndroidのSensor周辺のアーキテクチャについて

せっかくAndroidのお仕事してるのにあんまりAndroidのこと記事にしてませんね。
ということでAndroidのSensor周辺のアーキテクチャについて備忘録を兼ねて書いておきます。


ざっくりとAndroid(Gingerbread)のソースを読んで判ったアーキテクチャを図にしてみました。
下図のような構成になっているようです。


Application

Applicationは特に記載していませんが、当然Javaで書かれDalvik VM上で動きます。
ApplicationからはContext.getSystemServiceを利用してSensorManagerを取得します。
SensorManagerはJNIを通してsensorserviceとやりとりをすることでsensorへのaccessを行います。


# この辺のコードは「frameworks/base/core/java/android/hardware/SensorManager.java」とかを読んでいけば追って行けます。

SensorService & libhardware - sensors.xxx.so

sensorserviceからは「libhardware」が呼び出され、その中で「sensors.xxx.so」が呼び出されます。
「sensors.xxx.so」の「xxx」には環境依存の名前が入ります。
この環境依存の名前はpropertyから取得するようになっており、以下のいずれかのpropertyに設定された名前を利用します。

  1. ro.hardware
  2. ro.product.board
  3. ro.board.platform
  4. ro.arch

# build.propやdefault.propに上記いずれかのpropertyを記載することで任意の「sensors.xxx.so」を環境に応じて読み込むことができます。

上記のいずれも該当するファイルが存在以内場合は、「sensors.default.so」を読み込もうとします。
また「sensors.xxx.so」の配置場所は下記の2箇所を利用することが出来ます。

  1. /system/lib/hw
  2. /vendor/lib/hw

Linux Device Driver

「sensors.xxx.so」の中ではLinuxデバイスドライバを叩くことでセンサの操作に必要な機能を実装します。
センサのドライバの多くは標準的なinputデバイスとしてアクセスすることができるように作られています。
このため、「sensors.xxx.so」の内部では「/dev/input/eventX」を直接読み出すことでセンサの値を取得するような実装が見られます。


inputデバイスを用いることでセンサの値を取得することはできます。しかしながらセンサに対する制御はinputデバイスでは行えません。
そのため多くのデバイスでは次のどちらかまたは両方のインターフェイスを用いる実装が行われています。

  1. ioctl
  2. SysFs

多くのデバイスではioctlが使われているようですが、一部のデバイスではSysFsを用いるようになっています。


以上でざっくりとしたAndroidのSensorに関する周辺の構造は終わりです。
あとは下回りのドライバの実装に関するknow-how的なお話になるので割愛です。
興味がある方は公開されているドライバの実装を追って見たりすると面白いかもしれません。