因为喜欢用文件记录代码调用流程及总结什么的,画 uml 图什么的实现是懒的画了,直接上传源码总结吧,先传几张图欣赏下吧,感觉有需要就下载源码自己跟下流程吧,如果喜欢这种风格的的话,请点赞[笑脸] ##源码环境 mtk 6582 + android 4.4
安卓框架图:
android app 操作sensor 流程:
1. 获取 sensor manager 对象; / // 此函数会创建一个 SystemSensorManager 对象,上面有介绍,他会调用 SensorManger // 通过 Binder 请求 SensorService 服务返回【传感器列表】, 保存在 SystemSensorManager 中 // 代码调用路径: // xxx.apk // ContextImpl.java // app 都有的 Context 参数实现,这是创建 activity 时创建的 // SystemServiceRegistry.java // 此类的静态代码块中注册各种服务 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 2. 获取 sensor object; / // 查找第一步获得的传感器列表,返回对应的传感器的 Sensor 类对象 mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 3. 定义 eventListener: // 定义了 SensorEventListener 类接口,主要主要是重写了 onSensorChanged() // 和 onAccuracyChanged() 方法,当所监听的sensor有数据上报会自动调用 // onSensorChanged() 进行处理。这里的 handleLightSensorEvent() 就是用来 // 处理 light sensor 上报的数据。 private final SensorEventListener mLightSensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { if (mLightSensorEnabled) { final long time = SystemClock.uptimeMillis(); final float lux = event.values[0]; handleLightSensorEvent(time, lux); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // Not used. } }; 4. 注册 eventListener; // 函数会一直调用到 C++ 层,创建一个套接字,接收 SensorService 发 // 过来的传感器数据,然后一层层调用,最后调用注册的监听函数处理传感器数据 // 代码调用路径: // xxx.apk 中 // SensorManager.java // 他是 SystemSensorManager 的父类,按接口编程 // SystemSensorManager.java // SensorEventQueue.java // SystemSensorManager.java // 初始化父类 BaseEventQueue // -------------------- jni ----------------------------------------------------------------- // android_hardware_SensorManager.cpp // SensorManager.cpp // 在这里注册一个套接字接收 Sensor 发来的数据 // 收到数据处理流程: // android_hardware_SensorManager.cpp // Recevicer::handleEvent() // SystemSensorManager.java // app 覆写的:onAccuracyChanged()/onSensorChanged() mSensorManager.registerListener(mLightSensorListener, mLightSensor, LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler); 5. 卸载 eventListener; // 调用类路径为: // SensorManager.java // SystemSensorManager.java // ------------------- jni ------------------------------------------------------------ // android_hardware_SensorManager.cpp // SensorEventQueue.cpp // 用来管理 sensor 上报的事件的 // SensorEventConnection.cpp // SensorEventConnection 类,管理 Sensor 连接的 // SensorService.cpp // SensorInterface.cpp // SensorDevice.cpp // Sensors.c // Nusensors.cpp // Acceleration.cpp // -------------------- kernel ------------------------------------------------------------------- // accel.c // MTK 封装的加速度传感器框架文件 // mc3413.c // 第三方实现的具体的传感器驱动文件 mSensorManager.unregisterListener(mLightSensorListener);
// 【Sensor 初始化流程】: // 初始化文件路径: // Init.cpp // init 进程:system\core\init // App_main.cpp // zygote 进程:frameworks\base\cmds\app_process // AndroidRuntime.cpp // ZygoteInit.java // :frameworks/base/core/java/com/android/internal/os // RuntimeInit.java // 抛出异常: frameworks\base\core\java\com\android\internal\os // ---------------------------------------------------------------- // SystemServer.java // systemserver 进程: 是 zygote 子进程:frameworks\base\services\java\com\android\server // Onload.cpp // 注册一些 jni, 如硬件访问服务的: frameworks\base\services\jni // --- jni ----------------------------- // com_android_server_SystemServer.cpp // 初始化 C++ 层的 sensor 服务端:frameworks\base\services\jni // SensorService.h // SensorService(C++) 类初始化:提交 Binder 服务:frameworks\native\services\sensorservice // SensorService.cpp // SensorDevice.cpp // SensorDevice(C++) 类初始化:与 HAL 层打交道: frameworks\native\services\sensorservice // --------- 下调 HAL 实现 ---------------- // Sensors.c // 【HAL实现】MTK 创建的 Sensors.c,HAL 层文件,与具体传感器实现打交道:vendor\mediatek\proprietary\hardware\sensor // Acceleration.cpp // 【具体的 sensor 实现函数】:vendor\mediatek\proprietary\hardware\sensor // Gyroscope.cpp // Magnetic.cpp // StepCounter.cpp // 。。。 // ------- kernel ---------------------- // Accel.c // kernel-3.18\drivers\misc\mediatek\accelerometer // alsps.c // kernel-3.18\drivers\misc\mediatek\alsps
MTK sensor 上报数据经过了一个中间层,框图为
acc_driver_add() 煞费苦心的注册了一个 platform_device 匹配 gsensor,却在 probe() 中假装做了些事情。 应该是预留的接口,用于做一些 sensor 全局的设置,比如获得 pinctrl 设备,设置特殊工作引脚什么的。。。
G-sensor 的 probe() 为什么会进两次?