Android Sensor模块解析(Sensor Hidl服务)

文章目录

  • 前言
  • 一、Hidl服务的启动
  • 二、Sensor注册监听调用流程(Hidl层)
  • 三、Sensor接收数据流程(Hidl层)


前言

Sensor Hidl服务在眼镜中是一个[email protected]进程
请添加图片描述
它其实是sensor hal的hidl实现,sensor hal也是在这个进程中的。
Sensor hidl的代码位置主要在
/hardware/interfaces/sensors/2.1/multihal/
/hardware/interfaces/sensors/common/default/2.X/multihal/

一、Hidl服务的启动

在rc中去启动该hidl,启动的进程为[email protected]

/hardware/interfaces/sensors/2.1/multihal/[email protected]

service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.multihal
    class hal
    user system
    group system wakelock context_hub
    writepid /dev/cpuset/system-background/tasks
    capabilities BLOCK_SUSPEND
    rlimit rtprio 10 10

New 一个 HalProxyV2_1对象并注册为服务。
/hardware/interfaces/sensors/common/default/2.X/multihal/include/HalProxy.h

class HalProxyV2_1 : public IHalProxy<V2_1::ISensors> {
   ......
};

class IHalProxy : public HalProxy, public ISensorsVersion {
   ......
};

因此实际是调用了HalProxy的无参构造函数
/hardware/interfaces/sensors/common/default/2.X/multihal/HalProxy.cpp

HalProxy::HalProxy() {
    const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
    initializeSubHalListFromConfigFile(kMultiHalConfigFile);
    init();
}

这里会有一个/vendor/etc/sensors/hals.conf文件,在高通的平台下,这个文件里的内容是"sensors.ssc.so",既是高通hal编译出的内容。
initializeSubHalListFromConfigFile方法中,会打开该so文件,并使用dlsym方法来尝试找到高通hal中sensorsHalGetSubHal_2_1函数的地址,之后调用该地址的函数从而调用到了高通hal中的sensorsHalGetSubHal_2_1方法取得subHal。之后根据该subHal来构造SubHalWrapperV2_1对象,并加入了mSubHalList中
mSubHalList是一个列表,可以放多个SubHalWrapperV2_1对象。这个体现了sensor_multihal的作用,即可以统一管理多个厂商sensor的hal。
/hardware/interfaces/sensors/common/default/2.X/multihal/HalProxy.cpp

void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {    std::ifstream subHalConfigStream(configFileName);
    if (!subHalConfigStream) {
        ALOGE("Failed to load subHal config file: %s", configFileName);
    } else {
        std::string subHalLibraryFile;
        while (subHalConfigStream >> subHalLibraryFile) {
            void* handle = getHandleForSubHalSharedObject(subHalLibraryFile);
            ......
                } else {
                    SensorsHalGetSubHalV2_1Func* getSubHalV2_1Ptr =
                            (SensorsHalGetSubHalV2_1Func*)dlsym(handle, "sensorsHalGetSubHal_2_1");

                    if (getSubHalV2_1Ptr == nullptr) {
                        ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s",
                              subHalLibraryFile.c_str());
                    } else {
                        std::function<SensorsHalGetSubHalV2_1Func> sensorsHalGetSubHal_2_1 =
                                *getSubHalV2_1Ptr;
                        uint32_t version;
                        ISensorsSubHalV2_1* subHal = sensorsHalGetSubHal_2_1(&version);
                       ......
                            ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
                            mSubHalList.push_back(std::make_unique<SubHalWrapperV2_1>(subHal));
                        }
                    }
                }
            }
        }
    }
}

如果是高通平台的话,则sensorsHalGetSubHal_2_1方法的实现是在高通的sensors.ssc.so中,这里hal部分我们不再继续分析,后续有机会参与高通项目的可以查看这部分代码。

二、Sensor注册监听调用流程(Hidl层)

Android Sensor模块解析(Sensor Hidl服务)_第1张图片
接上之前Android Sensor模块解析(Sensor系统服务)的,SensorService调用了enable方法。

/frameworks/native/services/sensorservice/SensorService.cpp

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;

    sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
    
.....
    if (err == NO_ERROR) {
        ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
        err = sensor->activate(connection.get(), true);
    }
......
    return err;
}

sensor是之前在onFirstRef中添加的 HardwareSensor对象,其继承自SensorInterface类。avtivate方法是调用了SensorDevice的activate方法。
/frameworks/native/services/sensorservice/SensorInterface.cpp

status_t HardwareSensor::activate(void* ident, bool enabled) {    
    return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
}

在SensorDevice中,调用到了mSensors的activate方法,传入了handle值来表明要打开哪个sensor。

status_t SensorDevice::activate(void* ident, int handle, int enabled) {    
    if (mSensors == nullptr) return NO_INIT;
    Mutex::Autolock _l(mLock);
    return activateLocked(ident, handle, enabled);
}

status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
    ......
    if (activateHardware) {
        err = doActivateHardwareLocked(handle, enabled);
    ......
    return err;
}

status_t SensorDevice::doActivateHardwareLocked(int handle, bool enabled) {    
    ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
             enabled);
    status_t err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
    ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
             strerror(-err));
    return err;
}

mSensors是在连接hidl服务的时候创建的一个ISensorsWrapperV2_1对象,在构造该对象时,将sensor的hidl服务作为参数传入。

SensorDevice::HalConnectionStatus SensorDevice::connectHidlServiceV2_1() {    
    HalConnectionStatus connectionStatus = HalConnectionStatus::UNKNOWN;
    sp<V2_1::ISensors> sensors = V2_1::ISensors::getService();
    if (sensors == nullptr) {
        connectionStatus = HalConnectionStatus::DOES_NOT_EXIST;
    } else {
        mSensors = new ISensorsWrapperV2_1(sensors);
        connectionStatus = initializeHidlServiceV2_X();
    }

    return connectionStatus;
}

ISensorsWrapperV2_1继承自SensorsWrapperBase,SensorsWrapperBase的activate方法又调用内部mSensors对象的activate方法,这样就调用到了2.1的sensor hidl服务的activate方法。
/hardware/interfaces/sensors/common/utils/ISensorsWrapper.h

Return<Result> activate(int32_t sensorHandle, bool enabled) override {
    return mSensors->activate(sensorHandle, enabled);
}

于是从系统的systemserver来到了hidl服务这里。眼镜使用的是[email protected],在service.cpp中将halProxy注册到系统。
/hardware/interfaces/sensors/2.1/multihal/service.cpp

int main(int /* argc */, char** /* argv */) {    
    ......
    android::sp<ISensors> halProxy = new HalProxyV2_1();
    if (halProxy->registerAsService() != ::android::OK) {
        ALOGE("Failed to register Sensors HAL instance");
        return -1;
    }

    joinRpcThreadpool();
    return 1;  // joinRpcThreadpool shouldn't exit
}

我们再回到activate上来,调用hidl服务的activate既是调用了HalProxy的activate方法。

Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
    if (!isSubHalIndexValid(sensorHandle)) {
        return Result::BAD_VALUE;
    }
    return getSubHalForSensorHandle(sensorHandle)
            ->activate(clearSubHalIndex(sensorHandle), enabled);
}

这里根据传入的sensorHandle的值找到了对应的ISubHalWrapperBase的对象。这个ISubHalWrapperBase对象其实是之前push_back到mSubHalList中的SubHalWrapperV2_1。

class SubHalWrapperV2_1 : public SubHalWrapperBase<V2_1::implementation::ISensorsSubHal> {
  ......
};

Return<Result> activate(int32_t sensorHandle, bool enabled) override {
        return mSubHal->activate(sensorHandle, enabled);
}

SubHalWrapperV2_1的activate方法调用了mSubHal的activate方法,根据前面的介绍,这个mSubHal即高通sensors.ssc.so中实现的ISensorsSubHal*。之后会在高通的sensor hal总继续完成调用。

三、Sensor接收数据流程(Hidl层)

Android Sensor模块解析(Sensor Hidl服务)_第2张图片

systemServer进程中创建了快速消息队列以及eventQueue,通过hidl通信将eventQueue的Desc传递给了hidl服务。sensor的hidl服务中通过该Desc还原出对应的eventQueue。

Return<Result> HalProxy::initialize_2_1(
        const ::android::hardware::MQDescriptorSync<V2_1::Event>& eventQueueDescriptor,
        const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
        const sp<V2_1::ISensorsCallback>& sensorsCallback) {
    sp<ISensorsCallbackWrapperBase> dynamicCallback =
            new ISensorsCallbackWrapperV2_1(sensorsCallback);

    // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.auto eventQueue =
            std::make_unique<EventMessageQueueV2_1>(eventQueueDescriptor, true /* resetPointers */);
    std::unique_ptr<EventMessageQueueWrapperBase> queue =
            std::make_unique<EventMessageQueueWrapperV2_1>(eventQueue);

    return initializeCommon(queue, wakeLockDescriptor, dynamicCallback);

在initializeCommon方法中,将mEventQueue进行赋值

Return<Result> HalProxy::initializeCommon(
        std::unique_ptr<EventMessageQueueWrapperBase>& eventQueue,
        const ::android::hardware::MQDescriptorSync<uint32_t>& wakeLockDescriptor,
        const sp<ISensorsCallbackWrapperBase>& sensorsCallback) {
......

    // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions.
    mEventQueue = std::move(eventQueue);

在HalProxy的postEventsToMessageQueue方法里,调用了mEventQueue的write方法。

这里实际上是使用跨进程的FMQ快速消息队列来及逆行数据的发送,底层的原理是共享内存。这里hidl进程的FMQ服务端进行数据的发送。而systemServer进程中的FMQ客户端进行数据的接收。

/hardware/interfaces/sensors/common/default/2.X/multihal/HalProxy.cpp

void HalProxy::postEventsToMessageQueue(const std::vector<Event>& events, size_t numWakeupEvents,
                                        V2_0::implementation::ScopedWakelock wakelock) {
    ......
            if (mEventQueue->write(events.data(), numToWrite)) {
                // TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit// in more writes immediately
                //写数据之后调用wake通知读端进行数据的读取
                mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
            } else {
                numToWrite = 0;
            }
        }
    }
   ......
}

在SensorDevice中的pollFmq中,通过getEventQueue()来获得EventMessageQueueWrapperV2_1对象(该对象不是hidl进程中的那个EventMessageQueueWrapperV2_1),并调用其的read方法,通过这种方式,将sensor的数据写入了mEventBuffer。
之后便回到Sensor的framework层的方法中回调上去,这个可以看之前sensor系统服务的分析。
/frameworks/native/services/sensorservice/SensorDevice.cpp

ssize_t SensorDevice::pollFmq(sensors_event_t* buffer, size_t maxNumEventsToRead) {    ssize_t eventsRead = 0;
    ......
    if (eventsToRead > 0) {
        if (mSensors->getEventQueue()->read(mEventBuffer.data(), eventsToRead)) {
            // Notify the Sensors HAL that sensor events have been read. This is required to support// the use of writeBlocking by the Sensors HAL.mEventQueueFlag->wake(asBaseType(EventQueueFlagBits::EVENTS_READ));
    ......
    return eventsRead;
}

你可能感兴趣的:(android,c++)