Sensor流程(一)

1.APP层(注册sensor流程)

在这里插入图片描述
在这里插入图片描述

1.1 SensorManager.registerListenerImpl

1)如果没注册过则new SensorEventQueue,在SensorEventQueue构造中会new Receiver,用来接收数据(后续分析)

2)将要注册的sensor add进与linstener绑定的SensorEventQueue中。
在这里插入图片描述

1.2 SensorEventQueue.addSensor

1)加入到mActiveSensors中
在这里插入图片描述

1.3 BaseEventQueue.enableSensor

在这里插入图片描述
在这里插入图片描述

1.4 SensorEventQueue.enableSensor

在这里插入图片描述

1.5 SensorService.SensorEventConnection.enableDisable

在这里插入图片描述

1.6 SensorService.enable

在这里插入图片描述

2. Framework层(service启动以及如何将数据传给APP)

2.1 Sensor服务的启动:SystemServer.startBootstrapServices()

​ sensor service 在SystemServer中启动的,在SystemServer新建一个线程,当有APP选择该service时,再start sensor service.
在这里插入图片描述
startSensorService是一个native方法,该方法实现见android_server_SystemServer_startSensorService方法
在这里插入图片描述
在这里插入图片描述

2.2 com_android_server_SystemServer.android_server_SystemServer_startSensorService()

接下来,调用SensorService的instantiate()方法,SensorService.cpp中并没有instantiate()方法的实现,说明调用的是其父类的instantiate方法。接下来,查看SensorService是哪些类的子类。
在这里插入图片描述
SensorService继承了BinderService,BnSensorServer和Thread。
在这里插入图片描述

2.2.1 BinderService.instantiate()

通过其父类BinderService的instantiate方法可知,通过该方法new SensorService,并将该service add进ServiceManager,这样APP就能通过getSystemService获取到SensorService。接下来就进入SensorService了。
在这里插入图片描述

2.3 SensorService的构造

2.3.1 SensorService()

SensorService的构造函数中对属性进行初始化,创建了UidPolicy对象。构造函数被调用之后,会触发调用onFirstRef()方法。
在这里插入图片描述

2.3.2 onFirstRef()

onFirstRef() 方法被调用是因为前面在BinderService.instantiate()中创建SensorService时被转成了一个强指针(sp),在sp的构造函数中会调用RefBase的incStrong(),在incStrong方法中会调用到影子对象(SensorService)的onFirstRef()。该方法在第一次引用时被调用,用来做一些初始化操作。
在这里插入图片描述
在这里插入图片描述

void SensorService::onFirstRef() {
    ALOGD("nuSensorService starting...");
    //初始化SensorDevice,获取HAL层实例
    SensorDevice& dev(SensorDevice::getInstance());

    sHmacGlobalKeyIsValid = initializeHmacKey();

    if (dev.initCheck() == NO_ERROR) {
        sensor_t const* list;
        //获取HAL层注册的sensors
        ssize_t count = dev.getSensorList(&list);
        if (count > 0) {
            ssize_t orientationIndex = -1;
            bool hasGyro = false, hasAccel = false, hasMag = false;
            uint32_t virtualSensorsNeeds =
                    (1<<SENSOR_TYPE_GRAVITY) |
                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
                    (1<<SENSOR_TYPE_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR) |
                    (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR);
            //遍历每个sensor
            for (ssize_t i=0 ; i<count ; i++) {
                bool useThisSensor=true;

                switch (list[i].type) {
                    case SENSOR_TYPE_ACCELEROMETER:
                        hasAccel = true;
                        break;
                    case SENSOR_TYPE_MAGNETIC_FIELD:
                        hasMag = true;
                        break;
                    case SENSOR_TYPE_ORIENTATION:
                        orientationIndex = i;
                        break;
                    case SENSOR_TYPE_GYROSCOPE:
                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                        hasGyro = true;
                        break;
                    case SENSOR_TYPE_GRAVITY:
                    case SENSOR_TYPE_LINEAR_ACCELERATION:
                    case SENSOR_TYPE_ROTATION_VECTOR:
                    case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
                    case SENSOR_TYPE_GAME_ROTATION_VECTOR:
                        if (IGNORE_HARDWARE_FUSION) {
                            useThisSensor = false;
                        } else {
                            virtualSensorsNeeds &= ~(1<<list[i].type);
                        }
                        break;
                }
                if (useThisSensor) {
                    //将hal层的sensor_t存在HardwareSensor中。
                    //将每种sensor和其handler存在mRecentEvent(map)中
                    registerSensor( new HardwareSensor(list[i]) );
                }
            }

            // it's safe to instantiate the SensorFusion object here
            // (it wants to be instantiated after h/w sensors have been
            // registered)
            SensorFusion::getInstance();

            if (hasGyro && hasAccel && hasMag) {
                // Add Android virtual sensors if they're not already
                // available in the HAL
                bool needRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) != 0;

                registerSensor(new RotationVectorSensor(), !needRotationVector, true);
                registerSensor(new OrientationSensor(), !needRotationVector, true);

                bool needLinearAcceleration =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) != 0;

                registerSensor(new LinearAccelerationSensor(list, count),
                               !needLinearAcceleration, true);

                // virtual debugging sensors are not for user
                registerSensor( new CorrectedGyroSensor(list, count), true, true);
                registerSensor( new GyroDriftSensor(), true, true);
            }

            if (hasAccel && hasGyro) {
                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);

                bool needGameRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GAME_ROTATION_VECTOR)) != 0;
                registerSensor(new GameRotationVectorSensor(), !needGameRotationVector, true);
            }

            if (hasAccel && hasMag) {
                bool needGeoMagRotationVector =
                        (virtualSensorsNeeds & (1<<SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR)) != 0;
                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
            }

            // Check if the device really supports batching by looking at the FIFO event
            // counts for each sensor.
            bool batchingSupported = false;
            mSensors.forEachSensor(
                    [&batchingSupported] (const Sensor& s) -> bool {
                        if (s.getFifoMaxEventCount() > 0) {
                            batchingSupported = true;
                        }
                        return !batchingSupported;
                    });

            if (batchingSupported) {
                // Increase socket buffer size to a max of 100 KB for batching capabilities.
                mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
            } else {
                mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
            }

            // Compare the socketBufferSize value against the system limits and limit
            // it to maxSystemSocketBufferSize if necessary.
            FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
            char line[128];
            if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
                line[sizeof(line) - 1] = '\0';
                size_t maxSystemSocketBufferSize;
                sscanf(line, "%zu", &maxSystemSocketBufferSize);
                if (mSocketBufferSize > maxSystemSocketBufferSize) {
                    mSocketBufferSize = maxSystemSocketBufferSize;
                }
            }
            if (fp) {
                fclose(fp);
            }

            mWakeLockAcquired = false;
            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;

            mNextSensorRegIndex = 0;
            for (int i = 0; i < SENSOR_REGISTRATIONS_BUF_SIZE; ++i) {
                mLastNSensorRegistrations.push();
            }

            mInitCheck = NO_ERROR;
            //SensorEventAckReceiver用于在dispatch wake up sensor event给上层后,接受上层返回的ACK
            mAckReceiver = new SensorEventAckReceiver(this);
            //SensorEventAckReceiver新起一个线程,run->执行threadLoop方法
            mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
            //主线程新起一个线程,执行threadLoop方法
            run("SensorService", PRIORITY_URGENT_DISPLAY);
            //主线程降低优先级
            // priority can only be changed after run
            enableSchedFifoMode();

            // Start watching UID changes to apply policy.
            mUidPolicy->registerSelf();
        }
    }
}
2.3.2.1 SensorDevice::getInstance()

在这里插入图片描述

2.3.2.2 SensorService::threadLoop

该函数用于循环读取sensor硬件上传上来的数据(如果没有数据则堵塞),分发给应用。

1)通过poll往hal层取数据,若没数据就一直阻塞(HAL层实现),有数据就一直返回。
在这里插入图片描述
2)通过SensorEventConnection,将数据发送给每个应用
在这里插入图片描述

2.4 SensorEventConnection.sendEvents将数据发送给应用

每个注册sensor的应用都有专属的SensorEventConnection

1)处理每个数据
在这里插入图片描述
2)判断该sensor是否已经被disable了,或者该应用有没有注册该sensor,若已经disable或者应用没有注册,就过滤掉数据
在这里插入图片描述
3) 将需要发送给APP的数据,copy到scratch中
在这里插入图片描述
4)将scratch中的数据发送给APP
在这里插入图片描述

2.5 SensorEventQueue.write()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来分析,应用层如何接收sensor数据,从app通过SensorManager注册sensor开始分析。

2.6 APP通过SensorManager注册sensor

在这里插入图片描述

2.7 SystemSensorManager.registerListenerImpl()

1)如果之前SensorEventListener没有创建过SensorEventQueue,则创建一个,并将listener和queue一起放进mSensorListeners中。
在这里插入图片描述
2) new SensorEventQueue的时候,同时new 其父类BaseEventQueue。
在这里插入图片描述
3) BaseEventQueue的构造函数中会调用一个native方法
在这里插入图片描述

2.8 android_hardware_SensorManager.nativeInitSensorEventQueue

该方法中会创建一个接收数据的Receiver
在这里插入图片描述
1)在构造中将sensorQueue和messageQueue保存下来
在这里插入图片描述
2)在onFirstRef方法中利用Android Native Looper机制中的addFd来监听文件描述符,当有事件发生时,回调Receiver.handleEvent()
在这里插入图片描述
其中:
在这里插入图片描述
fd :需要轮询的文件描述符

ident :表示为当前发生事件的标识符,必须>=0

events :表示为要监听的文件类型

callback :当有事件发生时,会回调该callback函数。

data :文件描述符fd里面的数据

2.9 Receiver.handleEvent()

1)从BitTube中读取数据
在这里插入图片描述
2)调用SensorEventQueue的dispatchSensorEvent方法,将数据传到SystemSensorManager
在这里插入图片描述

3.数据流结构图

在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值