この記事は4ヶ月以上前から書こうと思っていたのですが、時間がなくてなかなか書けなかったので、今日時間ができたら書きます。この記事の主な内容は以下の通りです
目次
4. SensorService はどのようにセンサー データをアプリケーションに提供しますか?
この記事で分析するソースコードは Android 9.0 をベースにしています
================================================= ==
1. Androidモジュール間の関係の基本フローチャート
Android センサー モジュール全体のコアは SensorService です。アプリケーションは SensorManager を通じて対話します。SensorService は基本的にセンサーのすべての動作を管理します。これには、センサーのオンとオフの切り替え、アプリケーションへのセンサー データの取得、アプリケーションがセンサー、スタンバイ後のセンサーの動作、センサー データ、スイッチ レコード キャッシュ、ここで仮想センサーなどをカスタマイズすることもできます。
Android 9まではSensorServiceがシステムサーバー内で動作していたため、SensorServiceがハングアップしている限りシステム全体がハングアップしてしまいました(Android 10では改良されているようですが、まだ勉強していません)。 Googleはそれをオーディオと同様にします。その方がサーバーが改善されます。3秒間ハングしても再起動できます。
2. SensorService の開始
sensorservice は、system_server の起動時に system_server によってプルアップされますが、
前述したように、system_server プロセス内で実行されるため、sensorservice がクラッシュすると、
system_server がハングアップして再起動されます。
android/frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
//......
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();//调用JNI接口
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
//......
}
対応する jni 実装は次のとおりです。
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
//这边先将该接口注册,后面给system_server调用
{ "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService }
{ "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
};
//在这儿创建sensorservice
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
SensorService::instantiate();
}
}
SensorService::instantiate() を使用して作成されたセンサーサービス インスタンス。
センサーサービスは BinderService を継承するため、次のように BinderService::instantiate() を使用してインスタンスを作成します。
//这边SERVICE为SensorService类型
template<typename SERVICE>
class BinderService
{
//......
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
//创建SensorService实例并且添加到ServiceManage
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
static void instantiate() { publish(); }
//......
};
SensorService コンストラクターを見ると、実際にはコンストラクターは何もしていません。主に UidPolicy オブジェクトを作成します。これは、後で分析するスタンバイ センサーの動作管理に使用されます。
SensorService::SensorService()
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
mWakeLockAcquired(false) {
mUidPolicy = new UidPolicy(this);
}
次に呼び出されるのは、onFirstRef() メソッドです。
//onFirstRef() メソッドは ServiceManager で呼び出され、
以前に作成された SensorService オブジェクトが強力に昇格されるときに RefBase::incStrong(const void* id) で呼び出されます。 pointer. の
呼び出し方法は以前の BinderService::publish() に戻る必要がありますが、興味のある方はご自身で勉強してください。
=====================================
onFirstRef() を見てください。
void SensorService::onFirstRef() {
SensorDevice& dev(SensorDevice::getInstance());//创建并获取SensorDevice实例
sHmacGlobalKeyIsValid = initializeHmacKey();
if (dev.initCheck() == NO_ERROR) {
sensor_t const* list;
ssize_t count = dev.getSensorList(&list);//获取vendor层注册的sensor 数目
if (count > 0) {
ssize_t orientationIndex = -1;
bool hasGyro = false, hasAccel = false, hasMag = false;
uint32_t virtualSensorsNeeds =
(1<<SENSOR_TYPE_GRAVITY) |
(1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
(1<<SENSOR_TYPE_ROTATION_VECTOR) |
(1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
(1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
//遍历每个sensor并将其注册到SensorList里边
for (ssize_t i=0 ; i<count ; i++) {
bool useThisSensor=true;
switch (list[i].type) {
case SENSOR_TYPE_ACCELEROMETER:
hasAccel = true;
break;
case SENSOR_TYPE_MAGNETIC_FIELD:
hasMag = true;
break;
case SENSOR_TYPE_ORIENTATION:
orientationIndex = i;
break;
case SENSOR_TYPE_GYROSCOPE:
case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
hasGyro = true;
break;
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
case SENSOR_TYPE_GAME_ROTATION_VECTOR:
if (IGNORE_HARDWARE_FUSION) {
useThisSensor = false;
} else {
virtualSensorsNeeds &= ~(1<<list[i].type);
}
break;
}
if (useThisSensor) {
//将HAL层的sensor_t类型结构体,存在HardwareSensor类里边,
//进而在SensorList类里边通过map将handle和HardwareSensor一起存储起来,
registerSensor( new HardwareSensor(list[i]) );
}
}
// it's safe to instantiate the SensorFusion object here
// (it wants to be instantiated after h/w sensors have been
// registered)
SensorFusion::getInstance();
//融合虚拟sensor的一些逻辑处理,这些不是重点,可以先不管
//所谓融合sensor,就是虚拟一个sensor,数据是拿一个或多个实际sensor的数据通过各种算法运算处理出来的,
//比如手机里边的自动转屏功能,就是用加速度数据算出来的。
//一般这些虚拟sensor需要一个算法一直在跑,若直接跑在AP端功耗很高,
//手机厂家都是将其实现在协处理器里边,比如高通骁龙845、855的slpi,
//而不是直接用google在framework实现的那套算法,
if (hasGyro && hasAccel && hasMag) {
// Add Android virtual sensors if they're not already
// available in the HAL
bool needRotationVector =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;
registerSensor(new RotationVectorSensor(), !needRotationVector, true);
registerSensor(new OrientationSensor(), !needRotationVector, true);
bool needLinearAcceleration =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;
registerSensor(new LinearAccelerationSensor(list, count),
!needLinearAcceleration, true);
// virtual debugging sensors are not for user
registerSensor( new CorrectedGyroSensor(list, count), true, true);
registerSensor( new GyroDriftSensor(), true, true);
}
if (hasAccel && hasGyro) {
bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
registerSensor(new GravitySensor(list, count), !needGravitySensor, true);
bool needGameRotationVector =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
}
if (hasAccel && hasMag) {
bool needGeoMagRotationVector =
(virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
}
mWakeLockAcquired = false;
mLooper = new Looper(false);
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];//创建存储sensor数据的buffer,可以存储256个数据
mSensorEventScratch = new sensors_event_t[minBufferSize];//这个用来存储啥的还不知道
mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
mLastNSensorRegistrations.push();//这个用来保存应用开关sensor的记录,后面 dumpsys sensorservice dump出来方便debug问题
}
mInitCheck = NO_ERROR;
//创建并运行一个SensorEventAckReceiver 线程
//这个loop线程用来不断检测是否需要持有wakelock
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
//在run里边调用SensorEventAckReceiver::threadLoop()方法,
//至于threadLoop是如何被调用的,感兴趣的读者可以跟一下源码,
//大概是在android/system/core/libutils/Threads.cpp 里边,
//通过pread_create() 创建一个线程运行thread::_threadLoop,
//在这里边调用其子类(也就是SensorEventAckReceiver)的threadLoop,
//同理通过创建一个线程运行SensorService::threadLoop(),
run("SensorService", PRIORITY_URGENT_DISPLAY);
// priority can only be changed after run
enableSchedFifoMode();//降低主线程调度优先级
// Start watching UID changes to apply policy.
mUidPolicy->registerSelf();//这边mUidPolicy将自己注册到uid待机管理里边,后面应用待机行为发生变化时其接口会通过多态被回调
}
}
}
SensorService::threadLoop() を見る前に、まず SensorDevice のコンストラクターを見てみましょう。SensorDevice は、
実際に HAL 層と直接対話するクラスです。
これは、hidl (HAL が参照した) を介して HAL 層のセンサーのサービスとの接続を確立します。この層は Google によって実装された部分のみを参照します: [email protected]. dlopen() を通じて、この層はチップ メーカー、携帯電話などのサードパーティによって実装された SO ライブラリを
呼び出します
メーカー、開発者など。実際には、これらを総称して HAL 層、またはベンダー層と呼ぶ必要があります。
SensorDevice::SensorDevice()
: mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
//通过hidl与HAL层建立连接
if (!connectHidlService()) {
return;
}
//获取开机时前面所说的第三方SO库注册的sensor,这个SO库一般就是直接与驱动进行通信对实际sensor进行开关和数据获取了,
//比如高通骁龙855的sensors.ssc.so通过qmi与slpi进行通信。
//后面所有与HAL层通信都是通过这个sp<hardware::sensors::V1_0::ISensors> mSensors
checkReturn(mSensors->getSensorsList(
[&](const auto &list) {
const size_t count = list.size();
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; i < count; i++) {
sensor_t sensor;
convertToSensor(list[i], &sensor);
// Sanity check and clamp power if it is 0 (or close)
if (sensor.power < minPowerMa) {
ALOGE("Reported power %f not deemed sane, clamping to %f",
sensor.power, minPowerMa);
sensor.power = minPowerMa;
}
mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
//保存该sensor的handle,这个现在还不知道做什么的,具体这个handle是在前面所说的第三方SO库决定的,一般按顺序叠加
mActivationCount.add(list[i].sensorHandle, model);
checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
}
}));
}
SensorService::threadLoop() を振り返ると、
bool SensorService::threadLoop() {
ALOGD("nuSensorService thread starting...");
// each virtual sensor could generate an event per "real" event, that's why we need to size
// numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too
// aggressive, but guaranteed to be enough.
const size_t vcount = mSensors.getVirtualSensors().size();
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + vcount);
//为何要这么做,再解释一下,比如说这边有vcount个虚拟的 sensor跑在framework,
//那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
//而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
//所以 numEventMax = minBufferSize / (1 + vcount);
SensorDevice& device(SensorDevice::getInstance());
const int halVersion = device.getHalDeviceVersion();
do {
//通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的第三方SO库实现)
//一般在该so库的poll里边,可以采用c++标准实现的queue::pop(),来获取数据,没数据时就一直阻塞,
//当驱动有数据上来时,另外一个线程将sensor数据往这个队列里边queue::pop就行了
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
mSensorEventBuffer[i].flags = 0;
}
// Make a copy of the connection vector as some connections may be removed during the course
// of this loop (especially when one-shot sensor events are present in the sensor_event
// buffer). Promote all connections to StrongPointers before the lock is acquired. If the
// destructor of the sp gets called when the lock is acquired, it may result in a deadlock
// as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
// strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
// rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
// sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
// not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
// releasing the wakelock.
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
}
//若有wakeup 类型sensor上报的数据就持有wakelock
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题
// 暂时可先忽略handle virtual sensor,dynamic sensor部分不看
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
bool needsWakeLock = false;
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i < numConnections; ++i) {
if (activeConnections[i] != 0) {
//通过SensorEventConnection 将数据通过socket发送给应用
activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
mMapFlushEventsToConnections);
needsWakeLock |= activeConnections[i]->needsWakeLock();
// If the connection has one-shot sensors, it may be cleaned up after first trigger.
// Early check for one-shot sensors.
if (activeConnections[i]->hasOneShotSensors()) {
cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
count);
}
}
}
//若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
if (mWakeLockAcquired && !needsWakeLock) {
setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;
}
この時点でセンサーサービスは起動されており、バインダー通信から送信されるenable()、disable()、flush()などのリクエストを受信したり、
HAL層のデータを読み取ってアプリケーションに提供したりすることができます。
================================================= ===========================
SensorService がアプリケーションにデータを提供する方法を説明する前に、まず次の主要なクラスを分析しましょう。
(1)センサーデバイス
SensorDevice は Singleton クラスを継承し、シングルトンとして設計されています。後で使用したい場合は、getinstance() を使用してください。なぜシングルトンを使用するのかというと、sensorservice にはベンダー層と対話するための複数のスレッドがあるためです。複数の
スレッドを使用する場合、ロジックはその必要はありません、メモリを節約してください(笑)。
それにはキー メンバーが保存されています: sp<hardware::sensors::V1_0::ISensors> mSensors.
構築中に、ベンダー層のセンサー サービス [email protected] が取得されます。
この mSensors は Vendor 層のインターフェイスを呼び出します。コードは次のとおりです。実は以前に解析したことがあります。戻って見ないように、もう一度貼り付けます。
SensorDevice::SensorDevice()
: mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
//通过hidl与HAL层建立连接
if (!connectHidlService()) {
return;
}
//获取开机时前面所说的第三方SO库注册的sensor,这个SO库一般就是直接与驱动进行通信对实际sensor进行开关和数据获取了,
//比如高通骁龙855的sensors.ssc.so通过qmi与slpi进行通信。
//这些sensor_t 类型的结构体,需要第三方的so库里边自己实现,每个结构体对象存储一个sensor的信息
checkReturn(mSensors->getSensorsList(
[&](const auto &list) {
const size_t count = list.size();
mActivationCount.setCapacity(count);
Info model;
for (size_t i=0 ; i < count; i++) {
sensor_t sensor;
convertToSensor(list[i], &sensor);
// Sanity check and clamp power if it is 0 (or close)
if (sensor.power < minPowerMa) {
ALOGE("Reported power %f not deemed sane, clamping to %f",
sensor.power, minPowerMa);
sensor.power = minPowerMa;
}
mSensorList.push_back(sensor);//将HAL层注册的sensor保存起来,具体如何注册的,后面分析sensor HAL层部分再分析
//保存该sensor的handle,具体数值是在前面所说的第三方SO库决定的,一般是从1开启按顺序叠加
mActivationCount.add(list[i].sensorHandle, model);
checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* disable */));//关闭该sensor,以防开着没用漏电
}
}));
}
bool SensorDevice::connectHidlService() {
// SensorDevice will wait for HAL service to start if HAL is declared in device manifest.
size_t retry = 10;
while (retry-- > 0) {
//......
//通过hidl获取 [email protected]
mSensors = ISensors::getService();
if (mSensors == nullptr) {
// no sensor hidl service found
break;
}
//.......
}
return (mSensors != nullptr);
}
(2)センサーイベント接続
このクラスは主にセンサー データをアプリケーションに送信し、ソケットを通じて通信するために使用されます。
アプリケーションがセンサーを登録すると、SensorManager.cpp は SensorService::createSensorEventConnection() を呼び出して、アプリケーションに属する接続を生成します。アプリケーションには
いくつの接続がありますか? SensorEventConnection は、アプリケーションが作成する SensorEventListerner の数によって異なります。
アプリケーション開発者によっては、複数のセンサーを登録するときに SensorEventListerner を 1 つだけ作成し、onSensorChanged() でタイプを区別したい場合もあります。パフォーマンスの観点から、1 つの
センサーと 1 つの SensorEventListerner を好む人もいます。結局のところ、アプリケーションが SensorEventListerner を作成するたびに
、新しいソケット接続が確立され、データを待機するためにもう 1 回のポーリングが使用されます。
コンストラクターを見てみましょう。
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
const String16& opPackageName, bool hasSensorAccess)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
mDestroyed(false), mHasSensorAccess(hasSensorAccess) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
mTotalAcksNeeded = mTotalAcksReceived = 0;
#endif
}
主にアプリケーション情報を保存するために、
2 つのパッケージ名をそれぞれ、
packageName: アプリケーションのパッケージ名;
opPackageName: java vm 名、
android/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp
android_server_SystemServer_startHidlServices() で取得して渡します。
このクラスの焦点は、アプリケーションにデータを送信する SensorEventConnection::sendEvents() 関数です。したがって、アプリケーションがセンサー データを取得できないという問題が発生した場合は、ここでデバッグすることもできます。
a. 複数のアプリケーションが同じセンサーを登録します。データを受信するアプリケーションと受信しないアプリケーションがあります。
b. すべてのアプリケーションが特定のセンサー データを受信していない。
c、すべてのセンサーにデータがありません。
ここで mPackageName とセンサー タイプ、センサー データ、センサー タイムスタンプを出力したり、統合ストレージの後にセンサー サービスをダンプしたりできます。
(3) センサーイベントキュー
SensorEventQueue には複数のクラス実装があります。ここでの主なものは、Android/frameworks/native/libs/sensor/ で定義されている SensorService で使用される SensorEventQueue です。アプリケーションがセンサーを登録すると、Java クラス SensorEventQueue が SystemSensorManager に作成されます
。ここでは、これから説明する C++ クラス SensorEventQueue を作成します。
センサー データが到着すると、SensorEventQueue は、コールバック アプリケーションによって実装された onSensorChanged() インターフェイスを通じてアプリケーションにデータを渡します。
//在这儿创建,android/frameworks/native/libs/sensor/SensorManager.cpp
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
//向SensorService请求创建connection,最后调用 SensorService::createSensorEventConnection()
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
if (connection == NULL) {
// SensorService just died or the app doesn't have required permissions.
ALOGE("createEventQueue: connection is NULL.");
return NULL;
}
//将前边创建的SensorEventConnection,作为SensorEventQueue构造函数的参数传进去,
//创建SensorEventQueue
queue = new SensorEventQueue(connection);
break;
}
return queue;
}
どのような状況で作成されますか? 作成プロセスについては、アプリケーションにセンサーを登録するプロセスで説明します。
//接下来看下构造函数,
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
: mSensorEventConnection(connection), mRecBuffer(NULL), mAvailable(0), mConsumed(0),
mNumAcksToSend(0) {
mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
}
コンストラクターは非常にシンプルで、SensorEventConnection から送信されたデータを格納する mRecBuffer を作成します。
このうち、
SensorEventQueue::write() は SensorEventConnection にデータを送信するために使用され、
SensorEventQueue::read() はアプリケーションにデータを読み取るために使用されます。
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
if (mAvailable == 0) {
ssize_t err = BitTube::recvObjects(mSensorChannel,
mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
if (err < 0) {
return err;
}
mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
size_t count = min(numEvents, mAvailable);
memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
return static_cast<ssize_t>(count);
}
3. センサープロセスの登録を申請する
まず、センサーを登録するだけのアプリケーションのコードを見てみましょう。
private SensorManager mSensorManager;
private Sensor mSensor;
//获取sensorManager
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//申请的为加速度传感器
mSensorManager.registerListener(mSensorEventListener,mSensor,SensorManager.SENSOR_DELAY_NORMAL);
final SensorEventListener mSensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
//有数据时该接口被回调,在这边使用sensor数据
Log.i(TAG,"sensorEvent.sensor.getType():" + sensorEvent.sensor.getType());
if(sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
//add you code
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
//add your code
}
まず registerListener() を見てみましょう。Google は、アプリケーション開発者が使用できるように、それらのいくつかを実装しています。最終的には、インターフェース SystemSensorManager::registerListenerImpl() が呼び出されるので、1 つを選択して、それに従い始めることができます。
android/frameworks/base/core/java/android/hardware/SensorManager.java
public boolean registerListener(SensorEventListener listener, Sensor sensor,
int samplingPeriodUs, int maxReportLatencyUs, Handler handler) {
int delayUs = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
}
//接着看
//android/frameworks/base/core/java/android/hardware/SystemSensorManager.java
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
if (listener == null || sensor == null) {
Log.e(TAG, "sensor or listener is null");
return false;
}
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
//一个SensorEventListener对应一个SensorEventQueue
// We map SensorEventListener to a SensorEventQueue, which holds the looper
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName =
listener.getClass().getEnclosingClass() != null
? listener.getClass().getEnclosingClass().getName()
: listener.getClass().getName();
//这边创建SensorEventQueue
//并装在hashmap mSensorListeners里边
queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
SensorEventListener (アプリケーション自体によって作成された) が以前に SensorEventQueue を作成していない場合は、SensorEventQueue を作成し、SensorEventListener とともに mSensorListeners に追加します。重要な点は、センサー データが最下層とアプリケーションの onSensorChanged() からどのように供給されるかです
。 SensorEventQueue が作成されると、その親クラス オブジェクト BaseEventQueue が同時に構築され、そのネイティブInitBaseEventQueue() メソッドでandroid/frameworks/base/core/jni/android_hardware_SensorManager.cpp のネイティブInitSensorEventQueue()
が呼び出されます。 jni を介してデータを受信する Receiver オブジェクトを作成し、この分析データをアップロードして詳細に分析します。
次に、登録プロセスを確認し、BaseEventQueue::addSensor() を介してセンサーを登録するプロセスを続行します。
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
// Try continuous mode if batching fails.
if (maxBatchReportLatencyUs == 0
|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
BaseEventQueue::enableSensor() を下に進み
、次を確認します。
private int enableSensor(
Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
if (mNativeSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
maxBatchReportLatencyUs);
}
jni を介して C++ インターフェイスを呼び出して、
次を確認します。
android/frameworks/base/core/jni/android_hardware_SensorManager.cpp
static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
jint maxBatchReportLatency) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
0);
}
次に
android/frameworks/native/libs/sensor/SensorEventQueue.cpp
SensorEventQueue::enableSensor()が来ます。
ここにはいくつかのオーバーロードがありますが、パラメーターが異なります。そのうちの 1 つだけを見てみましょう (TO DO: このブロックの開始方法とセンサー データの提供方法については後で分析します。プロセスを直接たどってみましょう)
status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
int64_t maxBatchReportLatencyUs, int reservedFlags) const {
return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
us2ns(maxBatchReportLatencyUs), reservedFlags);
}
次に到達
android/frameworks/native/services/sensorservice/SensorEventConnection.cpp
SensorService::SensorEventConnection::enableDisable()
status_t SensorService::SensorEventConnection::enableDisable(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags)
{
status_t err;
if (enabled) {
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
reservedFlags, mOpPackageName);
} else {
err = mService->disable(this, handle);
}
return err;
}
次は SensorService::enable() です
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName) {
if (mInitCheck != NO_ERROR)
return mInitCheck;
//获取到HardwareSensor,里边存储HAL层注册的sensor_t 类型结构体
sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
//检查应用是否有权限获取sensor数据
if (sensor == nullptr ||
!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
if (mCurrentOperatingMode != NORMAL
&& !isWhiteListedPackage(connection->getPackageName())) {
return INVALID_OPERATION;
}
//将来自应用的SensorEventConnection保存在SensorRecord,若之前没有一个应用开启该sensor,则创建SensorRecord,
//将该SensorRecord和对应的sensor handle保存在mActiveSensors里边记录下来,
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
rec = new SensorRecord(connection);
mActiveSensors.add(handle, rec);
if (sensor->isVirtual()) {
mActiveVirtualSensors.emplace(handle);
}
} else {
if (rec->addConnection(connection)) {
// this sensor is already activated, but we are adding a connection that uses it.
// Immediately send down the last known value of the requested sensor if it's not a
// "continuous" sensor.
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
// NOTE: The wake_up flag of this event may get set to
// WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
auto logger = mRecentEvent.find(handle);
if (logger != mRecentEvent.end()) {
sensors_event_t event;
// It is unlikely that this buffer is empty as the sensor is already active.
// One possible corner case may be two applications activating an on-change
// sensor at the same time.
if(logger->second->populateLastEvent(&event)) {
event.sensor = handle;
if (event.version == sizeof(sensors_event_t)) {
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
//若该sensor之前已经有其他应用注册着了,并且是on change类型的sensor,比如 proximity,
//那么将最新的一次事件送给应用
connection->sendEvents(&event, 1, NULL);
if (!connection->needsWakeLock() && mWakeLockAcquired) {
checkWakeLockStateLocked();
}
}
}
}
}
}
}
if (connection->addSensor(handle)) {
BatteryService::enableSensor(connection->getUid(), handle);
// the sensor was added (which means it wasn't already there)
// so, see if this connection becomes active
if (mActiveConnections.indexOf(connection) < 0) {
mActiveConnections.add(connection);//若该connection还没有保存在mActiveConnections,保存一下
}
} else {
ALOGW("sensor %08x already enabled in connection %p (ignoring)",
handle, connection.get());
}
// Check maximum delay for the sensor.
nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL;
if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) {
samplingPeriodNs = maxDelayNs;
}
nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
if (samplingPeriodNs < minDelayNs) {
samplingPeriodNs = minDelayNs;
}
ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
"rate=%" PRId64 " timeout== %" PRId64"",
handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
///enable sensor的时候先batch和翻录是一下,目的是清除一下数据?
status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
maxBatchReportLatencyNs);
// Call flush() before calling activate() on the sensor. Wait for a first
// flush complete event before sending events on this connection. Ignore
// one-shot sensors which don't support flush(). Ignore on-change sensors
// to maintain the on-change logic (any on-change events except the initial
// one should be trigger by a change in value). Also if this sensor isn't
// already active, don't call flush().
if (err == NO_ERROR &&
sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
rec->getNumConnections() > 1) {
connection->setFirstFlushPending(handle, true);
status_t err_flush = sensor->flush(connection.get(), handle);
// Flush may return error if the underlying h/w sensor uses an older HAL.
if (err_flush == NO_ERROR) {
rec->addPendingFlushConnection(connection.get());
} else {
connection->setFirstFlushPending(handle, false);
}
}
//关键就在这儿
//调用 HardwareSensor::activate() ==> SensorDevice::activate()
if (err == NO_ERROR) {
ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
err = sensor->activate(connection.get(), true);
}
if (err == NO_ERROR) {
connection->updateLooperRegistration(mLooper);
//记录调用者和对应sensor信息,后面可用dumpsys sensorservice dump出来debug问题
mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
SensorRegistrationInfo(handle, connection->getPackageName(),
samplingPeriodNs, maxBatchReportLatencyNs, true);
mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
}
//若调用失败,则将与应用的链接直接清掉
if (err != NO_ERROR) {
// batch/activate has failed, reset our state.
cleanupWithoutDisableLocked(connection, handle);
}
return err;
}
次に SensorDevice::activate() を見てみましょう。
status_t SensorDevice::activate(void* ident, int handle, int enabled) {
if (mSensors == nullptr) return NO_INIT;
status_t err(NO_ERROR);
bool actuateHardware = false;
Mutex::Autolock _l(mLock);
ssize_t activationIndex = mActivationCount.indexOfKey(handle);
if (activationIndex < 0) {
ALOGW("Handle %d cannot be found in activation record", handle);
return BAD_VALUE;
}
Info& info(mActivationCount.editValueAt(activationIndex));//从这里边获取到Info
ALOGD_IF(DEBUG_CONNECTIONS,
"SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
ident, handle, enabled, info.batchParams.size());
if (enabled) {
ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
if (isClientDisabledLocked(ident)) {
ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
ident, handle);
return INVALID_OPERATION;
}
if (info.batchParams.indexOfKey(ident) >= 0) {
//若是第一个注册该sensor的应用,那么需要调用HAL层的activate()
if (info.numActiveClients() == 1) {
// This is the first connection, we need to activate the underlying h/w sensor.
actuateHardware = true;
}
} else {
// Log error. Every activate call should be preceded by a batch() call.
ALOGE("\t >>>ERROR: activate called without batch");
}
} else {
ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
// If a connected dynamic sensor is deactivated, remove it from the
// dictionary.
auto it = mConnectedDynamicSensors.find(handle);
if (it != mConnectedDynamicSensors.end()) {
delete it->second;
mConnectedDynamicSensors.erase(it);
}
if (info.removeBatchParamsForIdent(ident) >= 0) {
//若是最后一个反注册该sensor的应用,那么需要调用HAL层的activate(),
//否则就重新batch一下
if (info.numActiveClients() == 0) {
// This is the last connection, we need to de-activate the underlying h/w sensor.
actuateHardware = true;
} else {
// Call batch for this sensor with the previously calculated best effort
// batch_rate and timeout. One of the apps has unregistered for sensor
// events, and the best effort batch parameters might have changed.
ALOGD_IF(DEBUG_CONNECTIONS,
"\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
checkReturn(mSensors->batch(
handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
}
} else {
// sensor wasn't enabled for this ident
}
if (isClientDisabledLocked(ident)) {
return NO_ERROR;
}
}
if (actuateHardware) {
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
enabled);
//这儿通过hidl调用HAL层的接口,源码在/android/hardware/interfaces/sensors/1.0,
err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled)));
ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
strerror(-err));
if (err != NO_ERROR && enabled) {
// Failure when enabling the sensor. Clean up on failure.
info.removeBatchParamsForIdent(ident);
}
}
return err;
}
次に、hidl を介して HAL に到達します。まず、Android 自体によって実装された hal 層に進みます。これを Android センサー hal と呼びます。次に、携帯電話メーカー自体によって実装された hal 層 (OEM センサーと呼ばれます) に進みます。ハル。
ここでもプロセスを直接見ていき、後で Android センサー hal の起動を分析します。
アンドロイド/ハードウェア/インターフェース/センサー/1.0/デフォルト/Sensors.cpp
Return<Result> Sensors::activate(
int32_t sensor_handle, bool enabled) {
return ResultFromStatus(
mSensorDevice->activate(
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
sensor_handle,
enabled));
}
それから来ました
アンドロイド/ハードウェア/libhardware/モジュール/センサー/multihal.cpp
static int device__activate(struct sensors_poll_device_t *dev, int handle,
int enabled) {
//留意这边有个强转,其实dev就是sensors_poll_context_t*类型,只是后面为了方便存储,
//就只是存了一个第一个成员变量首地址,通过这个地址可以获取到其父类,父类的父类的地址,
sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
return ctx->activate(handle, enabled);
}
次は
int sensors_poll_context_t::activate(int handle, int enabled) {
int retval = -EINVAL;
ALOGV("activate");
int local_handle = get_local_handle(handle);
sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
retval = v0->activate(v0, local_handle, enabled);
} else {
ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
enabled, handle);
}
ALOGV("retval %d", retval);
return retval;
}
ここのさらに下には、携帯電話メーカー自体によって実装されたインターフェイスがあり、Android 部分はここで終了します。
4. SensorService はどのようにセンサー データをアプリケーションに提供しますか?
簡単に説明すると、SensorService はデータの送信側として SensorEventConnection を使用し、アプリケーション側はデータの受信側として SensorEventListerner を使用し、unix ソケットを通じてデータを送信することで、それぞれから解析することができます。
まず SensorService 側から送信側を見てみましょう. SensorService が構築された後、継続的に実行されるスレッド threadLoop() が作成され、ポーリングを通じて hal 層からセンサー データが取得されます (このポーリングは Linux C の名前と同じです)標準関数poll()と同様の関数があります。Linux C標準のpoll()関数を呼び出す代わりに、センサーデータがない場合はブロックして待機し続けます(このブロック関数はHAL層によって実装されます)データが出てきたら、何らかの加工や判定を行った上でアプリケーションに送信します。
処理の判断には、データを破棄するかどうか、後でデバッグ用にダンプできるようにデータをベクター実装キャッシュに保存するかどうか、フラッシュ データかどうか、データをフュージョン センサーに与えるかどうか、アプリケーションを実行するかどうかが含まれます。センサーが閉じられたかどうか、アプリケーションがアイドル状態になったかどうかなど。
//从SensorService::threadLoop()开始看,
bool SensorService::threadLoop() {
ALOGD("nuSensorService thread starting...");
// each virtual sensor could generate an event per "real" event, that's why we need to size
// numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT. in practice, this is too
// aggressive, but guaranteed to be enough.
const size_t vcount = mSensors.getVirtualSensors().size();
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + vcount);
//为何要这么做,再解释一下,比如说这边有vcount个虚拟的 sensor跑在framework,
//那么比较极端的情况下每从HAL取numEventMax个数据,这边vcount个sensor会各生成numEventMax个数据,
//而mSensorEventBuffer 最多只能容纳 MAX_RECEIVE_BUFFER_EVENT_COUNT个数据,
//所以 numEventMax = minBufferSize / (1 + vcount);
SensorDevice& device(SensorDevice::getInstance());
const int halVersion = device.getHalDeviceVersion();
do {
//通过SensorDevice往HAL层取数据, 若没有数据的时候就一直阻塞(这个由前面说的HAL层实现)
//当有数据时该函数就会返回
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
mSensorEventBuffer[i].flags = 0;
}
// Make a copy of the connection vector as some connections may be removed during the course
// of this loop (especially when one-shot sensor events are present in the sensor_event
// buffer). Promote all connections to StrongPointers before the lock is acquired. If the
// destructor of the sp gets called when the lock is acquired, it may result in a deadlock
// as ~SensorEventConnection() needs to acquire mLock again for cleanup. So copy all the
// strongPointers to a vector before the lock is acquired.
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
// rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,
// sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should
// not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and
// releasing the wakelock.
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
}
//若有wakeup 类型sensor上报的数据就持有wakelock
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);//将事件保存下来,后面可以用dumpsys sensorservice dump出来方便分析问题
// 暂时可先忽略handle virtual sensor,dynamic sensor部分不看
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
bool needsWakeLock = false;
size_t numConnections = activeConnections.size();
for (size_t i=0 ; i < numConnections; ++i) {
if (activeConnections[i] != 0) {
//通过SensorEventConnection 将数据给到每个应用,每个应用都有自己的SensorEventConnection,好就是这里,再跟进去
activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
mMapFlushEventsToConnections);
needsWakeLock |= activeConnections[i]->needsWakeLock();
// If the connection has one-shot sensors, it may be cleaned up after first trigger.
// Early check for one-shot sensors.
if (activeConnections[i]->hasOneShotSensors()) {
cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
count);
}
}
}
//若还有wake up 类型的sensor报上来的数据的话,需要继续持有wakelock
if (mWakeLockAcquired && !needsWakeLock) {
setWakeLockAcquiredLocked(false);
}
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
return false;
}
つまり、SensorService::threadLoop() は、SensorDevice を介して hal 層からセンサー データを取得します。
データはさらに処理され、SensorService::SensorEventConnection::sendEvents() を通じて送信されます。異なるアプリケーションに属する複数の SensorEventConnections があることに注意してください。sendEvents() では、各アプリケーションが独自の処理を行います。
次に見てください、
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
// filter out events not for this connection
sensors_event_t* sanitizedBuffer = nullptr;
int count = 0;
Mutex::Autolock _l(mConnectionLock);
if (scratch) {
size_t i=0;
while (i<numEvents) {
//每个数据琢一处理
int32_t sensor_handle = buffer[i].sensor;
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
buffer[i].meta_data.sensor);
// Setting sensor_handle to the correct sensor to ensure the sensor events per
// connection are filtered correctly. buffer[i].sensor is zero for meta_data
// events.
sensor_handle = buffer[i].meta_data.sensor;
}
ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
//enable 一个sensor时,会保存该sensor的handle
//确认一下若该sensor已经被disable了,那么就没有必要将该sensor的数据给到应用了
//或者该应用没有注册该sensor的话,也是直接过滤掉
// Check if this connection has registered for this sensor. If not continue to the
// next sensor_event.
if (index < 0) {
++i;
continue;
}
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
// Check if there is a pending flush_complete event for this sensor on this connection.
if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
mapFlushEventsToConnections[i] == this) {
flushInfo.mFirstFlushPending = false;
ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
buffer[i].meta_data.sensor);
++i;
continue;
}
// If there is a pending flush complete event for this sensor on this connection,
// ignore the event and proceed to the next.
if (flushInfo.mFirstFlushPending) {
++i;
continue;
}
//过滤掉flush的数据后,将要给到应用的数据拷到scratch
do {
// Keep copying events into the scratch buffer as long as they are regular
// sensor_events are from the same sensor_handle OR they are flush_complete_events
// from the same sensor_handle AND the current connection is mapped to the
// corresponding flush_complete_event.
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
if (mapFlushEventsToConnections[i] == this) {
scratch[count++] = buffer[i];
}
} else {
// Regular sensor event, just copy it to the scratch buffer.
//若为false,即应用进入idle,那么就不将数据装进scratch在通过scratch给到应用,
//否则就装进去
if (mHasSensorAccess) {
scratch[count++] = buffer[i];
}
}
i++;
} while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
buffer[i].type != SENSOR_TYPE_META_DATA) ||
(buffer[i].type == SENSOR_TYPE_META_DATA &&
buffer[i].meta_data.sensor == sensor_handle)));
}
} else {
//这边不会走到不用管,感觉google这段代码有点多余哈哈
if (mHasSensorAccess) {
scratch = const_cast<sensors_event_t *>(buffer);
count = numEvents;
} else {
scratch = sanitizedBuffer = new sensors_event_t[numEvents];
for (size_t i = 0; i < numEvents; i++) {
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
scratch[count++] = buffer[i++];
}
}
}
}
sendPendingFlushEventsLocked();
// Early return if there are no events for this connection.
if (count == 0) {
delete sanitizedBuffer;//可能遇到空指针? free 已经做了判断了
return status_t(NO_ERROR);
}
#if DEBUG_CONNECTIONS
mEventsReceived += count;
#endif
//将最新的数据缓存到mEventCache,后面可以dump出来debug
if (mCacheSize != 0) {
// There are some events in the cache which need to be sent first. Copy this buffer to
// the end of cache.
if (mCacheSize + count <= mMaxCacheSize) {
memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
mCacheSize += count;
} else {
// Check if any new sensors have registered on this connection which may have increased
// the max cache size that is desired.
if (mCacheSize + count < computeMaxCacheSizeLocked()) {
reAllocateCacheLocked(scratch, count);
delete sanitizedBuffer;
return status_t(NO_ERROR);
}
// Some events need to be dropped.
int remaningCacheSize = mMaxCacheSize - mCacheSize;
if (remaningCacheSize != 0) {
memcpy(&mEventCache[mCacheSize], scratch,
remaningCacheSize * sizeof(sensors_event_t));
}
int numEventsDropped = count - remaningCacheSize;
countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
// Drop the first "numEventsDropped" in the cache.
memmove(mEventCache, &mEventCache[numEventsDropped],
(mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
// Copy the remainingEvents in scratch buffer to the end of cache.
memcpy(&mEventCache[mCacheSize - numEventsDropped], scratch + remaningCacheSize,
numEventsDropped * sizeof(sensors_event_t));
}
delete sanitizedBuffer;
return status_t(NO_ERROR);
}
int index_wake_up_event = -1;
if (mHasSensorAccess) {
index_wake_up_event = findWakeUpSensorEventLocked(scratch, count);
if (index_wake_up_event >= 0) {
scratch[index_wake_up_event].flags |= WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
++mWakeLockRefCount;
#if DEBUG_CONNECTIONS
++mTotalAcksNeeded;
#endif
}
}
// NOTE: ASensorEvent and sensors_event_t are the same type.
//重点在这边,把scratch里边的数据发出去,
ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
if (size < 0) {
// Write error, copy events to local cache.
if (index_wake_up_event >= 0) {
// If there was a wake_up sensor_event, reset the flag.
scratch[index_wake_up_event].flags &= ~WAKE_UP_SENSOR_EVENT_NEEDS_ACK;
if (mWakeLockRefCount > 0) {
--mWakeLockRefCount;
}
#if DEBUG_CONNECTIONS
--mTotalAcksNeeded;
#endif
}
if (mEventCache == NULL) {
mMaxCacheSize = computeMaxCacheSizeLocked();
mEventCache = new sensors_event_t[mMaxCacheSize];
mCacheSize = 0;
}
memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
mCacheSize += count;
// Add this file descriptor to the looper to get a callback when this fd is available for
// writing.
updateLooperRegistrationLocked(mService->getLooper());
delete sanitizedBuffer;
return size;
}
}
次に、
ssize_t SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents)に従って
、onSensorChange() インターフェイスを通じてアプリケーションにデータを提供する方法を確認します。
android/frameworks/native/libs/sensor/SensorEventQueue.cpp
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
見る一下
ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize)
android/frameworks/native/libs/sensor/BitTube.cpp
ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize)
{
//SensorService::SensorEventConnection::mChannel::write()
//mChannel 为 BitTube 对象
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d sending %d events", size, count);
次に、BitTube::write(void const* vaddr, size_t size) に進み、次を見てみましょう。
ssize_t BitTube::write(void const* vaddr, size_t size)
{
ssize_t err, len;
do {
//这边通过 unix域套接字 发出去
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
// cannot return less than size, since we're using SOCK_SEQPACKET
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
次に、受信側からそれを分析し、どこで受信されたかを確認する必要があります (android_hardware_SensorManager.cpp Receiver で受信)
具体的なプロセスは何ですか? アプリケーションに戻って、SensorManager を通じてセンサーを登録する必要があります。
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
if (listener == null || sensor == null) {
Log.e(TAG, "sensor or listener is null");
return false;
}
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
//一个SensorEventListener对应一个SensorEventQueue,并装在hashmap mSensorListeners里边
// We map SensorEventListener to a SensorEventQueue, which holds the looper
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName =
listener.getClass().getEnclosingClass() != null
? listener.getClass().getEnclosingClass().getName()
: listener.getClass().getName();
queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
SensorEventListener (アプリケーション自体によって作成される) が以前に SensorEventQueue を作成していない場合は、SensorEventQueue を作成し、SensorEventListener とともに mSensorListeners に追加します。重要な点はここです。SensorEventQueue が作成されると、その親クラス オブジェクト BaseEventQueue が構築され
ます同時に、nativeInitBaseEventQueue() メソッドで、
jni は
android/frameworks/base/core/jni/android_hardware_SensorManager.cppを呼び出して
、データを受信する Receiver オブジェクトを作成します。
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
if (queue == NULL) {
jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
return 0;
}
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);//获取MessageQueue
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
clientName に基づいて SensorEventQueue を作成し、次に Receiver を作成して、そのコンストラクターを確認します。
Receiver(const sp<SensorEventQueue>& sensorQueue,
const sp<MessageQueue>& messageQueue,
jobject receiverWeak) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
//保存传进来的2个比较关键的对象引用
mSensorQueue = sensorQueue;
mMessageQueue = messageQueue;
mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak);
mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16));
mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16));
}
onFirstRef()をもう一度見てください
virtual void onFirstRef() {
LooperCallback::onFirstRef();
//获取套接字fd
mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0,
ALOOPER_EVENT_INPUT, this, mSensorQueue.get());
}
//作成された SensorEventQueue をここで取得します==>BitTube の unix ソケットを通じて作成された mReceiveFd が
ルーパーに追加されます。
android/system/core/libutils/Looper.cpp では Looper::pollInner() で
、epoll を通じて監視されます。 fd は、イベントが発生すると、Receiver::handleEvent() をコールバックしてから、
virtual int handleEvent(int fd, int events, void* data) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
ssize_t n;
ASensorEvent buffer[16];
//这边最后是通过标准的socket接口recv将数据读取出来,代码在以下位置:
//android/frameworks/native/libs/sensor
//SensorEventQueue::read() ==> BitTube::recvObjects()==>BitTube::read()
while ((n = q->read(buffer, 16)) > 0) {
for (int i=0 ; i<n ; i++) {
if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
// step-counter returns a uint64, but the java API only deals with floats
float value = float(buffer[i].u64.step_counter);
env->SetFloatArrayRegion(mFloatScratch, 0, 1, &value);
} else if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
float value[2];
value[0] = buffer[i].dynamic_sensor_meta.connected ? 1.f: 0.f;
value[1] = float(buffer[i].dynamic_sensor_meta.handle);
env->SetFloatArrayRegion(mFloatScratch, 0, 2, value);
} else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
env->SetIntArrayRegion(mIntScratch, 0, 14,
buffer[i].additional_info.data_int32);
env->SetFloatArrayRegion(mFloatScratch, 0, 14,
buffer[i].additional_info.data_float);
} else {
env->SetFloatArrayRegion(mFloatScratch, 0, 16, buffer[i].data);
}
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
// This is a flush complete sensor event. Call dispatchFlushCompleteEvent
// method.
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
buffer[i].meta_data.sensor);
}
} else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
// This is a flush complete sensor event. Call dispatchAdditionalInfoEvent
// method.
if (receiverObj.get()) {
int type = buffer[i].additional_info.type;
int serial = buffer[i].additional_info.serial;
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchAdditionalInfoEvent,
buffer[i].sensor,
type, serial,
mFloatScratch,
mIntScratch,
buffer[i].timestamp);
}
}else {
int8_t status;
switch (buffer[i].type) {
case SENSOR_TYPE_ORIENTATION:
case SENSOR_TYPE_MAGNETIC_FIELD:
case SENSOR_TYPE_ACCELEROMETER:
case SENSOR_TYPE_GYROSCOPE:
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
status = buffer[i].vector.status;
break;
case SENSOR_TYPE_HEART_RATE:
status = buffer[i].heart_rate.status;
break;
default:
status = SENSOR_STATUS_ACCURACY_HIGH;
break;
}
//关键就在这里,这边通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mFloatScratch,
status,
buffer[i].timestamp);
}
}
if (env->ExceptionCheck()) {
mSensorQueue->sendAck(buffer, n);
ALOGE("Exception dispatching input event.");
return 1;
}
}
//对SensorService::SensorEventConnection发送确认,
//SensorService::SensorEventConnection::handleEvent()接收并确认
mSensorQueue->sendAck(buffer, n);
}
if (n<0 && n != -EAGAIN) {
// FIXME: error receiving events, what to do in this case?
}
return 1;
}
};
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
final Sensor sensor = mManager.mHandleToSensor.get(handle);
if (sensor == null) {
// sensor disconnected
return;
}
SensorEvent t = null;
synchronized (mSensorsEvents) {
t = mSensorsEvents.get(handle);
}
if (t == null) {
// This may happen if the client has unregistered and there are pending events in
// the queue waiting to be delivered. Ignore.
return;
}
// Copy from the values array.
System.arraycopy(values, 0, t.values, 0, t.values.length);
t.timestamp = timestamp;
t.accuracy = inAccuracy;
t.sensor = sensor;
// call onAccuracyChanged() only if the value changes
final int accuracy = mSensorAccuracies.get(handle);
if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
mSensorAccuracies.put(handle, t.accuracy);
mListener.onAccuracyChanged(t.sensor, t.accuracy);
}
mListener.onSensorChanged(t);//在这边,通过多态回调应用开发者自己实现的onSensorChanged(),将sensor事件给到应用
}
この時点で、センサー データがアプリケーションの onSensorChanged() インターフェイスに渡されます。
5. スタンバイ後の SensorService の動作
主な関連クラスは SensorService::UidPolicy で、関連インターフェイスは SensorService::setSensorAccess() および SensorEventConnection::setSensorAccess() です。
一般的なロジックは、SensorService が UidPolicy を使用してから、ActivityManager を使用して、どの新しく作成されたアプリケーション、どのアプリケーションがアイドル状態になり、どのアプリケーションが終了するかを監視し、アプリケーションがセンサーを登録してアイドル状態になると、データはアプリケーションに送信されないというものです。
class UidPolicy : public BnUidObserver {
public:
explicit UidPolicy(wp<SensorService> service)
: mService(service) {}
void registerSelf();
void unregisterSelf();
bool isUidActive(uid_t uid);
//这三个接口重载实现了IUidObserver 声明的接口,
//后面通过多态被调用
void onUidGone(uid_t uid, bool disabled);
void onUidActive(uid_t uid);
void onUidIdle(uid_t uid, bool disabled);
void addOverrideUid(uid_t uid, bool active);
void removeOverrideUid(uid_t uid);
private:
bool isUidActiveLocked(uid_t uid);
void updateOverrideUid(uid_t uid, bool active, bool insert);
Mutex mUidLock;
wp<SensorService> mService;
std::unordered_set<uid_t> mActiveUids;
std::unordered_map<uid_t, bool> mOverrideUids;
};
このクラスの動作は非常に単純なので、分析する前に、SensorService::setSensorAccess() と SensorEventConnection::setSensorAccess() を見てみましょう。
void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
{
Mutex::Autolock _l(mLock);
for (size_t i = 0 ; i < activeConnections.size(); i++) {
//获取到该uid对应的SensorEventConnection
//每个应用有各自的SensorEventConnection,在创建 SensorEventListerner的时候创建,
//有一个或多个,具体有几个取决于应用创建多少个SensorEventListerner
if (activeConnections[i] != 0 && activeConnections[i]->getUid() == uid) {
activeConnections[i]->setSensorAccess(hasAccess);
}
}
}
}
void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
Mutex::Autolock _l(mConnectionLock);
mHasSensorAccess = hasAccess;//将mHasSensorAccess置成true/false
}
その後、アプリケーションの SensorEventConnection::mHasSensorAccess が false になると、データは対応するアプリケーションに送信されなくなります。
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
//......
if (mHasSensorAccess) {
scratch[count++] = buffer[i];
}
//......
}
次に見てください、
void SensorService::UidPolicy::registerSelf() {
ActivityManager am;
am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
| ActivityManager::UID_OBSERVER_IDLE
| ActivityManager::UID_OBSERVER_ACTIVE,
ActivityManager::PROCESS_STATE_UNKNOWN,
String16("android"));
}
SensorService::onFirstRef()で呼び出され、SensorServiceの起動解析時にも述べたように、
登録後はアプリケーションの待機状態(アプリケーションプロセスの生成、破棄、アイドル状態への移行)の監視を開始します。
アプリケーションがアイドル状態になった後、このインターフェイスはコールバックされ、対応する uid を渡すことによって、
コマンド am make-uid-idle com.example.applicationtestproject を使用して、アプリケーションを強制的にデバッグのためにアイドル状態にすることができます。
void SensorService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
ALOGI("%s , uid : %x", __FUNCTION__, (int)uid);
bool deleted = false;
{
Mutex::Autolock _l(mUidLock);
if (mActiveUids.erase(uid) > 0) {
deleted = true;
}
}
if (deleted) {
sp<SensorService> service = mService.promote();
if (service != nullptr) {
service->setSensorAccess(uid, false);
//应用进入idle后,这边设置对应 mHasSensorAccess 为false,那么之后sensor数据就不给应用了
}
}
}
void SensorService::UidPolicy::onUidActive(uid_t uid) {
ALOGI("%s , uid : %x", __FUNCTION__, (int)uid);
{
Mutex::Autolock _l(mUidLock);
mActiveUids.insert(uid);
}
sp<SensorService> service = mService.promote();
if (service != nullptr) {
service->setSensorAccess(uid, true);//置对应 mHasSensorAccess 为 true
}
}
このインターフェイスは、アプリケーションがアイドル状態で終了した後、ActivityManager によってコールバックされます。
GoogleがAndroid9のSensorServiceに実装したスタンバイ関連の仕組みを簡単に言うと、アプリがアイドル状態になった後は
センサーデータをアプリに与えず、ユーザーのプライバシーが確保されないようにするというものです。
携帯電話メーカーは、消費電力を節約するために、実際にここで最適化を行うことができます。つまり、センサーを保持しているすべてのアプリケーションがアイドル状態になると、すべてのセンサーがオフになります
。
6. フュージョンセンサー(SensorFusion)
SensorFusionはおそらくここでセンサーを仮想化し、複数のセンサーからデータを取得し、それを入力として他の情報と組み合わせ、最終的にアルゴリズム処理を通じて仮想センサーデータを出力することができますが、基本的に携帯電話メーカーには使用されません。消費電力を削減するため、ドライバに実装されています。もう 1 つの理由は、この機能はユーザーがサードパーティの ROM をフラッシュした後は機能しなくなるため、ドライバ層に実装されていない場合は、ベンダー層にも実装されます。 、ここでは分析しません。
7. SensorService をコンパイルする
android/frameworks/native/service/SensorService ディレクトリに直接 mm して、
コンパイル後、out ディレクトリに libsensorservice.so が生成され、system/lib system/lib64 に 1 つありますので、それを携帯電話の対応するディレクトリにプッシュするだけです。
adbルート
adbの再マウント
adb プッシュアウト/....../system/lib/libsensorservice.so /system/lib
adb プッシュアウト/....../system/lib64/libsensorservice.so /system/lib64
8、ダンプシスセンサーサービス
SensorService はダンプ インターフェイスを実装しています。問題をデバッグするとき、分析を支援するために、adb Shell dumpsys sensorservice を通じてセンサー情報をダンプできます 。現在のダンプ インターフェイスには主に次の情報が含まれています:
(1) 携帯電話で使用可能なすべてのセンサーに適用します。 android 定義されたセンサーとメーカー定義のセンサー
(2) アプリケーション パッケージ名に対応するいくつかのセンサーが現在、アプリケーションによって有効になっています
(3) 最新のセンサー データ、
(4) 最新のセンサー スイッチ レコード、および対応するアプリケーション パッケージ名前
9. Android センサーの hal 層が開始します
Android によって実装されたセンサー hal レイヤーは、デーモン サービスとして実行され、hidl を通じて呼び出されます。コードの場所は、android/hardware/interfaces/sensors/1.0 です。android /hardware/libhardware/modules/sensors によって提供されるインターフェイスは、次の場所で定義されています。
ISensors.hal には、主にgetSensorsList()
があります。//すべてのセンサーのリンクされたリストを取得しますactivate()//センサーを開く/閉じるpoll()//センサー データを取得するバッチ()//サンプリング レートを設定しますflash()//リフレッシュバッファ
Android.bp からわかるように、
cc_binary {
name: "[email protected]",
relative_install_path: "hw",
vendor: true,
init_rc: ["[email protected]"],
defaults: ["hidl_defaults"],
srcs: ["service.cpp"],
shared_libs: [
"liblog",
"libcutils",
"libdl",
"libbase",
"libutils",
"libhidlbase",
"libhidltransport",
"[email protected]",
"libhwbinder",
],
arch: {
arm: {
cflags: ["-DARCH_ARM_32"],
},
},
}
サービス名は [email protected] です。
service.cpp を bin プログラムにコンパイルし、 [email protected]、
service Vendor.sensors-hal-1-0 /vendor/bin/hw/[email protected]を通じて起動します。
クラス hal
ユーザー システム
グループ システム ウェイクロック入力
機能 BLOCK_SUSPEND
rlimit rtprio 10 10
service.cpp を見てください。
int main() {
#ifdef ARCH_ARM_32
android::hardware::ProcessState::initWithMmapSize((size_t)getHWBinderMmapSize());
#endif
/* Sensors framework service needs at least two threads.
* One thread blocks on a "poll"
* The second thread is needed for all other HAL methods.
*/
return defaultPassthroughServiceImplementation<ISensors>(2);
}
defaultPassthroughServiceImplementation() を通じて、ServiceManager に自分自身をサービスとして登録します。
Sensors.cpp から開始し、
//ServiceManager によって呼び出される最初の関数はこの関数です
ISensors *HIDL_FETCH_ISensors(const char * /* hal */) {
Sensors *sensors = new Sensors;
LOG(ERROR) << "=======>lkh HIDL_FETCH_ISensors";
android::CallStack stack("=======>lkh ");
if (sensors->initCheck() != OK) {
delete sensors;
sensors = nullptr;
return nullptr;
}
return sensors;
}
Sensors インスタンスを作成すると、hidl を介してセンサー hal を呼び出すすべてのインターフェイスが、Sensors によって実装されたインターフェイスを呼び出します。
Sensors::Sensors()
: mInitCheck(NO_INIT),
mSensorModule(nullptr),
mSensorDevice(nullptr) {
status_t err = OK;
//若文件/vendor/etc/sensors/hals.conf存在,
//打开哪些库就根据这个配置文件里边的库的名字来打开,
//供应商要开发自己sensor库的话,也可以将自己的库名字添加进去,
//比如高通骁龙845 855,hal层库名字叫sensors-hal,直接在hals.conf 填下 sensors-hal就ok了,
LOG(ERROR) << "=======>lkh Sensors construct";
android::CallStack stack("=======>lkh ");
if (UseMultiHal()) {
mSensorModule = ::get_multi_hal_module_info();
} else {
err = hw_get_module(
SENSORS_HARDWARE_MODULE_ID,
(hw_module_t const **)&mSensorModule);
}
if (mSensorModule == NULL) {
err = UNKNOWN_ERROR;
}
if (err != OK) {
LOG(ERROR) << "Couldn't load "
<< SENSORS_HARDWARE_MODULE_ID
<< " module ("
<< strerror(-err)
<< ")";
mInitCheck = err;
return;
}
//当这个函数返回时,mSensorDevice里边装的是
//multihal.cpp open_sensors()里边的 dev->proxy_device
//所以之后 mSensorDevice->activate(),mSensorDevice->poll(),mSensorDevice->batch()等接口调用,
//其实现都是调用了multihal.cpp 的device__activate(),device__poll(),device__batch()
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
if (err != OK) {
LOG(ERROR) << "Couldn't open device for module "
<< SENSORS_HARDWARE_MODULE_ID
<< " ("
<< strerror(-err)
<< ")";
mInitCheck = err;
return;
}
// Require all the old HAL APIs to be present except for injection, which
// is considered optional.
CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
if (mSensorDevice->inject_sensor_data == nullptr) {
LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()";
}
if (mSensorModule->set_operation_mode == nullptr) {
LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()";
}
}
mInitCheck = OK;
}
次に sensors_open_1()
android/hardware/libhardware/include/hardware/sensors.h を参照してください。
static inline int sensors_open_1(const struct hw_module_t* module,
sensors_poll_device_1_t** device) {
return module->methods->open(module,
SENSORS_HARDWARE_POLL, TO_HW_DEVICE_T_OPEN(device));
}
このうち
#define TO_HW_DEVICE_T_OPEN(x) reinterpret_cast<struct hw_device_t**>(x) は、
sensors_poll_device_1_t** 型を hw_device_t にキャストし、
関数 open_sensors() のパラメータとして渡します。
次に、android/hardware/libhardware/modules/sensors/multihal.cpp が続きます。
static int open_sensors(const struct hw_module_t* hw_module, const char* name,
struct hw_device_t** hw_device_out) {
ALOGV("open_sensors begin...");
lazy_init_modules();//这边dlopen手机厂商或第三方供应商实现的那个sensor库
//将获取到的hw_module_t保存起来
// Create proxy device, to return later.
sensors_poll_context_t *dev = new sensors_poll_context_t();
memset(dev, 0, sizeof(sensors_poll_device_1_t));
dev->proxy_device.common.tag = HARDWARE_DEVICE_TAG;
dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_4;
dev->proxy_device.common.module = const_cast<hw_module_t*>(hw_module);
dev->proxy_device.common.close = device__close;
dev->proxy_device.activate = device__activate;
dev->proxy_device.setDelay = device__setDelay;
dev->proxy_device.poll = device__poll;
dev->proxy_device.batch = device__batch;
dev->proxy_device.flush = device__flush;
dev->proxy_device.inject_sensor_data = device__inject_sensor_data;
dev->proxy_device.register_direct_channel = device__register_direct_channel;
dev->proxy_device.config_direct_report = device__config_direct_report;
dev->nextReadIndex = 0;
// Open() the subhal modules. Remember their devices in a vector parallel to sub_hw_modules.
for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
it != sub_hw_modules->end(); it++) {
sensors_module_t *sensors_module = (sensors_module_t*) *it;
struct hw_device_t* sub_hw_device;
//这边,就会去调用手机厂商或第三方供应商实现的那个sensor库里边实现的open函数,
//进而将其对hw_device_t的实现装到sub_hw_device里边,存储在 sensors_poll_context_t::sub_hw_devices里边
//之后, 所有对下hal层的调用,都通过该函数传出去的*hw_device_out(即proxy_device),
//类型强转获取到这边创建的dev(首地址相同),然后调用sensors_poll_context_t实现的接口,
//进而在这里边调用sub_hw_devices里边存储的从OEM HAL层获取的对应接口的实现(装在hw_device_t里边)。
int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);
if (!sub_open_result) {
if (!HAL_VERSION_IS_COMPLIANT(sub_hw_device->version)) {
ALOGE("SENSORS_DEVICE_API_VERSION_1_3 or newer is required for all sensor HALs");
ALOGE("This HAL reports non-compliant API level : %s",
apiNumToStr(sub_hw_device->version));
ALOGE("Sensors belonging to this HAL will get ignored !");
}
dev->addSubHwDevice(sub_hw_device);//用vector保存起来,后面调用OEM HAL层接口实现时重新取出来
}
}
// Prepare the output param and return
*hw_device_out = &dev->proxy_device.common;
//这里边将proxy_device.common的地址装进去,实际上也是proxy_device的地址(common为其第一个成员,因此地址相同),
ALOGV("...open_sensors end");
return 0;
}
ここで渡されるアドレスは hw_device_t タイプのアドレス &dev->proxy_device.common ですが、これは sensors_poll_device_1 の最初のメンバーであり、sensors_poll_device_1 は sensors_poll_context_t の最初のメンバーであり、ここで作成されるのは実際には sensors_poll_context_t オブジェクトであることに注意してください
。したがって、後で &dev->proxy_device.common タイプの強制転送を通じて proxy_device と dev の最初のアドレスを取得できます。
上記の分析の場合、たとえば、SensorService によって HIDL 経由で呼び出される activate インターフェイスの場合、
android/hardware/interfaces/sensors/1.0/default/Sensors.cpp に到達します。
Return<Result> Sensors::activate(
int32_t sensor_handle, bool enabled) {
return ResultFromStatus(
mSensorDevice->activate(
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
sensor_handle,
enabled));
}
//そして、android/hardware/libhardware/modules/sensors/multihal.cpp に到達します。
static int device__activate(struct sensors_poll_device_t *dev, int handle,
int enabled) {
sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
return ctx->activate(handle, enabled);
}
読む
int sensors_poll_context_t::activate(int handle, int enabled) {
int retval = -EINVAL;
ALOGV("activate");
//这边将前面分析的open_sensors()里边获取到的OEM HAL层实现的hw_device_t取出来,
//进而调用OEM HAL层对activate的实现。
int local_handle = get_local_handle(handle);
sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
retval = v0->activate(v0, local_handle, enabled);
} else {
ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
enabled, handle);
}
ALOGV("retval %d", retval);
return retval;
}
この時点で、Android HAL レイヤーが開始されており、hidl クライアントからの呼び出しに応答して、OEM HAL レイヤーのインターフェイスを呼び出すことができます。
10. SensorManager が起動します
(1)SystemSensorManagerの起動処理
SystemSensorManager は SensorManager インターフェイスを継承して実装します。アプリケーションは SensorManager インターフェイスを呼び出すことでニーズを満たします。
実際の関数実装者は SystemSensorManager (ポリモーフィック テクノロジ) です。
まず SystemSensorManager の起動プロセスを見てみましょう。インスタンスを作成するためのコール スタックは次のとおりです:
05-21 16:01:29.257 1813 1885 E ======>lkh: android.hardware.SystemSensorManager.<init>(SystemSensorManager.java:147)
05-21 16:01:29.257 1813 1885 E == ====>lkh: android.app.SystemServiceRegistry$33.createService(SystemServiceRegistry.java:476)
05-21 16:01:29.257 1813 1885 E ======>lkh: android.app.SystemServiceRegistry$33 で.createService(SystemServiceRegistry.java:472)
05-21 16:01:29.257 1813 1885 E ======>lkh: android.app.SystemServiceRegistry$CachedServiceFetcher.getService(SystemServiceRegistry.java:1200)
05-21 16 :01:29.257 1813 1885 E ======>lkh: android.app.SystemServiceRegistry.getSystemService(SystemServiceRegistry.java:1116) で
05-21 16:01:29.257 1813 1885 E ======>lkh: android.app.ContextImpl.getSystemService(ContextImpl.java:1739)
05-21 16:01:29.257 1813 1885 E ==== ==>lkh: com.android.server.policy.WakeGestureListener.<init>(WakeGestureListener.java:43)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android で.server.policy.PhoneWindowManager$MyWakeGestureListener.<init>(PhoneWindowManager.java:1407)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android.server.policy.PhoneWindowManager で。 init(PhoneWindowManager.java:2665)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android.server.policy.OemPhoneWindowManager.init(OemPhoneWindowManager.java:410)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android.server.wm.WindowManagerService$4.run(WindowManagerService.java:1236)
05-21 16:01:29.257 1813 1885 E ======>lkh: android.os.Handler$BlockingRunnable.run(Handler.java:893)
05-21 16:01:29.257 1813 1885 E ======>lkh: android で。 os.Handler.handleCallback(Handler.java:873)
05-21 16:01:29.257 1813 1885 E ======>lkh: android.os.Handler.dispatchMessage(Handler.java:99)
05-21 16:01:29.257 1813 1885 E ======>lkh: android.os.Looper.loop(Looper.java:193)
05-21 16:01:29.257 1813 1885 E ======> lkh: android.os.HandlerThread.run(HandlerThread.java:65)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android.server.ServiceThread.run(ServiceThread. java:44)
05-21 16:01:29.257 1813 1885 E ======>lkh: com.android.server.UiThread.run(UiThread.java:43) で
起動時に android/frameworks/base/core/java/android/app/SystemServiceRegistry.java にインスタンスが作成される
registerService(Context.SENSOR_SERVICE, SensorManager.class,
new CachedServiceFetcher<SensorManager>() {
@Override
public SensorManager createService(ContextImpl ctx) {
return new SystemSensorManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler().getLooper());
}});
SystemSensorManager のコンストラクターを見てみましょう
public SystemSensorManager(Context context, Looper mainLooper) {
synchronized (sLock) {
if (!sNativeClassInited) {
sNativeClassInited = true;
nativeClassInit();//native层offset初始化,没做什么其他事情
}
}
Log.e("======>lkh", Log.getStackTraceString(new Throwable()));
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
//mNativeInstance 保存native创建的 c++对象 SensorManager的引用,
//该对象通过getOpPackageName()返回的结果作为参数创建,并且2者保存在一个map里边,
//注意,此SensorManager为native层c++实现的,非面向应用用Java实现的SensorManager
// initialize the sensor list
for (int index = 0;; ++index) {
Sensor sensor = new Sensor();
if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
mFullSensorsList.add(sensor);
mHandleToSensor.put(sensor.getHandle(), sensor);
}
//获取SesorService的sensor list里边的所有sensor,每个sensor创建一个对应的java层的Sensor对象,
//并保存到链表里边,并将sensor handle和sensor一并保存到map里边
}
(2) ネイティブ層SensorManager起動処理
上記でわかるように、SensorManager の作成では、jni を介して android_hardware_SensorManager を呼び出し、
次に初期化のためにその静的インターフェイス getInstanceForPackage() を呼び出すことによって SystemSensorManager が初期化
されます。
SensorManager::SensorManager(const String16& opPackageName)
: mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
// okay we're not locked here, but it's not needed during construction
assertStateLocked();
}
// SystemSensorManager によって渡された opPackageName を保存します
status_t SensorManager::assertStateLocked() {
bool initSensorManager = false;
if (mSensorServer == NULL) {
initSensorManager = true;
} else {
// Ping binder to check if sensorservice is alive.
status_t err = IInterface::asBinder(mSensorServer)->pingBinder();
if (err != NO_ERROR) {
initSensorManager = true;
}
}
if (initSensorManager) {
waitForSensorService(&mSensorServer);
LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, "getService(SensorService) NULL");
class DeathObserver : public IBinder::DeathRecipient {
SensorManager& mSensorManager;
virtual void binderDied(const wp<IBinder>& who) {
ALOGW("sensorservice died [%p]", who.unsafe_get());
mSensorManager.sensorManagerDied();
}
public:
explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
mSensors = mSensorServer->getSensorList(mOpPackageName);
size_t count = mSensors.size();
mSensorList =
static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL");
for (size_t i=0 ; i<count ; i++) {
mSensorList[i] = mSensors.array() + i;
}
}
return NO_ERROR;
}
主にやるべきことは 3 つあります
1. 起動時に SensorService が起動するのを待ち、そのポインタを取得します
2. DeathObserver を登録します (これの具体的な仕組みはまだ見ていません。オブザーバー モードを使用しているはずです)。 SensorService がハングアップします。このとき、
クリーニング後の操作を実行するために、登録されたインターフェイスが呼び出されます。この場合、それは sensorManagerDied() インターフェイスです。)
3. sensorlist 内の各センサー オブジェクトのアドレスを取得します。