Java Framework
路徑:
framework/base/core/java/android/os/UEventObserver.java
說明:abstract class UEventObserver
- UEventObserver 為系統監控是否有 uevent 從 kernel 發出來,它是一個抽象類別,程式設計師可以去繼承它,並且實作
abstract void onUEvent(UEvent event);
- 呼叫 startObserving,就會把需要觀察的裝置路徑,儲存在列表中(路徑長得像:"DEVPATH=/devices/...." or "SUBSYSTEM=..."),以便之後和 uevent 字串比對用。
- 因為 UEventObserver 的運作是透過執行緒不斷地去讀取,所以第二步的 startObserving 就會去檢查執行緒起動了沒。另外,這一條執行緒是系統中僅有的一條執行緒,會透過以下變數判斷執行緒是不是已經生成。
static boolean sThreadStarted
- 若執行緒讀到的 uevent 字串,經比對後符合列表中的裝置路徑,就會觸發 onUEvent 這個函式。
class UEvent
- UEvent 這個類別提供一個 HashMap 資料結構,會把透過 socket 收到的 uevent 字串做拆解,把「=」前當成 key、「=」後當成 value,以便 onUEvent 函式需要的時候使用。uevent 的長相如下:(怪怪的字元應該是結束字元)
change@/devices/platform/tegra_i2c.1/i2c-1/1-0058/power_supply/battery�� ACTION=change�� DEVPATH=/devices/platform/tegra_i2c.1/i2c-1/1-0058/power_supply/battery�� SUBSYSTEM=power_supply�� POWER_SUPPLY_NAME=battery�� POWER_SUPPLY_TYPE=Battery�� POWER_SUPPLY_STATUS=Unknown��POWER_SUPPLY_HEALTH=Good�� POWER_SUPPLY_PRESENT=0�� POWER_SUPPLY_TECHNOLOGY=Li-ion��POWER_SUPPLY_VOLTAGE_NOW=0�� POWER_SUPPLY_CAPACITY=0�� POWER_SUPPLY_TEMP=-2731�� SEQNUM=721��
private static native void native_setup(); private static native int next_event(byte[] buffer);
- 這兩個是叫用 JNI 介面,第一個用來做是初始化;第二個是用來讀取 uevent,都在 UEventThread.run() 中使用。
JNI
路徑:
framework/base/core/jni/android_os_UEventObserver.cpp
說明:android_os_UEventObserver_native_setup
- 這就是 UEventObserver.java 的 native_setup 所對應的 JNI 接口,這個函式會呼叫 HAL 中的 uevent_init。
android_os_UEventObserver_next_event
- 這就是 UEventObserver.java 的 next_event 所對應的 JNI 接口,這個函式會呼叫 HAL 中的 uevent_next_event。
HAL(hardware)路徑:
hardware/libhardware_legacy/uevent/uevent.c hardware/libhardware_legacy/include/hardware_legacy/uevent.h說明:
uevent_init()
- 這個函式會建立 AF_NETLINK 類型的 socket,然後 bind。
uevent_next_event(char* buffer, int buffer_length)
- 利用 poll 的方式,對這個 socket fd 作輪詢,如果有資料,就用 recv 去接收,並放在 buffer。poll 的 timeout 等於 -1,代表「Infinitely」。
備註
- Driver 必須要發出 uevent,語法是 kobject_uevent(&kobj, KOBJ_CHANGE),KOBJ_CHANGE 也可以是 KOBJ_ADD、KOBJ_REMOVE。
參考資料
沒有留言:
張貼留言