IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> sensor fwk arch -> 正文阅读

[游戏开发]sensor fwk arch

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

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 11:39:00  更:2022-12-25 11:39:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 10:15:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码