赞
踩
来个时序图,按图索骥
整个android sensor模块的核心是SensorService,应用通过SensorManager与其交互,SensorService基本上管理sensor的所有行为,包括
// ./frameworks/base/services/java/com/android/server/SystemServer.java /** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } public final class SystemServer { private static final String TAG = "SystemServer"; private void run() { // Initialize native services. System.loadLibrary("android_servers"); // Start services. try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); } ... private void startBootstrapServices() { // The sensor service needs access to package manager service, app ops // service, and permissions service, therefore we start it after them. mSystemServiceManager.startService(SensorService.class); } } //SensorService.java public class SensorService extends SystemService { private static final String START_NATIVE_SENSOR_SERVICE = "StartNativeSensorService"; /** Start the sensor service. This is a blocking call and can take time. */ private static native long startSensorServiceNative(ProximityActiveListener listener); private static native void registerProximityActiveListenerNative(long ptr); private static native void unregisterProximityActiveListenerNative(long ptr); public SensorService(Context ctx) { super(ctx); synchronized (mLock) { mSensorServiceStart = SystemServerInitThreadPool.submit(() -> { TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog(); traceLog.traceBegin(START_NATIVE_SENSOR_SERVICE); long ptr = startSensorServiceNative(new ProximityListenerDelegate()); synchronized (mLock) { mPtr = ptr; } traceLog.traceEnd(); }, START_NATIVE_SENSOR_SERVICE); } } }
通过对JNI的了解 System.loadLibrary(“android_servers”); 会去查找libandroid_servers.so 这个库文件
cc_library_shared {
name: "libandroid_servers",
defaults: ["libservices.core-libs"],
whole_static_libs: ["libservices.core"],
}
//frameworks/base/services/core/jni/onload.cpp extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { ALOGE("GetEnv failed!"); return result; } ALOG_ASSERT(env, "Could not retrieve the env!"); ... register_android_server_sensor_SensorService(vm, env); return JNI_VERSION_1_4; } //frameworks/base/services/core/jni/com_android_server_sensor_SensorService.cpp static const JNINativeMethod methods[] = { { "startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J", reinterpret_cast<void*>(startSensorServiceNative) }, { "registerProximityActiveListenerNative", "(J)V", reinterpret_cast<void*>(registerProximityActiveListenerNative) }, { "unregisterProximityActiveListenerNative", "(J)V", reinterpret_cast<void*>(unregisterProximityActiveListenerNative) }, }; int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) { sJvm = vm; jclass listenerClass = FindClassOrDie(env, PROXIMITY_ACTIVE_CLASS); sMethodIdOnProximityActive = GetMethodIDOrDie(env, listenerClass, "onProximityActive", "(Z)V"); return jniRegisterNativeMethods(env, "com/android/server/sensors/SensorService", methods, NELEM(methods)); } static jlong startSensorServiceNative(JNIEnv* env, jclass, jobject listener) { NativeSensorService* service = new NativeSensorService(env, listener); return reinterpret_cast<jlong>(service); } NativeSensorService::NativeSensorService(JNIEnv* env, jobject listener) : mProximityActiveListenerDelegate(new ProximityActiveListenerDelegate(env, listener)) { if (base::GetBoolProperty("system_init.startsensorservice", true)) { sp<IServiceManager> sm(defaultServiceManager()); mService = new SensorService();//进入到SensorService sm->addService(String16(SensorService::getServiceName()), mService, false /* allowIsolated */, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); } }
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
总结下sensorservice启动过程
系统初始化进程加载,启动SystemServer,Zygote中会执行SystemServier main方法,导致其run方法被调用;
加载本地库文件, System.loadLibrary(“android_servers”); 获取本地方法;
被加载到的JNI库文件导致JNI_Onload函数被调用;调用本地jni文件
注册本地方法jniRegisterNativeMethods 数组;
完成Java 到 C++ 函数绑定,使Java能否访问到C库中的函数;
启动startBootstrapServices();
最后调用native方法 native void startSensorService();
JNI文件com_android_server_SystemServer.cpp,绑定的函数数组,由java的startSensorService方法绑定到
android_server_SystemServer_startSensorService函数;
C++函数中,start_sensor_service被调用;
调用SensorService的调用publish
创建一个Serivces,通过sm->addService 来添加到android中去; sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); 其中sm是ServiceManager的引用:sp sm(defaultServiceManager());
SensorService继承关系
Sensorservice : public BnSensorServer
BnSensorServer : public BnInterface<ISensorService>
BnInterface : public BBinder
BBinder : public IBinder
IBinder : public virtual RefBase // 对象第一次强引用时自动调用onFirstRef方法
void SensorService::onFirstRef() { // 在 SensorDevice 的构造函数中,会建立和hal层的连接 SensorDevice& dev(SensorDevice::getInstance()); //....... if (dev.initCheck() == NO_ERROR) { // 通过 SensorDevice,调用 Sensor HAL 提供的 get_sensors_list 接口,获取所支持的 Sensor 信息获,调用registerSensor函数把Sensor保存起来 sensor_t const* list; ssize_t count = dev.getSensorList(&list); //....... for (ssize_t i=0 ; i<count ; i++) { //....... if (useThisSensor) { registerSensor( new HardwareSensor(list[i]) ); } } //SensorFusion功能,传感融合。它的主要作用就是,按照一定的算法计算系统的多个传感器对某一个值的上报的数据,得到更准确的值。 // it's safe to instantiate the SensorFusion object here // (it wants to be instantiated after h/w sensors have been // registered) SensorFusion::getInstance(); //注册虚拟传感器:这些虚拟的传感器步会产生真的数据,而是通过SensorFusion功能计算得到的值,作为虚拟传感的数据。 //虚拟sensor就是拿一个或多个物理sensor通过算法处理得到的,比如自动转屏,根据加速度算出来 //虚拟sensor的算法一直在跑,跑在ap侧功耗高,手机厂家会实现在协处理器里边,比如枭龙845,而不是直接用谷歌在fwk实现的那套算法 registerSensor(new RotationVectorSensor(), !needRotationVector, true); registerSensor(new OrientationSensor(), !needRotationVector, true); //....... // 初始化一些Buffer,用他们保存sensor硬件上报的数据 mLooper = new Looper(false); const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT; mSensorEventBuffer = new sensors_event_t[minBufferSize]; mSensorEventScratch = new sensors_event_t[minBufferSize]; mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize]; mCurrentOperatingMode = NORMAL; //....... //创建一个 Looper 和 SensorEventAckReceiver。其中 Looper 用于 enable sensor 后,进行数据的接收;而 SensorEventAckReceiver 则用于在 dispatch wake up sensor event 给上层后,接收上层返回的确认 ACK。 mAckReceiver = new SensorEventAckReceiver(this); //在run里边调用SensorEventAckReceiver::threadLoop()方法, //至于threadLoop是如何被调用的,感兴趣的读者可以跟一下源码, //大概是在android/system/core/libutils/Threads.cpp 里边, //通过pread_create() 创建一个线程运行thread::_threadLoop, //在这里边调用其子类(也就是SensorEventAckReceiver)的threadLoop, mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY); //SensorService 不仅是一个服务,而且他还是一个线程,初始化工作的最后就是启动该线程执行threadLoop函数。threadLoop函数主要的工作就是,循环读取sensor硬件上传上来的数据,然后分发给应用。 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继承了Singleton类,设计成单例,后面要用的话用getinstance()的方式, 为何用单例?是因为sensorservice会有多个线程与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获取 android.hardware.sensors@1.0-service mSensors = ISensors::getService(); if (mSensors == nullptr) { // no sensor hidl service found break; } //....... } return (mSensors != nullptr); }
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就行了 //还记得mSensorEventBuffer,sensorservice中256个sensor_event_t 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; }
到此,sensorservice已经启动,能够接收binder通信发过来的enable(),disable(),flush()等请求。也能够读取hal层的数据给到 应用
可留到最后再看
主要的相关类为SensorService::UidPolicy,相关接口为 SensorService::setSensorAccess()和SensorEventConnection::setSensorAccess(),
大致逻辑是SensorService会通过UidPolicy进而通过ActivityManager来监听有哪些新创建的应用,哪些应用进入idle,哪些应用退出,然后当应用注册sensor并且进入idle后,就不将数据发送给应用.
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; }; 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启动的时候有说了下,
注册后开始监听应用的待机状态(应用进程的创建,销毁,进入idle)
应用进入idle后该接口被回调,传入其对应的uid
可通过该指令 am make-uid-idle com.example.applicationtestproject 强行让应用进入idle进行调试
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 } }
应用退出idle后该接口被ActivityManager回调
简单来讲,google在android9 的SensorService实现的待机相关机制就是,应用进入idle后,
就不将sensor数据给到应用,保证用户隐私不被获取。
对于手机厂家,为了节省功耗,其实还可以在这边做一个优化,就是当持有该sensor的所有应用都进入idle后,
就关闭所有sensor。
SensorFusion
SensorFusion大概是在这可以虚拟出sensor,取多个sensor的数据,可以再结合其他信息作为输入,通过算法处理最后输出虚拟sensor数据,
基本上对于手机厂商是不会用到的,原因一个是为了降低功耗所以做到驱动里边,另一个原因是用户刷第三方rom后该功能就没了,所以如果不做在驱动层也会做到vendor层,在这不做分析了。
dumpsys sensorservice
SensorService 实现了dump接口,debug问题时,可以通过 adb shell dumpsys sensorservice
将sensor信息dump出来协助分析,目前的dump接口主要包含以下几个信息:
public class SensorActivity extends Activity implements SensorEventListener { private final SensorManager mSensorManager; private final Sensor mAccelerometer; public SensorActivity() { mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); } protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void onSensorChanged(SensorEvent event) { } }
//frameworks/base/core/java/android/app/ContextImpl.java @Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); } //frameworks/base/core/java/android/app/SystemServiceRegistry.java public static Object getSystemService(ContextImpl ctx, String name) { //SYSTEM_SERVICE_FETCHERS 是一个HashMap,何时put? ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; } //fetcher是缓存,何时new,在静态代码中 static { registerService(Context.SENSOR_SERVICE, SensorManager.class, new CachedServiceFetcher<SensorManager>() { @Override public SensorManager createService(ContextImpl ctx) { return new SystemSensorManager(ctx.getOuterContext(), ctx.mMainThread.getHandler().getLooper()); }}); ... } //以上,getSystemService->registerService->static //SystemServiceRegistry private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); }
//SystemSensorManager.java public class SystemSensorManager extends SensorManager { private static native void nativeClassInit(); private static native long nativeCreate(String opPackageName); private static native boolean nativeGetSensorAtIndex(long nativeInstance, Sensor sensor, int index); /** {@hide} */ public SystemSensorManager(Context context, Looper mainLooper) { synchronized (sLock) { if (!sNativeClassInited) { sNativeClassInited = true; nativeClassInit(); } } mMainLooper = mainLooper; ApplicationInfo appInfo = context.getApplicationInfo(); mTargetSdkLevel = appInfo.targetSdkVersion; mContext = context; mNativeInstance = nativeCreate(context.getOpPackageName()); mIsPackageDebuggable = (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE)); PackageManager packageManager = context.getPackageManager(); mHasHighSamplingRateSensorsPermission = (PERMISSION_GRANTED == packageManager.checkPermission( HIGH_SAMPLING_RATE_SENSORS_PERMISSION, appInfo.packageName)); // initialize the sensor list for (int index = 0;; ++index) { Sensor sensor = new Sensor(); //native sensor转变成java sensor if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break; mFullSensorsList.add(sensor); mHandleToSensor.put(sensor.getHandle(), sensor); } } }
SystemSensorManager构造中调用 nativeClassInit
, nativeClassInit
nativeGetSensorAtIndex
插句题外话
SystemSensorManager jni注册流程同Log.java类似,zygote->AndroidRuntime::startReg()->android_hardware_sensormanager.cpp->nativeMehtod
注意与SensorService jni的启动时机
SensorService是SystemServer进程起来后完成注册,jni在 base/servvice/core ,通过 System.load(“android_server”)
frameworks/base/services/core/jni/com_android_server_SystemServer.cpp
SensorManager的jni是zygote起来之后。base/core zygote->AndroidRuntime::startReg()->android_hardware_sensormanager.cpp->nativeMehtod
frameworks/base/core/jni/android_hardware_SensorManager.cpp
public SystemSensorManager(Context context, Looper mainLooper) { synchronized (sLock) { if (!sNativeClassInited) { sNativeClassInited = true; nativeClassInit(); } } mMainLooper = mainLooper; ApplicationInfo appInfo = context.getApplicationInfo(); mTargetSdkLevel = appInfo.targetSdkVersion; mContext = context; mNativeInstance = nativeCreate(context.getOpPackageName()); mIsPackageDebuggable = (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE)); PackageManager packageManager = context.getPackageManager(); mHasHighSamplingRateSensorsPermission = (PERMISSION_GRANTED == packageManager.checkPermission( HIGH_SAMPLING_RATE_SENSORS_PERMISSION, appInfo.packageName)); // 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); } }
SystemSensorManager.java构造函数先调用 nativeClassInit 和 nativeGetSensorAtIndex 获取系统支持的所有 Sensor 的参数(nativeClassInit 只会调用一次),包括名称、类型等参数。
SystemSensorManager构造有几个nave方法
获取Sensor.java类的成员变量和成员函数,保存到gSensorOffsets中
/* * nativeClassInit is not inteneded to be thread-safe. It should be called before other native... * functions (except nativeCreate). */ static void nativeClassInit (JNIEnv *_env, jclass _this) { //android.hardware.Sensor SensorOffsets& sensorOffsets = gSensorOffsets; jclass sensorClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "android/hardware/Sensor")); sensorOffsets.clazz = sensorClass; sensorOffsets.name = GetFieldIDOrDie(_env, sensorClass, "mName", "Ljava/lang/String;"); sensorOffsets.vendor = GetFieldIDOrDie(_env, sensorClass, "mVendor", "Ljava/lang/String;"); sensorOffsets.version = GetFieldIDOrDie(_env, sensorClass, "mVersion", "I"); sensorOffsets.handle = GetFieldIDOrDie(_env, sensorClass, "mHandle", "I"); sensorOffsets.range = GetFieldIDOrDie(_env, sensorClass, "mMaxRange", "F"); sensorOffsets.resolution = GetFieldIDOrDie(_env, sensorClass, "mResolution","F"); sensorOffsets.power = GetFieldIDOrDie(_env, sensorClass, "mPower", "F"); sensorOffsets.minDelay = GetFieldIDOrDie(_env, sensorClass, "mMinDelay", "I"); sensorOffsets.fifoReservedEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoReservedEventCount", "I"); sensorOffsets.fifoMaxEventCount = GetFieldIDOrDie(_env,sensorClass, "mFifoMaxEventCount", "I"); sensorOffsets.stringType = GetFieldIDOrDie(_env,sensorClass, "mStringType", "Ljava/lang/String;"); sensorOffsets.requiredPermission = GetFieldIDOrDie(_env,sensorClass, "mRequiredPermission", "Ljava/lang/String;"); sensorOffsets.maxDelay = GetFieldIDOrDie(_env,sensorClass, "mMaxDelay", "I"); sensorOffsets.flags = GetFieldIDOrDie(_env,sensorClass, "mFlags", "I"); sensorOffsets.setType = GetMethodIDOrDie(_env,sensorClass, "setType", "(I)Z"); sensorOffsets.setUuid = GetMethodIDOrDie(_env,sensorClass, "setUuid", "(JJ)V"); sensorOffsets.init = GetMethodIDOrDie(_env,sensorClass, "<init>", "()V"); // java.util.List; ListOffsets& listOffsets = gListOffsets; jclass listClass = (jclass) MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/util/List")); listOffsets.clazz = listClass; listOffsets.add = GetMethodIDOrDie(_env,listClass, "add", "(Ljava/lang/Object;)Z"); // initialize java.lang.String and empty string intern StringOffsets& stringOffsets = gStringOffsets; stringOffsets.clazz = MakeGlobalRefOrDie(_env, FindClassOrDie(_env, "java/lang/String")); stringOffsets.intern = GetMethodIDOrDie(_env, stringOffsets.clazz, "intern", "()Ljava/lang/String;"); ScopedLocalRef<jstring> empty(_env, _env->NewStringUTF("")); stringOffsets.emptyString = (jstring) MakeGlobalRefOrDie(_env, _env->CallObjectMethod(empty.get(), stringOffsets.intern)); }
mNativeInstance = nativeCreate(context.getOpPackageName());
nativeCreate 创建Native层 SensorManager 建立与SensorService的连接
frameworks/native/libs/sensor/SensorManager.cpp:Sensor 在 Native 层的客户端,负责与服务端 SensorService.cpp 的通信
//frameworks/base/core/jni/android_hardware_SensorManager.cpp static jlong nativeCreate (JNIEnv *env, jclass clazz, jstring opPackageName) { ScopedUtfChars opPackageNameUtf(env, opPackageName); return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str())); } //frameworks/native/libs/sensor/SensorManager.cpp //传入包名 SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) { waitForSensorService(nullptr); Mutex::Autolock _l(sLock); SensorManager* sensorManager; auto iterator = sPackageInstances.find(packageName); if (iterator != sPackageInstances.end()) { sensorManager = iterator->second; } else { String16 opPackageName = packageName; // It is possible that the calling code has no access to the package name. // In this case we will get the packages for the calling UID and pick the // first one for attributing the app op. This will work correctly for // runtime permissions as for legacy apps we will toggle the app op for // all packages in the UID. The caveat is that the operation may be attributed // to the wrong package and stats based on app ops may be slightly off. if (opPackageName.size() <= 0) { sp<IBinder> binder = defaultServiceManager()->getService(String16("permission")); if (binder != nullptr) { const uid_t uid = IPCThreadState::self()->getCallingUid(); Vector<String16> packages; interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages); if (!packages.isEmpty()) { opPackageName = packages[0]; } else { ALOGE("No packages for calling UID"); } } else { ALOGE("Cannot get permission service"); } } //创建native SensorManager sensorManager = new SensorManager(opPackageName); // If we had no package name, we looked it up from the UID and the sensor // manager instance we created should also be mapped to the empty package // name, to avoid looking up the packages for a UID and get the same result. if (packageName.size() <= 0) { sPackageInstances.insert(std::make_pair(String16(), sensorManager)); } // Stash the per package sensor manager. sPackageInstances.insert(std::make_pair(opPackageName, sensorManager)); } return *sensorManager; }
获取native层sensor列表,保存到java层的sensor对象中
//frameworks/base/core/jni/android_hardware_SensorManager.cpp static jboolean nativeGetSensorAtIndex(JNIEnv *env, jclass clazz, jlong sensorManager, jobject sensor, jint index) { SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); Sensor const* const* sensorList; ssize_t count = mgr->getSensorList(&sensorList); if (ssize_t(index) >= count) { return false; } return translateNativeSensorToJavaSensor(env, sensor, *sensorList[index]) != NULL;//index找到native sensor 入参 } static jobject translateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) { const SensorOffsets& sensorOffsets(gSensorOffsets); if (sensor == NULL) { //java层已经new过,为空再new一回 //Sensor sensor = new Sensor(); sensor = env->NewObject(sensorOffsets.clazz, sensorOffsets.init, ""); } if (sensor != NULL) { jstring name = getJavaInternedString(env, nativeSensor.getName()); jstring vendor = getJavaInternedString(env, nativeSensor.getVendor()); jstring requiredPermission = getJavaInternedString(env, nativeSensor.getRequiredPermission()); env->SetObjectField(sensor, sensorOffsets.name, name); env->SetObjectField(sensor, sensorOffsets.vendor, vendor); env->SetIntField(sensor, sensorOffsets.version, nativeSensor.getVersion()); env->SetIntField(sensor, sensorOffsets.handle, nativeSensor.getHandle()); ... if (env->CallBooleanMethod(sensor, sensorOffsets.setType, nativeSensor.getType()) == JNI_FALSE) { jstring stringType = getJavaInternedString(env, nativeSensor.getStringType()); env->SetObjectField(sensor, sensorOffsets.stringType, stringType); } int32_t id = nativeSensor.getId(); env->CallVoidMethod(sensor, sensorOffsets.setId, id); Sensor::uuid_t uuid = nativeSensor.getUuid(); env->CallVoidMethod(sensor, sensorOffsets.setUuid, htonll(uuid.i64[0]), htonll(uuid.i64[1])); } return sensor; }
SensorManager::SensorManager(const String16& opPackageName) : mSensorList(nullptr), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { Mutex::Autolock _l(mLock); assertStateLocked(); } status_t SensorManager::assertStateLocked() { bool initSensorManager = false; if (mSensorServer == nullptr) { 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]", static_cast<void*>(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 == nullptr, "mSensorList NULL"); for (size_t i=0 ; i<count ; i++) { mSensorList[i] = mSensors.array() + i; } } return NO_ERROR; } status_t SensorManager::waitForSensorService(sp<ISensorServer> *server) { // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ... sp<ISensorServer> s; const String16 name("sensorservice"); for (int i = 0; i < 60; i++) { status_t err = getService(name, &s); switch (err) { case NAME_NOT_FOUND: sleep(1); continue; case NO_ERROR: if (server != nullptr) { *server = s; } return NO_ERROR; default: return err; } } return TIMED_OUT; }
//SensorManager.java public Sensor getDefaultSensor(int type) { // TODO: need to be smarter, for now, just return the 1st sensor List<Sensor> l = getSensorList(type);//看下面 boolean wakeUpSensor = false; // For the following sensor types, return a wake-up sensor. These types are by default // defined as wake-up sensors. For the rest of the SDK defined sensor types return a // non_wake-up version. //这些默认wake-up,否则 false if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION || type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE || type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE || type == Sensor.TYPE_WRIST_TILT_GESTURE || type == Sensor.TYPE_DYNAMIC_SENSOR_META || type == Sensor.TYPE_HINGE_ANGLE) { wakeUpSensor = true; } for (Sensor sensor : l) { if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor; } return null; } public List<Sensor> getSensorList(int type) { // cache the returned lists the first time List<Sensor> list; final List<Sensor> fullList = getFullSensorList(); synchronized (mSensorListByType) { list = mSensorListByType.get(type); if (list == null) { if (type == Sensor.TYPE_ALL) { list = fullList; } else { list = new ArrayList<Sensor>(); for (Sensor i : fullList) { if (i.getType() == type) { list.add(i); } } } list = Collections.unmodifiableList(list); mSensorListByType.append(type, list); } } return list; }
registerListenerimpl 实际执行registerListenerimpl
// 文件路径:frameworks/base/core/java/android/hardware/SystemSensorManager.java protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { .... // 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) {//必须加同步,多个app,多个线程 //private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =new HashMap<SensorEventListener, SensorEventQueue>(); 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(); //将SensorEvenListeners 映射到SensorEventQueue,SensorEventQueue持有looper queue = new SensorEventQueue(listener, looper, this, fullClassName); //BaseEventQueue->addSensor if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) { queue.dispose(); return false; } mSensorListeners.put(listener, queue); return true; } else { return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs); } } }
SystemSensorManager 类中 registerListenerImpl:
1. new SensorEventQueue
1. nativeInitBaseEventQueue //sp\<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
2. addSensor (BaseEventQueue)
1. mActiveSensors.put(handle, true); //SparseBooleanArray 一个handle只能有一个lisnener if (mActiveSensors.get(handle)) return false;
2. SensorEventQueue::addSensorEvent // SparseArray\<SensorEvent> mSensorsEvents
3. SensorEventQueue::enableSensor //先略过 看5.1
4. nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs)
//registerListenerImpl->addSensor //BaseEventQueue.java 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. //为什么addSensor之后不能再add,若是不同的参数呢?其实 同一个listener,sensor只能add一次,并且以第一次为准 //SparseBooleanArray 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; } static final class SensorEventQueue extends BaseEventQueue { private final SensorEventListener mListener; private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>(); //BaseEventQueue构造中nativeInitBaseEventQueue public SensorEventQueue(SensorEventListener listener, Looper looper, SystemSensorManager manager, String packageName) { super(looper, manager, OPERATING_MODE_NORMAL, packageName); mListener = listener; } @Override// registerListenerImpl->addSensor->addSensorEvent public void addSensorEvent(Sensor sensor) { SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor, mManager.mTargetSdkLevel)); //SparseArray<SensorEvent> mSensorsEvents synchronized (mSensorsEvents) { //一个listener对应一个queue,要给同handle的sensor //一个queue有多个sensor,一个sensor只能有一个queue mSensorsEvents.put(sensor.getHandle(), t); } } @Override public void removeSensorEvent(Sensor sensor) {//unregister时调用此处 synchronized (mSensorsEvents) { mSensorsEvents.delete(sensor.getHandle()); } } // Called from native code. 注意此处,native会调用此处,何时调用看5.2 @SuppressWarnings("unused") @Override 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);//accuracy有变化 mListener.onAccuracyChanged(t.sensor, t.accuracy); } mListener.onSensorChanged(t);//app的调用 } }
BaseEventQueue构造中 nativeInitBaseEventQueue
private abstract static class BaseEventQueue { private static native long nativeInitBaseEventQueue(long nativeManager, WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, String packageName, int mode, String opPackageName); private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs); private static native int nativeDisableSensor(long eventQ, int handle); private static native void nativeDestroySensorEventQueue(long eventQ); private static native int nativeFlushSensor(long eventQ); private static native int nativeInjectSensorData(long eventQ, int handle, float[] values, int accuracy, long timestamp); private long mNativeSensorEventQueue; private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); private final CloseGuard mCloseGuard = CloseGuard.get(); protected final SystemSensorManager mManager; protected static final int OPERATING_MODE_NORMAL = 0; protected static final int OPERATING_MODE_DATA_INJECTION = 1; BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) { if (packageName == null) packageName = ""; mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance,//注意此处 new WeakReference<>(this), looper.getQueue(), packageName, mode, manager.mContext.getOpPackageName()); mCloseGuard.open("dispose"); mManager = manager; } public void dispose() { dispose(false); } 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; } public boolean removeAllSensors() {//sesor null 则removeAll for (int i = 0; i < mActiveSensors.size(); i++) { if (mActiveSensors.valueAt(i) == true) { int handle = mActiveSensors.keyAt(i); Sensor sensor = mManager.mHandleToSensor.get(handle); if (sensor != null) { disableSensor(sensor); mActiveSensors.put(handle, false); removeSensorEvent(sensor); } else { // sensor just disconnected -- just ignore. } } } return true; } //unregisterListenerImpl->removeSensor public boolean removeSensor(Sensor sensor, boolean disable) { final int handle = sensor.getHandle(); if (mActiveSensors.get(handle)) { if (disable) disableSensor(sensor); mActiveSensors.put(sensor.getHandle(), false); removeSensorEvent(sensor); return true; } return false; } public int flush() { if (mNativeSensorEventQueue == 0) throw new NullPointerException(); return nativeFlushSensor(mNativeSensorEventQueue); } public boolean hasSensors() { // no more sensors are set return mActiveSensors.indexOfValue(true) >= 0; } @Override protected void finalize() throws Throwable { try { dispose(true); } finally { super.finalize(); } } private void dispose(boolean finalized) { if (mCloseGuard != null) { if (finalized) { mCloseGuard.warnIfOpen(); } mCloseGuard.close(); } if (mNativeSensorEventQueue != 0) { nativeDestroySensorEventQueue(mNativeSensorEventQueue); mNativeSensorEventQueue = 0; } } 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); } protected int injectSensorDataBase(int handle, float[] values, int accuracy, long timestamp) { return nativeInjectSensorData( mNativeSensorEventQueue, handle, values, accuracy, timestamp); } private int disableSensor(Sensor sensor) { if (mNativeSensorEventQueue == 0) throw new NullPointerException(); if (sensor == null) throw new NullPointerException(); return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle()); } @UnsupportedAppUsage protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp); @UnsupportedAppUsage protected abstract void dispatchFlushCompleteEvent(int handle); @UnsupportedAppUsage protected void dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues) { // default implementation is do nothing } protected abstract void addSensorEvent(Sensor sensor); protected abstract void removeSensorEvent(Sensor sensor); }
nativeInitBaseEventQueue : 创建一个接收数据的Receiver对象
addSensor
addSensorEvent
enableSensor : nativeEnableSensor
以上全是java层的register,到了nativeInitBaseEventQueue这里,就到了jni。nativeInitBaseEventQueue : 创建SensorEventQueue\创建一个接收数据的Receiver对象。
//frameworks/base/core/jni/android_hardware_SensorManager.cpp static const JNINativeMethod gBaseEventQueueMethods[] = { {"nativeInitBaseEventQueue", "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J", (void*)nativeInitSensorEventQueue }, //...... }; 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)); //创建native SensorEventQueue if (queue == NULL) { jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue."); return 0; } // Receiver 详见4.4 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } //创建一个接收数据的Receiver对象,用于回调,构造传入messageQueue, sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); receiver->incStrong((void*)nativeInitSensorEventQueue); return jlong(receiver.get()); }
//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 == nullptr) { // SensorService just died or the app doesn't have required permissions. ALOGE("createEventQueue: connection is NULL."); return nullptr; } //创建SensorEventQueue,构造中传入conn queue = new SensorEventQueue(connection); break; } return queue; }
两个重要的函数,后面着重讲下。
reregisterListenerImpl->new SensorEventQueue->nativeInitBaseEventQueue->createSensorEventConnection
SensorEventConnection这个类主要是用来给应用发送sensor数据的,通过socket进行通信,
当应用注册sensor时,SensorManager.cpp里边会通过调用 SensorService::createSensorEventConnection()来生成属于该应用的connection,
一个应用拥有多少个SensorEventConnection,取决于应用创建多少个SensorEventListerner,(为什么这么说呢? 因为new SensorEventQue之前,会先判断是否有必要new,HashMap<SensorEventListener, SensorEventQueue> mSensorListeners,详见4章)
可能有的应用开发者注册多个sensor时,喜欢只创建一个SensorEventListerner,然后在onSensorChanged()里边做类型区分,
有的喜欢一个sensor一个SensorEventListerner,从性能的角度考虑建议一个应用创建一个SensorEventListerner就够了,
毕竟每创建一个,就要新建立一个socket连接,多一个poll去等待数据。
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
int requestedMode, const String16& opPackageName) {
String16 connOpPackageName =
(opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
requestedMode == DATA_INJECTION, connOpPackageName));
if (requestedMode == DATA_INJECTION) {
result->updateLooperRegistration(mLooper);
}
return result;
}
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) {
//上面保存一堆应用信息
//注意BitTube
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
mTotalAcksNeeded = mTotalAcksReceived = 0;
#endif
}
SensorEventConnection构造中主要是保存应用的信息,
该类的重点在于其SensorEventConnection::sendEvents() 函数,在这边将数据发送给应用,所以如果遇到应用获取不到sensor数据的问题,也可以在这里边debug,包括
都可以将mPackageName和sensor type, sensor data,sensor timestamp在这打印出来,或者统一存储后dump sensorservice出来
//frameworks/native/libs/sensor/SensorEventQueue.cpp SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection) : mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0), mNumAcksToSend(0) { //创建mRecBuffer,用来存从SensorEventConnection发送过来的数据, mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT]; } //SensorEventQueue::write()用来给SensorEventConnection发送数据, //SensorService::threadLoop()-> SensorEventConnection::sendEvents()-->SensorEventQueue::write //流程见5.2.2 ssize_t SensorEventQueue::write(const sp<BitTube>& tube, ASensorEvent const* events, size_t numEvents) { return BitTube::sendObjects(tube, events, numEvents); } // SensorEventQueue::read()用来读取数据给应用 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); }
4.2中nativeInitSensorEventQueue有new Receiver
//android_hardware_SensorManager.cpp 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)); //创建native SensorEventQueue if (queue == NULL) { jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue."); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } //创建一个接收数据的Receiver对象,传入messageQueue, sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); receiver->incStrong((void*)nativeInitSensorEventQueue); return jlong(receiver.get()); }
//frameworks/base/core/jni/android_hardware_SensorManager.cpp class Receiver : public LooperCallback { sp<SensorEventQueue> mSensorQueue; sp<MessageQueue> mMessageQueue; jobject mReceiverWeakGlobal; jfloatArray mFloatScratch; jintArray mIntScratch; public: Receiver(const sp<SensorEventQueue>& sensorQueue, const sp<MessageQueue>& messageQueue, jobject receiverWeak) { JNIEnv* env = AndroidRuntime::getJNIEnv(); //保存两个比较关键的对象引用 mSensorQueue = sensorQueue; mMessageQueue = messageQueue; mReceiverWeakGlobal = env->NewGlobalRef(receiverWeak); mIntScratch = (jintArray) env->NewGlobalRef(env->NewIntArray(16)); mFloatScratch = (jfloatArray) env->NewGlobalRef(env->NewFloatArray(16)); } ~Receiver() { JNIEnv* env = AndroidRuntime::getJNIEnv(); env->DeleteGlobalRef(mReceiverWeakGlobal); env->DeleteGlobalRef(mFloatScratch); env->DeleteGlobalRef(mIntScratch); } sp<SensorEventQueue> getSensorEventQueue() const { return mSensorQueue; } void destroy() { mMessageQueue->getLooper()->removeFd( mSensorQueue->getFd() ); } private: virtual void onFirstRef() { LooperCallback::onFirstRef(); //mSensorQueue->getFd()即 SensorEventQueue > SensorEventConnection > BitTube 里边mReceiveFd //把BitTube的mReceiverFd添加到Looper里面,Looper::pollInnner()会通过epoll监听该fd, //当有事件发生时候,Receiver::loopercallback,就会回调handleEvent mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); } virtual int handleEvent(int fd, int events, void* data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data); ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); ssize_t n; ASensorEvent buffer[16]; 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; } if (receiverObj.get()) {//call dispatchSensorEvent //关键就在这里,这边通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager 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; } }; void SensorEventQueue::onFirstRef() { //sp<BitTube> mSensorChannel mSensorChannel = mSensorEventConnection->getSensorChannel();//return mChannel } int SensorEventQueue::getFd() const { return mSensorChannel->getFd(); }
通过jni回调SystemSensorManager::dispatchSensorEvent(),将数据给SensorManager
App -->I2C过程: app通过SensorManager,getSystemServer调用到SystemSensorManager SystemSensorManager通过jni调用到SensorManager.cpp ,通过binder createconnection调用到SensorService
SensorService通过SystemServer启动,Sensor调用到hal kernel
I2c向app传递数据: SensorService 在是一个binder线程,threadloop方法中device.poll来读 发送数据,通过BitTube(跨进程socket) sendEvents 把数据传递到android_hardware_SensorManager.cpp 这个jni中,
通过JNI调用,调用到java层SystemSensorManager中的SensorEventQueue.dispatchSensorEvent,通过app向SensorEventQueue注册的mListener,来回调数据到app的onSensorChanged()方法,本章展开讲讲.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEg2ILgu-1671295003774)(D:\下载\20170706221356989.jpg)]
4.1 registerListenerImpl 主要逻辑
1. new SensorEventQueue
1. nativeInitBaseEventQueue //sp\<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
2. addSensor (BaseEventQueue)
1. mActiveSensors.put(handle, true); //SparseBooleanArray 一个handle只能有一个lisnener if (mActiveSensors.get(handle)) return false;
2. SensorEventQueue::addSensorEvent // SparseArray\<SensorEvent> mSensorsEvents
3. SensorEventQueue::enableSensor //先略过 看5.1
4. nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs)
那我们就看看 SensorEventQueue::enableSensor
接着看注册流程
//BaseEventQueue.java 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(); //mNativeSensorEventQueue 已经初始化过了,返回的是创建的Receiver地址,命名为mNativeSensorEventQueue,有何深意? return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs); }
//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 //重载好几个,选一个 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); } 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; } 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; } 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; }
//frameworks/base/core/java/android/hardware/SystemSensorManager.java BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) { if (packageName == null) packageName = ""; nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance, new WeakReference<>(this), looper.getQueue(), packageName, mode, manager.mContext.getOpPackageName()); mCloseGuard.open("dispose"); mManager = manager; } // @android_hardware_SensorManager.cpp {"nativeInitBaseEventQueue", "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;Ljava/lang/String;ILjava/lang/String;)J", (void*)nativeInitSensorEventQueue }, 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)); //createEventQueue和SensorService连接起来 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); 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()); } //new Receiver时,使用LooperCallback addFd,把SensorService的fd共享使用looper监听起来,好回调handleEvent //frameworks/base/core/jni/android_hardware_SensorManager.cpp class Receiver : public LooperCallback { sp<SensorEventQueue> mSensorQueue; sp<MessageQueue> mMessageQueue; jobject mReceiverWeakGlobal; jfloatArray mFloatScratch; jintArray mIntScratch; public: ...... private: virtual void onFirstRef() { LooperCallback::onFirstRef(); mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); //callback:this } virtual int handleEvent(int fd, int events, void* data) {} //LOOP方法定义,第4个是回调函数 //system/core/libutils/Looper.cpp int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) { return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); } int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { //getFd是在SensorEventQueue初始化时候赋值 //frameworks/native/libs/sensor/SensorEventQueue.cpp void SensorEventQueue::onFirstRef() { mSensorChannel = mSensorEventConnection->getSensorChannel(); } int SensorEventQueue::getFd() const { return mSensorChannel->getFd(); } //最终调用到services中 getSensorChannel ,这个mChannel是在SensorEventConnection中初始化,然后BitTube来获取mChannel,这样就保证service和client是通一个fd //frameworks/native/services/sensorservice/SensorEventConnection.cpp SensorService::SensorEventConnection::SensorEventConnection( const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode, const String16& opPackageName) : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false), mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) { mChannel = new BitTube(mService->mSocketBufferSize); //mChannel #if DEBUG_CONNECTIONS mEventsReceived = mEventsSentFromCache = mEventsSent = 0; mTotalAcksNeeded = mTotalAcksReceived = 0; #endif } sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const { return mChannel; }
SensorService由于线程会执行threadLoop,会首先device.poll从Hal层while读取数据,然后看是不是虚拟Sensor处理,最后发送到客户端 activeConnections[i]->sendEvents
bool SensorService::threadLoop() { SensorDevice& device(SensorDevice::getInstance()); const int halVersion = device.getHalDeviceVersion(); do { //从hal拿到数据 ssize_t count = device.poll(mSensorEventBuffer, numEventMax); //device.poll SortedVector< sp<SensorEventConnection> > activeConnections; populateActiveConnections(&activeConnections); // handle virtual sensors if (count && vcount) { sensors_event_t const * const event = mSensorEventBuffer; ... } //发送事件到客户端 android_hardware_SensorManager.cpp Receiver // 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) { //重点在这里!!!! 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); } } } } while (!Thread::exitPending()); ... }
//SensorService向mChannel写数据,通过BitTube完成,可以服务端写,然后通知客户端读 @service/SensorEventConnection.cpp 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; } }
//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); } //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); 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; }
//frameworks/base/core/jni/android_hardware_SensorManager.cpp //BaseEventQueue构造->nativeInitSensorEventQueue static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) { SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager); ... sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak); receiver->incStrong((void*)nativeInitSensorEventQueue); return jlong(receiver.get()); } virtual void onFirstRef() { LooperCallback::onFirstRef(); //获取套接字fd mMessageQueue->getLooper()->addFd(mSensorQueue->getFd(), 0, ALOOPER_EVENT_INPUT, this, mSensorQueue.get()); }
1. mSensorQueue->getFd()即 SensorEventQueue > SensorEventConnection > BitTube 里边mReceiveFd
2. 把BitTube的mReceiverFd添加到Looper里面,Looper::pollInnner()会通过epoll监听该fd,
3. 当有事件发生时候,Receiver::loopercallback,就会回调handleEvent
收到方法回调后,先q->read向服务端读取数据到buffer,然后通过jni调用给gBaseEventQueueClassInfo.dispatchSensorEvent
@frameworks/base/core/jni/android_hardware_SensorManager.cpp 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]; while ((n = q->read(buffer, 16)) > 0) { //read if (receiverObj.get()) { env->CallVoidMethod(receiverObj.get(), gBaseEventQueueClassInfo.dispatchSensorEvent, buffer[i].sensor, mFloatScratch, status, buffer[i].timestamp); } } } mSensorQueue->sendAck(buffer, n); } return 1; } }; //gBaseEventQueueClassInfo是SystemSensorManager$BaseEventQueue gBaseEventQueueClassInfo.clazz = FindClassOrDie(env, "android/hardware/SystemSensorManager$BaseEventQueue");
SensorEventQueue继承BaseEventQueue,重写方法dispatchSensorEvent,JNI调用的就是这个方法,就可以通过mListener回调给app
static final class SensorEventQueue extends BaseEventQueue {
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
// 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);
}
}
https://blog.csdn.net/gangjindianzi/article/details/124587713?spm=1001.2014.3001.5501
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。