文章目录
时序图
来个时序图,按图索骥
1 SensorService
整个android sensor模块的核心是SensorService,应用通过SensorManager与其交互,SensorService基本上管理sensor的所有行为,包括
- 开关sensor,
- 获取sensor数据给到应用,
- 应用是否有权限获取sensor,
- 待机后sensor的行为,
- sensor数据和开关记录缓存,
- 还可以在这自定义虚拟sensor,等等。
1.1 sensorService启动
- sensorService跑在system_server进程,
- SensorService需要访问pkms服务 appOpsService服务 PermissionsService 因此在它们之后启动SensorService
- SystemServerInitThreadPool在单独的线程中
1.1.1 java
- zygote启动,调用SystemServer main方法,启动系统服务
- 服务端java代码和jni c++代码都运行在系统服务进程system_server里面,system_server进程启动
- 先加载jni生成的动态链接库 System.loadLibrary(“android_servers”), libandroid_server.so,初始化本地 Native service
- 然后从服务的java代码生成service.jar中加载对应服务的class文件,启动服务
// ./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);
}
}
}
1.1.2 jni
通过对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);
}
}
1.1.3 native (SensorService)
class SensorService :
public BinderService<SensorService>,
public BnSensorServer,
protected Thread
- BinderService 是 Android Service 框架的主要类,是个模板类,它提供了 Service 的生命周期管理、进程间通信、请求响应处理等功能。Android 中的绝大部分 Service 都会继承此类
- BnSensorServer:frameworks/native/libs/sensor/include/sensor/ISensorServer.h
和 BinderService 主要实现IPC跨进程通信,实际继承BnInterface: frameworks/native/libs/binder/include/binder/IInterface.h - Thread:继承 Thread 启动 threadLoop
总结下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());
1.2 sensorService初始化
SensorService继承关系
Sensorservice : public BnSensorServer
BnSensorServer : public BnInterface<ISensorService>
BnInterface : public BBinder
BBinder : public IBinder
IBinder : public virtual RefBase // 对象第一次强引用时自动调用onFirstRef方法
1.2.1 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待机管理里边,后面应用待机行为发生变化时其接口会通过多态被回调
}
1.2.3 SensorDevice
看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);
}
1.2.4 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就行了
//还记得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层的数据给到 应用
- 通过poll往hal层取sensor数据, 若没有数据的时候就一直阻塞(该阻塞功能由HAL层实现),当有数据时该函数就会返回
- virtual sensors 相关数据计算后上报
- 通过SensorEventConnection中 sendEvents 将数据给到每个应用,每个应用都有自己的SensorEventConnection
1.3 待机后SensorService行为,
可留到最后再看
主要的相关类为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。
1.4 其他事项
-
SensorFusion
SensorFusion大概是在这可以虚拟出sensor,取多个sensor的数据,可以再结合其他信息作为输入,通过算法处理最后输出虚拟sensor数据,
基本上对于手机厂商是不会用到的,原因一个是为了降低功耗所以做到驱动里边,另一个原因是用户刷第三方rom后该功能就没了,所以如果不做在驱动层也会做到vendor层,在这不做分析了。 -
dumpsys sensorservice
SensorService 实现了dump接口,debug问题时,可以通过 adb shell dumpsys sensorservice
将sensor信息dump出来协助分析,目前的dump接口主要包含以下几个信息:
- 应用在手机上所有可获得的sensor,包括android定义的sensor以及厂商自定义的sensor
- 目前有几个sensor被应用开启,对应应用包名
- 最近的sensor数据;
- 最近的sensor开关记录,和对应应用包名
2 应用注册sensor流程
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) {
}
}
3 SensorManager的初始化
3.1 SensorManager初始化——java
3.1.1 getSystemService
//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);
}
3.1.2 SystemSensorManager构造
//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);
}
}
}
3.2 SensorManager初始化——jni
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 只会调用一次),包括名称、类型等参数。
3.2.1nativeClassInit
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));
}
3.2.3 nativeCreate
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;
}
3.2.3 nativeGetSensorAtIndex
获取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;
}
3.3 SensorManager初始化——native
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;
}
4 从registerListeners说起 ——SensorEventQueue
4.1 SensorEventQueue的初始化——java
//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;
}
- 每个sensor都是new的,然后调用native方法,nativeGetSensorAtIndex
- nativeGetSensorAtIndex通过jni访问到c++中的sensor manager
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)
4.1.1 SensorEventQueue
//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的调用
}
}
4.1.2 BaseEventQueue
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
4.2 nativeInitBaseEventQueue——jni
以上全是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());
}
4.3 SensorManager::createEventQueue——native
//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;
}
两个重要的函数,后面着重讲下。
- mSensorServer->createSensorEventConnection
- new SensorEventQueue(connection)
4.3.1 createSensorEventConnection
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构造中主要是保存应用的信息,
- 2个package名字,分别表示,
- packageName:应用包名;
- opPackageName:java vm的名字,
- 在android/frameworks/base/services/core/jni/com_android_server_SystemServer.cpp
- android_server_SystemServer_startHidlServices()里边获取并传进来的。
该类的重点在于其SensorEventConnection::sendEvents() 函数,在这边将数据发送给应用,所以如果遇到应用获取不到sensor数据的问题,也可以在这里边debug,包括
- 多个应用注册同一个sensor,有的应用收到数据,有的没有;
- 所有应用都没有收到某些sensor数据;
- 所有sensor都没有数据;
都可以将mPackageName和sensor type, sensor data,sensor timestamp在这打印出来,或者统一存储后dump sensorservice出来
4.3.2 SensorEventQueue.cpp
//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.4 Receiver
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
# 5 数据发送与接收
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)]
5.1 激活sensor
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;
}
5.2 发送与接收
5.2.1 fd共享流程
//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;
}
5.2.2 发送
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;
}
5.2.3 SensorEventQueue 接收数据分发给app
//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);
}
}
5.2.4 BitTube原理
https://blog.csdn.net/gangjindianzi/article/details/124587713?spm=1001.2014.3001.5501