Sensor HAL 的標頭檔位於 hardware/libhardware/include/hardware/sensors.h,有一個結構 sensor_module_t,它繼承自 hardware_module_t,這個結構是在 hardware.h。sensor_module_t 的變數宣告已在 hardware.h 規定成「HAL_MODULE_INFO_SYM」,這裡頭會定義一個 open 的函式指標,用來初始化 sensor_data_device_t 和 sensor_control_device_t。
const struct sensors_module_t HAL_MODULE_INFO_SYM結構 sensor_data_device_t 定義裝置的 open、close、poll,這些東西會在 SensorManager 叫用;sensor_control_device_t 定義裝置的 activate、delay、wake,這些東西會在 SensorService 叫用。
同一種類型的感測器可能多個,所以是一個 list,不過現在 Froyo 是直接回傳串列的第一個。如果有些函式在底層沒有實作,那 HAL 會直接 return,像 poll function 在 light sensor driver 就沒有實作。所以想要讀 light sensor 的值,只能被動地一直去讀 /sys 下的節點。
/sys 下的檔案是一般類型的檔案,所以 read 之後,需要做 lseek(fd, 0, SEEK_SET); 移回開頭,否則會讀不到東西,第二個參數是指移動多少 byte。另外, lseek(int fildes,0,SEEK_END) 移動到結尾;lseek(int fildes,0,SEEK_CUR) 移動到目前位置 .. <參考>。
PowerManagerService 有處理 proximate sensor 和 light sensor,針對 light sensor 的部分,它會去檢查 framework/base/core/res/res/values/config.xml 的 config_automatic_brightness_available 設定值,如果為 true,它就認為有 light sensor 存在,就會嘗試跟 SensorManager 註冊,並處理 auto brightness 的內容。不過,目前 HAL 吐上來的數值範圍 落在 [10,1000],如果給這個 service 處理會發生問題,需要做轉換。
當系統發生出 ACTION_BOOT_COMPLETED,就去啟動 sensor service,這部分實作 sensor initialization & event callback function。
假設把 source code 放在 hardware/libhardware 底下,需要將 hardware/libhardware/Android.mk 做以下修改,才能在 clean build 編譯到 sensor 的部分。
include $(addsuffix /Android.mk, $(addprefix $(LOCAL_PATH)/, \ modules/gralloc \ modules/sensors \ ))
HAL library 名稱有其規則,可以是 sensors.tegra 或者 sensors.default。另外,sensor library 會呼叫 hw_get_module load() -> dlsym 載入 library。
/* This goes first so that it can pick up a different file on the emulator. */ "ro.hardware", "ro.product.board", "ro.board.platform", "ro.arch"
沒有留言:
張貼留言