1.概览

  上一章详细的描述了SensorHal是如何启动的,其中包括了 SensorHal 相关类的实例化,从类关系上看还是比较复杂的,因为引入了各种包装类以兼容各种版本的SensorHal以及子SensorHal的支持,毫无疑问这部分也是属于SensorHal的初始化的。只不过在SensorHal启动后,SensorFrameork会明确调用SensorHal提供的initialize方法进行二阶段的初始化操作。二阶段的初始化让SensorHal有了灵魂,因为它明确了 EventQueue、wakelock以及供SensorHal回调通知 SensorFramework 关于动态Sensor的加载、卸载情况。所以单独一章来描述。

2.HidlSensorHalWrapper

  HidlSensorHalWrapper 类是SensorDevice用于隔离各种版本的SensorHal的,例如AIDL/HIDL。因为我们使用HIDL MutilHal 2.0接口,所以 HidlSensorHalWrapper 中会实例化类 ISensorsWrapperV2_0。

2.1 ISensorsWrapper 版本的确定

  从AndroidT的代码可知,至少有3个版本的ISensorsWrapper,分别是 ISensorsWrapperV1_0、ISensorsWrapperV2_0以及ISensorsWrapperV2_1

//hardware\interfaces\sensors\common\utils\ISensorsWrapper.h
class ISensorsWrapperV1_0 : public SensorsWrapperBase<hardware::sensors::V1_0::ISensors> {
    ...
};
class ISensorsWrapperV2_0 : public SensorsWrapperBase<hardware::sensors::V2_0::ISensors> {
    ...
};
class ISensorsWrapperV2_1 : public SensorsWrapperBase<hardware::sensors::V2_1::ISensors> {
    ...
};

  至于选择哪一个版本由SensorHal注册来决定,因为SensorHal所在的进程是先于SensorDevice所在线程被运行的。并且在SensorDevice中,选择SensorHal的先后顺序为2.1->2.0->1.0。
  从代码中也是能看出

//frameworks\native\services\sensorservice\HidlSensorHalWrapper.cpp
bool HidlSensorHalWrapper::connectHidlService() {
    HalConnectionStatus status = connectHidlServiceV2_1();
    if (status == HalConnectionStatus::DOES_NOT_EXIST) {
        status = connectHidlServiceV2_0();
    }

    if (status == HalConnectionStatus::DOES_NOT_EXIST) {
        status = connectHidlServiceV1_0();
    }
    return (status == HalConnectionStatus::CONNECTED);
}

  下面则是我现在使用的SensorHal实现

//hardware\interfaces\sensors\2.0\multihal\service.cpp
using android::hardware::sensors::V2_0::ISensors;
int main(int /* argc */, char** /* argv */) {
    android::sp<ISensors> halProxy = new HalProxyV2_0();
    if (halProxy->registerAsService() != ::android::OK)
    ...
}

  可见使用的SensorHal版本为V2_0,所以按上面SensorDevice录用SensorHal的顺序,也就是 ISensorsWrapperV2_0 被选中。下面看看它的类图
在这里插入图片描述

  VirtualLightRefBase则是早期Android中的智能指针实现。在接口 ISensorsWrapperBase则是定义了上层所需要的接口。SensorsWrapperBase为模板类,模板变量也就是HIDL-SensorHal的句柄了,因为为了兼容多版本的HDIL-SensorHal句柄,所以使用模板类

//hardware\interfaces\sensors\common\utils\ISensorsWrapper.h
template <typename T>
class SensorsWrapperBase : public ISensorsWrapperBase{
protected:
    sp<T> mSensors;    
};

  ISensorsWrapperV2_0 则是继承它的V2_0的版本

//hardware\interfaces\sensors\common\utils\ISensorsWrapper.h
class ISensorsWrapperV2_0 : public SensorsWrapperBase<hardware::sensors::V2_0::ISensors> {
};

  在ISensorsWrapperV2_0 中重写了下面几个方法,需要注意下,否则跟代码的时候就跟错了

//hardware\interfaces\sensors\common\utils\ISensorsWrapper.h
    bool supportsPolling() const override { return false; }
    bool supportsMessageQueues() const override { return true; }
    Return<Result> initialize(const MQDescriptorSync<uint32_t>& wakeLockDesc,
                              const ::android::sp<ISensorsCallback>& callback) override {
        return mSensors->initialize(*mEventQueue->getDesc(), wakeLockDesc, callback);
    }

2.2 ISensorsWrapperV2_0->initialize 的调用

  SensorHal的二阶段初始化则是起源于SensorDevice调用HidlSensorHalWrapper的connect方法,最终调用到SensorHal的 initialize 方法,下面是局部流程图
在这里插入图片描述

  下面是对应的代码

B2.hidl_wrapper->connect(this)
    D1.sensors = V2_0::ISensors::getService()
    D2.mSensors = new ISensorsWrapperV2_0(sensors)
    D3.connectionStatus = initializeHidlServiceV2_X
        mCallback = sp<HidlSensorsCallback>::make(mSensorDeviceCallback)
        //ISensorsWrapperV2_0
        E1.mSensors->initialize(*mWakeLockQueue->getDesc(), mCallback)
2.2.1 mCallback的真正面目

  mCallback 用于SensorHal回调通知SensorDevice动态Sensor的变化,它的定义如下

//frameworks\native\services\sensorservice\HidlSensorHalWrapper.h 
class HidlSensorHalWrapper : public ISensorHalWrapper {
private:
    sp<::android::hardware::sensors::V2_1::ISensorsCallback> mCallback;
};

  ISensorsCallback 为HIDL接口,其定义在文件 ISensorsCallback.hal,从命名空间可知它属于2.1下的 ISensorsCallback.hal

//hardware/interfaces/sensors/2.1/ISensorsCallback.hal

import @2.1::SensorInfo;
interface ISensorsCallback extends @2.0::ISensorsCallback {
    /**
     * Notify the framework that new dynamic sensors have been connected.
     *
     * If a dynamic sensor was previously connected and has not been
     * disconnected, then that sensor must not be included in sensorInfos.
     *
     * @param sensorInfos vector of SensorInfo for each dynamic sensor that
     *     was connected.
     */
    oneway onDynamicSensorsConnected_2_1(vec<SensorInfo> sensorInfos);
};

  2.1版本的ISensorsCallback有继承自 2.0,下面看下2.0版本的定义

//hardware/interfaces/sensors/2.0/ISensorsCallback.hal
import @1.0::SensorInfo;
interface ISensorsCallback {
    /**
     * Notify the framework that new dynamic sensors have been connected.
     *
     * If a dynamic sensor was previously connected and has not been
     * disconnected, then that sensor must not be included in sensorInfos.
     *
     * @param sensorInfos vector of SensorInfo for each dynamic sensor that
     *     was connected.
     */
    oneway onDynamicSensorsConnected(vec<SensorInfo> sensorInfos);

    /**
     * Notify the framework that previously connected dynamic sensors have been
     * disconnected.
     *
     * If a dynamic sensor was previously disconnected and has not been
     * reconnected, then that sensor must not be included in sensorHandles.
     *
     * The HAL must ensure that all sensor events from departing dynamic
     * sensors have been written to the Event FMQ before calling
     * onDynamicSensorsDisconnected.
     *
     * @param sensorHandles vector of sensor handles for each dynamic sensors
     *     that was disconnected.
     */
    oneway onDynamicSensorsDisconnected(vec<int32_t> sensorHandles);
};

  2.1版本的ISensorsCallback中仅仅添加了功能类似的接口onDynamicSensorsConnected_2_1,是因为无法兼容使用2.0版本的接口了onDynamicSensorsConnected,因为他们的入参SensorInfo不同了。关于HIDL的内容见HIDL章节,这里不赘诉。
  下面看看 mSensorDeviceCallback的定义

//frameworks\native\services\sensorservice\HidlSensorHalWrapper.h 
class HidlSensorHalWrapper : public ISensorHalWrapper {
private:
    SensorDeviceCallback* mSensorDeviceCallback = nullptr;
};

  它是在SensorDevice调用connect的时候传入的,至就是它本身的实例指针

//frameworks\native\services\sensorservice\SensorDevice.cpp
mHalWrapper->connect(this)
    //frameworks\native\services\sensorservice\HidlSensorHalWrapper.cpp
    mSensorDeviceCallback = callback;

  其中SensorDeviceCallback为SensorDevice的一个父类。
在这里插入图片描述

  mSensorDeviceCallback又会被 HidlSensorsCallback 封装后赋给 HidlSensorHalWrapper::mCallback,所以 当SensorHal回调的时候,实际上就是调用 HidlSensorsCallback 的一个实例,在其内部在进行转发。类图如下
在这里插入图片描述

  mCallback就是HidlSensorsCallback的一个实例。

2.2.2 mWakeLockQueue的真正面目
typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
std::unique_ptr<WakeLockQueue> mWakeLockQueue;
mWakeLockQueue =
        std::make_unique<WakeLockQueue>(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT,
                                        true /* configureEventFlagWord */);

  WakeLockQueue还是FMQ的那一套没啥好说的。
  至此ISensorsWrapperV2_0->initialize的两个入参讲解完毕,下面看下它拿到连个参数后的实现。

//hardware\interfaces\sensors\common\utils\ISensorsWrapper.h
class ISensorsWrapperV2_0 : public SensorsWrapperBase<hardware::sensors::V2_0::ISensors> {
    Return<Result> initialize(const MQDescriptorSync<uint32_t>& wakeLockDesc,
                                const ::android::sp<ISensorsCallback>& callback) override {
        return mSensors->initialize(*mEventQueue->getDesc(), wakeLockDesc, callback);
    }
};

  mSensors这里和SensorDevice中的mSensors可不是同一类型,前者就是HIDL-ISensor的句柄了,通过它进行的接口调用则是跨进程的了。后者则是调用SensorDevice所在进程的类ISensorsWrapperV2_0实现。
  mEventQueue也是FMQ,用于SensorHal来投递Sensor event到SensorDevice的,下面是对于的定义

typedef MessageQueue<::android::hardware::sensors::V1_0::Event,
                         ::android::hardware::kSynchronizedReadWrite>
ISensorsWrapperV2_0(sp<hardware::sensors::V2_0::ISensors> sensors)
    : SensorsWrapperBase(sensors) {
    auto eventQueue = std::make_unique<EventMessageQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
                                                            true /* configureEventFlagWord */);
    mEventQueue = std::make_unique<EventMessageQueueWrapperV1_0>(eventQueue);
};

  这里又是对FMQ的一层封装,使用类为 EventMessageQueueWrapperV1_0 ,它的类图如下
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐