iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
0
Mobile Development

Android Pie 底層開發學習心得系列 第 29

[Day-29] Android Pie Sensor (6) 硬件抽象層 (1)

  • Guide:
    • 介紹 (Overview)
    • 架構 (Architecture)
    • 應用 (Application)
    • 服務 (Service)
    • 硬件抽象層 (HAL)

HIDL - binderized

鑑於上一篇介紹完 framework 層 sensor 相關的服務初始和啟動,
這一篇我們來看看 8.0 版本之後的 HAL 架構,
因為 HIDL 已經在先前系列文章探討過了所以就不贅述。
檔案內容在 hardware 底下大概長這樣:

interfaces/sensors/
└── 1.0
    ├── Android.bp
    ├── default
    │   ├── Android.bp
    │   ├── android.hardware.sensors@1.0-service.rc
    │   ├── convert.cpp
    │   ├── include
    │   │   └── sensors
    │   │       └── convert.h
    │   ├── OWNERS
    │   ├── Sensors.cpp
    │   ├── Sensors.h
    │   └── service.cpp
    ├── ISensors.hal
    ├── types.hal
    └── vts
        └── functional
            ├── Android.bp
            ├── GrallocWrapper.cpp
            ├── GrallocWrapper.h
            ├── OWNERS
            └── VtsHalSensorsV1_0TargetTest.cpp

可以看到跟舊版不同的地方式,
有新增一個 service 控制 HAL,
和 framework 的 SensorService (的SensorDevice) 之間通信,
假如你在 adb shell 環境下可以透過 ps 指令查詢得到。
上面編譯成可執行程序放在 /vendor/bin/hw/ 裡。

主要的類由 Sensors 類繼承,
並實現了android::hardware::sensors::V1_0::ISensors
裡面聲明的那些 SensorService 可以通過 HIDL 調用的方法,
activate()poll()flush( )getSensorsLis() 等。
來看一下架構:

hardware/interfaces/sensors/1.0/default/Sensors.cpp

 56 Sensors::Sensors()
 57     : mInitCheck(NO_INIT),
 58       mSensorModule(nullptr),
 59       mSensorDevice(nullptr) {
 60     status_t err = OK;
 61     if (UseMultiHal()) {
**//走這邊,獲取vendor-hal的module的方法**
 62         mSensorModule = ::get_multi_hal_module_info();
 63     } else {
 64         err = **hw_get_module**(
 65             SENSORS_HARDWARE_MODULE_ID,
 66             (hw_module_t const **)&mSensorModule);
 67     } 
 68     if (mSensorModule == NULL) {
 69         err = UNKNOWN_ERROR;
 70     } 
 71       
 72     if (err != OK) {
 73         LOG(ERROR) << "Couldn't load "
 74                    << SENSORS_HARDWARE_MODULE_ID
 75                    << " module ("
 76                    << strerror(-err)
 77                    << ")";
 78       
 79         mInitCheck = err;
 80         return;
 81     } 
 82 
**//這邊是調用了multihal.cpp的open_sensors()方法,對mSensorDevice進行初始化**
 83     err = **sensors_open_1(&mSensorModule->common, &mSensorDevice);**
 84       
 85     if (err != OK) {
 86         LOG(ERROR) << "Couldn't open device for module "
 87                    << SENSORS_HARDWARE_MODULE_ID
 88                    << " ("
 89                    << strerror(-err)
 90                    << ")";
 91       
 92         mInitCheck = err;
 93         return;
 94     }

這裡看到一些 hw_get_modulehw_module_t 就覺得親近很多,
至少你可以發現它只是包了一層 HIDL 服務來實現溝通,
但是基本的 HAL 宣告和實作還是按照以往舊版方式。
我們繼續來看一下 multihal.cppopen_sensors() 方法是如何初始化 mSensorDevice

hardware/libhardware/modules/sensors/multihal.cpp

787 static int open_sensors(const struct hw_module_t* hw_module, const char* name,
788         struct hw_device_t** hw_device_out) { 
789     ALOGV("open_sensors begin...");
790                   
791     lazy_init_modules();  
792                   
793     // Create proxy device, to return later.
794     sensors_poll_context_t *dev = new sensors_poll_context_t();
795     memset(dev, 0, sizeof(sensors_poll_device_1_t));
796     dev->proxy_device.common.tag = HARDWARE_DEVICE_TAG;
797     dev->proxy_device.common.version = SENSORS_DEVICE_API_VERSION_1_4;
798     dev->proxy_device.common.module = const_cast<hw_module_t*>(hw_module);
799     dev->proxy_device.common.close = device__close;
800     dev->proxy_device.activate = device__activate;
801     dev->proxy_device.setDelay = device__setDelay;
802     dev->proxy_device.poll = device__poll;
803     dev->proxy_device.batch = device__batch;
804     dev->proxy_device.flush = device__flush;
805     dev->proxy_device.inject_sensor_data = device__inject_sensor_data;
806     dev->proxy_device.register_direct_channel = device__register_direct_channel;
807     dev->proxy_device.config_direct_report = device__config_direct_report;
808                   
809     dev->nextReadIndex = 0;
810                   
811     // Open() the subhal modules. Remember their devices in a vector parallel to sub_hw_modules.
812     for (std::vector<hw_module_t*>::iterator it = sub_hw_modules->begin();
813             it != sub_hw_modules->end(); it++) { 
814         sensors_module_t *sensors_module = (sensors_module_t*) *it;
815         struct hw_device_t* sub_hw_device;
816         int sub_open_result = sensors_module->common.methods->open(*it, name, &sub_hw_device);
817         if (!sub_open_result) {        
818             if (!HAL_VERSION_IS_COMPLIANT(sub_hw_device->version)) {
819                 ALOGE("SENSORS_DEVICE_API_VERSION_1_3 or newer is required for all sensor HALs");
820                 ALOGE("This HAL reports non-compliant API level : %s",
821                         apiNumToStr(sub_hw_device->version));
822                 ALOGE("Sensors belonging to this HAL will get ignored !");
823             }     
824             dev->addSubHwDevice(sub_hw_device);
825         }
826     }
827      
828     // Prepare the output param and return
829     ***hw_device_out = &dev->proxy_device.common**;
830     ALOGV("...open_sensors end");
831     return 0;
832 }

這邊讓 mSensorDevice 指向 dev->proxy_device.common
之後通過類型轉換,調用 mSensorDevice->xxx()
就等於調用 dev->proxy_device.xxx()
SensorService 調用 activate() 為例來分析一下:

hardware/interfaces/sensors/1.0/default/Sensors.cpp

151 Return<Result> Sensors::activate(
152         int32_t sensor_handle, bool enabled) {
153     return ResultFromStatus(
154             mSensorDevice->activate(       
155                 reinterpret_cast<sensors_poll_device_t *>(mSensorDevice),
156                 sensor_handle,
157                 enabled));
158 }

假如調用 mSensorDevice->activate()
等於調用 dev->proxy_device.activate = device__activate

hardware/libhardware/modules/sensors/multihal.cpp

537 static int device__activate(struct sensors_poll_device_t *dev, int handle,
538         int enabled) { 
539     sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev; 
540     return ctx->activate(handle, enabled);
541 }

再看 sensors_poll_context_t :: active

hardware/libhardware/modules/sensors/multihal.cpp

310 int sensors_poll_context_t::activate(int handle, int enabled) {
311     int retval = -EINVAL;
312     ALOGV("activate");    
313     int local_handle = get_local_handle(handle);
314     sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
315     if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
316         retval = v0->activate(v0, local_handle, enabled);
317     } else {
318         ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
319                 enabled, handle);              
320     }
321     ALOGV("retval %d", retval);
322     return retval;
323 }

下一篇我們就來稍微看看 hardware 底下 sensor 的其他文件吧!


Reference :

https://blog.csdn.net/goodnight1994/article/details/80259222


上一篇
[Day-28] Android Pie Sensor (5) 服務 (2)
下一篇
[Day-30] Android Pie Sensor (7) 硬件抽象層 (2)
系列文
Android Pie 底層開發學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言