深入理解Android sensor

时序图

在这里插入图片描述

来个时序图,按图索骥
在这里插入图片描述

1 SensorService

整个android sensor模块的核心是SensorService,应用通过SensorManager与其交互,SensorService基本上管理sensor的所有行为,包括

  • 开关sensor,
  • 获取sensor数据给到应用,
  • 应用是否有权限获取sensor,
  • 待机后sensor的行为,
  • sensor数据和开关记录缓存,
  • 还可以在这自定义虚拟sensor,等等。

1.1 sensorService启动

  1. sensorService跑在system_server进程,
  2. SensorService需要访问pkms服务 appOpsService服务 PermissionsService 因此在它们之后启动SensorService
  3. 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
  1. BinderService 是 Android Service 框架的主要类,是个模板类,它提供了 Service 的生命周期管理、进程间通信、请求响应处理等功能。Android 中的绝大部分 Service 都会继承此类
  2. BnSensorServer:frameworks/native/libs/sensor/include/sensor/ISensorServer.h
    和 BinderService 主要实现IPC跨进程通信,实际继承BnInterface: frameworks/native/libs/binder/include/binder/IInterface.h
  3. Thread:继承 Thread 启动 threadLoop

总结下sensorservice启动过程

  1. 系统初始化进程加载,启动SystemServer,Zygote中会执行SystemServier main方法,导致其run方法被调用;

  2. 加载本地库文件, System.loadLibrary(“android_servers”); 获取本地方法;

  3. 被加载到的JNI库文件导致JNI_Onload函数被调用;调用本地jni文件

  4. 注册本地方法jniRegisterNativeMethods 数组;

  5. 完成Java 到 C++ 函数绑定,使Java能否访问到C库中的函数;

  6. 启动startBootstrapServices();

  7. 最后调用native方法 native void startSensorService();

  8. JNI文件com_android_server_SystemServer.cpp,绑定的函数数组,由java的startSensorService方法绑定到

    android_server_SystemServer_startSensorService函数;

  9. C++函数中,start_sensor_service被调用;

  10. 调用SensorService的调用publish

  11. 创建一个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层的数据给到 应用

  1. 通过poll往hal层取sensor数据, 若没有数据的时候就一直阻塞(该阻塞功能由HAL层实现),当有数据时该函数就会返回
  2. virtual sensors 相关数据计算后上报
  3. 通过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 其他事项

  1. SensorFusion
    SensorFusion大概是在这可以虚拟出sensor,取多个sensor的数据,可以再结合其他信息作为输入,通过算法处理最后输出虚拟sensor数据,
    基本上对于手机厂商是不会用到的,原因一个是为了降低功耗所以做到驱动里边,另一个原因是用户刷第三方rom后该功能就没了,所以如果不做在驱动层也会做到vendor层,在这不做分析了。

  2. 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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《Android高级编程》的源代码 对应的书籍资料见: Android高级编程 基本信息 原书名: Professional Android Application Development 原出版社: Wrox 作者: (英)Reto Meier 译者: 王鹏杰 霍建同 出版社:清华大学出版社 ISBN:9787302228448 上架时间:2010-7-1 出版日期:2010 年6月 开本:16开 页码:398 版次:1-1 内容简介   android提供一个开放的开发环境,为针对移动设备编写创新应用程序带来了激动人心的新机遇。作为使用androidsdk构建这些应用程序的实用指南书籍,《android高级编程》从始至终穿插了一系列示例项目,每个项目都引入android的新功能和新技术,以助您达到最圆满的学习效果。书中介绍android的所有基本功能,并通过简明扼要的示例引导您使用高级功能。    《android高级编程》首先简要介绍android软件栈,接着陈述为手机创建稳定可靠、赏心悦目的应用程序的基本原理。通过学习,您可以打下牢固的理论根基,了解使用当前android 1.0 sdk编写定制移动程序所需的知识,还能灵活快捷地运用未来的增强功能构建最前沿的解决方案。    主要内容    ◆android移动开发的最佳实践    ◆简要介绍活动、intent、清单和资源    ◆如何使用布局和定制view创建用户界面    ◆存储和共享应用程序数据的技术    ◆如何创建基于地图的应用程序,如何使用gps和地理编码位置等基于位置的服务    ◆如何创建和使用后台服务及notification    ◆使用加速计、指南针和摄像头硬件    ◆与电话和网络硬件相关的所有内容,如电话api、sms和网络管理等    ◆高级开发主题,包括安全、ipc以及一些高级图形和用户界面技术    读者对象    本书面向希望在android手机平台上创建应用程序的所有人员。不管是经验丰富的移动开发人员,还是初出茅庐的新手,都能从本书提供的宝贵信息中获益。 作译者   Reto Meier出生于澳大利西南的珀斯市,现居伦敦。 Reto是一位经验丰富的软件开发人员,拥有逾10年的GUI程序架构、设计和开发经验。他在涉足IT行业前曾从事过海洋石油和天然气开发以及金融工作。 Reto始终不渝地追求掌握新技术,从2007年Android发布之初Reto就迷恋上了此项技术。他利用业余时间研究包括WPF在内的多种开发平台以及Google的各种开发工具。 详情请访问Reto的个人网站RadioactiveYak,网址是http://blog.radioactiveyak.com。 目录 封面 -14 封底 -13 扉页 -12 版权 -11 作者简介 -10 前言 -9 目录 -4 第1章 Android简介 1 1.1 一些背景信息 2 1.1.1 不远的过去 2 1.1.2 未来的前景 2 1.2 对Android的误解 3 1.3 开放的移动开发平台 3 1.4 自带的Android应用程序 4 1.5 Android SDK功能 5 1.5.1 对包括摄像头、GPS和加速计在内的硬件的访问 5 1.5.2 自带的Google地图、地理编码和基于位置的服务 6 1.5.3 后台服务 6 1.5.4 SQLite 数据存储和检索数据库 6 1.5.5 共享数据和应用程序间通信 7 1.5.6 使用Google Talk的P2P服务 7 1.5.7 扩展的数据支持和2D/3D图形 7 1.5.8 优化的内存和进程管理 8 1.6 开放手机联盟简介 8 1.7 运行Android的环境 8 1.8 从事Android开发的原因 9 1.8.1 推动Android普及的因素 9 1.8.2 Android的独到之处 10 1.8.3 改变移动开发格局 10 1.9 开发框架简介 11 1.9.1 开发包中的资源 11 1.9.2 理解Android软件栈 12 1.9.3 Dalvik虚拟机 13 1.9.4 Android应用程序架构 14 1.9.5 Android库 14 1.9.6 高级Android库 15 1.10 小结 16 第2章 开始入手 17 2.1 Android开发 18 2.1.1

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值