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文件,启动服务
public static void main(String[] args) {
new SystemServer().run();
}
public final class SystemServer {
private static final String TAG = "SystemServer";
private void run() {
System.loadLibrary("android_servers");
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
}
...
private void startBootstrapServices() {
mSystemServiceManager.startService(SensorService.class);
}
}
public class SensorService extends SystemService {
private static final String START_NATIVE_SENSOR_SERVICE = "StartNativeSensorService";
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
1.2.1 onFirstRef
void SensorService::onFirstRef() {
SensorDevice& dev(SensorDevice::getInstance());
if (dev.initCheck() == NO_ERROR) {
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::getInstance();
registerSensor(new RotationVectorSensor(), !needRotationVector, true);
registerSensor(new OrientationSensor(), !needRotationVector, true);
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;
mAckReceiver = new SensorEventAckReceiver(this);
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
run("SensorService", PRIORITY_URGENT_DISPLAY);
enableSchedFifoMode();
mUidPolicy->registerSelf();
}
1.2.3 SensorDevice
看SensorService::threadLoop()之前,先来看下SensorDevice的构造函数,
SensorDevice继承了Singleton类,设计成单例,后面要用的话用getinstance()的方式, 为何用单例?是因为sensorservice会有多个线程与vendor层交互,若用多个的话,逻辑会比较混淆,并且也没有必要,节约一点内存哈哈。
SensorDevice::SensorDevice()
: mHidlTransportErrors(20), mRestartWaiter(new HidlServiceRegistrationWaiter()) {
if (!connectHidlService()) {
return;
}
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);
if (sensor.power < minPowerMa) {
ALOGE("Reported power %f not deemed sane, clamping to %f",
sensor.power, minPowerMa);
sensor.power = minPowerMa;
}
mSensorList.push_back(sensor);
mActivationCount.add(list[i].sensorHandle, model);
checkReturn(mSensors->activate(list[i].sensorHandle, 0 ));
}
}));
}
bool SensorDevice::connectHidlService() {
size_t retry = 10;
while (retry-- > 0) {
mSensors = ISensors::getService();
if (mSensors == nullptr) {
break;
}
}
return (mSensors != nullptr);
}
1.2.4 threadLoop
bool SensorService::threadLoop() {
ALOGD("nuSensorService thread starting...");
const size_t vcount = mSensors.getVirtualSensors().size();
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + vcount);
SensorDevice& device(SensorDevice::getInstance());
const int halVersion = device.getHalDeviceVersion();
do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
for (int i = 0; i < count; i++) {
mSensorEventBuffer[i].flags = 0;
}
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
Mutex::Autolock _l(mLock);
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
}
if (bufferHasWakeUpEvent && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
recordLastValueLocked(mSensorEventBuffer, count);
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 (activeConnections[i]->hasOneShotSensors()) {
cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
count);
}
}
}
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);
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++) {
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;
}
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);
}
}
}
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);
}
}
应用退出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
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
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());
}});
...
}
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构造
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);
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));
for (int index = 0;; ++index) {
Sensor sensor = new 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));
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中
static void
nativeClassInit (JNIEnv *_env, jclass _this)
{
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");
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");
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 的通信
static jlong
nativeCreate
(JNIEnv *env, jclass clazz, jstring opPackageName)
{
ScopedUtfChars opPackageNameUtf(env, opPackageName);
return (jlong) &SensorManager::getInstanceForPackage(String16(opPackageNameUtf.c_str()));
}
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;
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");
}
}
sensorManager = new SensorManager(opPackageName);
if (packageName.size() <= 0) {
sPackageInstances.insert(std::make_pair(String16(), sensorManager));
}
sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
}
return *sensorManager;
}
3.2.3 nativeGetSensorAtIndex
获取native层sensor列表,保存到java层的sensor对象中
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;
}
static jobject
translateNativeSensorToJavaSensor(JNIEnv *env, jobject sensor, const Sensor& nativeSensor) {
const SensorOffsets& sensorOffsets(gSensorOffsets);
if (sensor == NULL) {
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 {
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) {
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
public Sensor getDefaultSensor(int type) {
List<Sensor> l = getSensorList(type);
boolean wakeUpSensor = 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) {
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
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
....
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
final String fullClassName =
listener.getClass().getEnclosingClass() != null
? listener.getClass().getEnclosingClass().getName()
: listener.getClass().getName();
queue = new SensorEventQueue(listener, looper, this, fullClassName);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
}
}
}
SystemSensorManager 类中 registerListenerImpl:
1. new SensorEventQueue
1. nativeInitBaseEventQueue
2. addSensor (BaseEventQueue)
1. mActiveSensors.put(handle, true);
2. SensorEventQueue::addSensorEvent
3. SensorEventQueue::enableSensor
4. nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs)
4.1.1 SensorEventQueue
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
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>();
public SensorEventQueue(SensorEventListener listener, Looper looper,
SystemSensorManager manager, String packageName) {
super(looper, manager, OPERATING_MODE_NORMAL, packageName);
mListener = listener;
}
@Override
public void addSensorEvent(Sensor sensor) {
SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
mManager.mTargetSdkLevel));
synchronized (mSensorsEvents) {
mSensorsEvents.put(sensor.getHandle(), t);
}
}
@Override
public void removeSensorEvent(Sensor sensor) {
synchronized (mSensorsEvents) {
mSensorsEvents.delete(sensor.getHandle());
}
}
@SuppressWarnings("unused")
@Override
protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
long timestamp) {
final Sensor sensor = mManager.mHandleToSensor.get(handle);
if (sensor == null) {
return;
}
SensorEvent t = null;
synchronized (mSensorsEvents) {
t = mSensorsEvents.get(handle);
}
if (t == null) {
return;
}
System.arraycopy(values, 0, t.values, 0, t.values.length);
t.timestamp = timestamp;
t.accuracy = inAccuracy;
t.sensor = sensor;
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);
}
}
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) {
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
if (maxBatchReportLatencyUs == 0
|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
public boolean removeAllSensors() {
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 {
}
}
}
return true;
}
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() {
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) {
}
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对象。
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));
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;
}
sp<Receiver> receiver = new Receiver(queue, messageQueue, eventQWeak);
receiver->incStrong((void*)nativeInitSensorEventQueue);
return jlong(receiver.get());
}
4.3 SensorManager::createEventQueue——native
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
sp<SensorEventQueue> queue;
Mutex::Autolock _l(mLock);
while (assertStateLocked() == NO_ERROR) {
sp<ISensorEventConnection> connection =
mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
if (connection == nullptr) {
ALOGE("createEventQueue: connection is NULL.");
return nullptr;
}
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) {
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
SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
: mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0),
mNumAcksToSend(0) {
mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
}
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
if (mAvailable == 0) {
ssize_t err = BitTube::recvObjects(mSensorChannel,
mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
if (err < 0) {
return err;
}
mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
size_t count = min(numEvents, mAvailable);
memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
return static_cast<ssize_t>(count);
}
4.4 Receiver
4.2中nativeInitSensorEventQueue有new Receiver
static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager,
jobject eventQWeak, jobject msgQ, jstring packageName, jint mode) {
SensorManager* mgr = reinterpret_cast<SensorManager*>(sensorManager);
ScopedUtfChars packageUtf(env, packageName);
String8 clientName(packageUtf.c_str());
sp<SensorEventQueue> queue(mgr->createEventQueue(clientName, mode));
if (queue == NULL) {
jniThrowRuntimeException(env, "Cannot construct native SensorEventQueue.");
return 0;
}
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ);
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());
}
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();
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) {
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) {
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
buffer[i].meta_data.sensor);
}
} else if (buffer[i].type == SENSOR_TYPE_ADDITIONAL_INFO) {
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()) {
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;
}
}
}
mSensorQueue->sendAck(buffer, n);
}
if (n<0 && n != -EAGAIN) {
}
return 1;
}
};
void SensorEventQueue::onFirstRef()
{
mSensorChannel = mSensorEventConnection->getSensorChannel();
}
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
2. addSensor (BaseEventQueue)
1. mActiveSensors.put(handle, true);
2. SensorEventQueue::addSensorEvent
3. SensorEventQueue::enableSensor
4. nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, maxBatchReportLatencyUs)
那我们就看看 SensorEventQueue::enableSensor
接着看注册流程
public boolean addSensor(
Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
if (maxBatchReportLatencyUs == 0
|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
removeSensor(sensor, false);
return false;
}
}
return true;
}
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);
}
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);
}
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;
sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
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;
}
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)) {
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
auto logger = mRecentEvent.find(handle);
if (logger != mRecentEvent.end()) {
sensors_event_t event;
if(logger->second->populateLastEvent(&event)) {
event.sensor = handle;
if (event.version == sizeof(sensors_event_t)) {
if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
setWakeLockAcquiredLocked(true);
}
connection->sendEvents(&event, 1, NULL);
if (!connection->needsWakeLock() && mWakeLockAcquired) {
checkWakeLockStateLocked();
}
}
}
}
}
}
}
if (connection->addSensor(handle)) {
BatteryService::enableSensor(connection->getUid(), handle);
if (mActiveConnections.indexOf(connection) < 0) {
mActiveConnections.add(connection);
}
} else {
ALOGW("sensor %08x already enabled in connection %p (ignoring)",
handle, connection.get());
}
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);
status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
maxBatchReportLatencyNs);
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);
if (err_flush == NO_ERROR) {
rec->addPendingFlushConnection(connection.get());
} else {
connection->setFirstFlushPending(handle, false);
}
}
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);
mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
SensorRegistrationInfo(handle, connection->getPackageName(),
samplingPeriodNs, maxBatchReportLatencyNs, true);
mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
}
if (err != NO_ERROR) {
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));
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) {
if (info.numActiveClients() == 1) {
actuateHardware = true;
}
} else {
ALOGE("\t >>>ERROR: activate called without batch");
}
} else {
ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
auto it = mConnectedDynamicSensors.find(handle);
if (it != mConnectedDynamicSensors.end()) {
delete it->second;
mConnectedDynamicSensors.erase(it);
}
if (info.removeBatchParamsForIdent(ident) >= 0) {
if (info.numActiveClients() == 0) {
actuateHardware = true;
} else {
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 {
}
if (isClientDisabledLocked(ident)) {
return NO_ERROR;
}
}
if (actuateHardware) {
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
enabled);
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) {
info.removeBatchParamsForIdent(ident);
}
}
return err;
}
5.2 发送与接收
5.2.1 fd共享流程
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));
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());
}
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());
}
virtual int handleEvent(int fd, int events, void* data) {}
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) {
void SensorEventQueue::onFirstRef()
{
mSensorChannel = mSensorEventConnection->getSensorChannel();
}
int SensorEventQueue::getFd() const
{
return mSensorChannel->getFd();
}
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);
#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 {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
SortedVector< sp<SensorEventConnection> > activeConnections;
populateActiveConnections(&activeConnections);
if (count && vcount) {
sensors_event_t const * const event = mSensorEventBuffer;
...
}
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 (activeConnections[i]->hasOneShotSensors()) {
cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,
count);
}
}
}
} while (!Thread::exitPending());
...
}
@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) {
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);
sensor_handle = buffer[i].meta_data.sensor;
}
ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
if (index < 0) {
++i;
continue;
}
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
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 (flushInfo.mFirstFlushPending) {
++i;
continue;
}
do {
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
if (mapFlushEventsToConnections[i] == this) {
scratch[count++] = buffer[i];
}
} else {
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 {
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();
if (count == 0) {
delete sanitizedBuffer;
return status_t(NO_ERROR);
}
#if DEBUG_CONNECTIONS
mEventsReceived += count;
#endif
if (mCacheSize != 0) {
if (mCacheSize + count <= mMaxCacheSize) {
memcpy(&mEventCache[mCacheSize], scratch, count * sizeof(sensors_event_t));
mCacheSize += count;
} else {
if (mCacheSize + count < computeMaxCacheSizeLocked()) {
reAllocateCacheLocked(scratch, count);
delete sanitizedBuffer;
return status_t(NO_ERROR);
}
int remaningCacheSize = mMaxCacheSize - mCacheSize;
if (remaningCacheSize != 0) {
memcpy(&mEventCache[mCacheSize], scratch,
remaningCacheSize * sizeof(sensors_event_t));
}
int numEventsDropped = count - remaningCacheSize;
countFlushCompleteEventsLocked(mEventCache, numEventsDropped);
memmove(mEventCache, &mEventCache[numEventsDropped],
(mCacheSize - numEventsDropped) * sizeof(sensors_event_t));
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
}
}
ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
if (size < 0) {
if (index_wake_up_event >= 0) {
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;
updateLooperRegistrationLocked(mService->getLooper());
delete sanitizedBuffer;
return size;
}
}
ssize_t SensorEventQueue::write(const sp<BitTube>& tube,
ASensorEvent const* events, size_t numEvents) {
return BitTube::sendObjects(tube, events, numEvents);
}
ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
void const* events, size_t count, size_t objSize)
{
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count*objSize);
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);
ssize_t BitTube::write(void const* vaddr, size_t size)
{
ssize_t err, len;
do {
len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);
err = len < 0 ? errno : 0;
} while (err == EINTR);
return err == 0 ? len : -err;
}
5.2.3 SensorEventQueue 接收数据分发给app
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();
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) {
if (receiverObj.get()) {
env->CallVoidMethod(receiverObj.get(),
gBaseEventQueueClassInfo.dispatchSensorEvent,
buffer[i].sensor,
mFloatScratch,
status,
buffer[i].timestamp);
}
}
}
mSensorQueue->sendAck(buffer, n);
}
return 1;
}
};
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) {
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
|