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


前言

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

一、Hidl服务的启动

在rc中去启动该hidl,启动的进程为android.hardware.sensors@2.1-service.multihal

/hardware/interfaces/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc

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系统服务)的,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服务这里。眼镜使用的是android.hardware.sensors@2.1-service.multihal,在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层)

请添加图片描述

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;
}
  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中的Sensor驱动框架是用于管理和处理各种传感器数据的软件框架。它的主要功能是提供一种标准化的接口,使应用程序可以轻松地访问和使用各种传感器。 Android中的Sensor驱动框架由以下两个主要组件组成: 1. Sensor HAL(硬件抽象层):这是Android操作系统与各种硬件传感器之间的接口。它定义了一组标准API,使Android可以与各种不同类型的传感器交互。 2. Sensor Manager:这是一个Android系统服务,它提供了一组API,使应用程序可以轻松地获取和使用各种传感器数据。它还负责管理各种传感器的注册和注销,以及传感器数据的传递和处理。 在Android中,可以使用以下几种传感器: 1. 加速度计(Accelerometer):用于测量设备的加速度。 2. 陀螺仪(Gyroscope):用于测量设备的旋转速度和方向。 3. 磁力计(Magnetometer):用于测量设备的磁场。 4. 温度传感器(Temperature Sensor):用于测量设备的温度。 5. 光传感器(Light Sensor):用于测量设备的光线强度。 6. 压力传感器(Pressure Sensor):用于测量环境的气压。 7. 重力传感器(Gravity Sensor):用于测量设备的重力加速度。 8. 线性加速度计(Linear Acceleration Sensor):用于测量设备在三个轴向上的线性加速度。 9. 旋转矢量传感器(Rotation Vector Sensor):用于测量设备的旋转矢量。 以上是Android中常用的传感器类型,每种传感器都有其特定的用途和应用场景。在开发Android应用程序时,可以根据需要选择合适的传感器来获取所需的数据,并使用Sensor驱动框架来管理和处理这些数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值