Android 電池管理系統
一、Android 電池服務
Android電池服務,用來監聽核心上報的電池事件,並將最新的電池資料上報給系統,系統收到新資料後會去更新電池顯示狀態、剩餘電量等資訊。如果收到過溫報警和低電報警,系統會自動觸發關機流程,保護電池和機器不受到危害。
Android電池服務的啟動和執行流程:
Android電池服務的原始碼結構
Framework\base\services\java\com\android\server
├── SystemServer.java
建立BatteryServices、PowerManagerService、ActivityManagerService
├── BatterySevices.java
監聽底層上報的battery事件,廣播電池發生改變的訊息
Framework\base\services\java\com\android\server\am
├── ActivityManagerService.java
建立BatteryStatsService
├── BatteryStatsService.java
統計和記錄電池引數的資訊
Framework\base\services\java\com\android\server\power
├── PowerManagerService.java
監聽電池發生變化的廣播訊息,並調節系統的電源狀態,例如亮屏
Framework\base\core\java\com\internal\os\
├── BatteryStatsImpl.java
統計和記錄電池引數的資訊,並通知其他模組
System\core\healthd
├── healthd.cpp
建立uevent socket,監聽核心上報的核心事件
├── BatteryMonitor.cpp
初始化本地電池資料結構,將power_supply路徑下屬性節點路徑填充進去,
├── BatteryMonitor.h
├── BatteryPropertiesRegistrar.cpp
建立電池屬性監聽器,並將其註冊到Android的系統服務中
├── BatteryPropertiesRegistrar.h
二、Healthd
該模型向下監聽來自底層的電池事件,向上傳遞電池資料資訊給Framework層的BatteryService用來計算電池電量相關資訊,
BatteryService通過傳遞來的資料來計算電池電量等資訊,因此healthd在電池管理系統中起著承上啟下的作用。
三、驅動
Android電源管理底層用的是Linux power_supply框架,核心提供給電池驅動的介面是結構體power_supply結構體。
- struct power_supply {
- const char *name;
- enum power_supply_type type;
- enum power_supply_property *properties;
- size_t num_properties;
- char **supplied_to;
- size_t num_supplicants;
- int (*get_property)(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val);
- int (*set_property)(struct power_supply *psy,
- enum power_supply_property psp,
- const union power_supply_propval *val);
- int (*property_is_writeable)(struct power_supply *psy,
- enum power_supply_property psp);
- void (*external_power_changed)(struct power_supply *psy);
- void (*set_charged)(struct power_supply *psy);
- /* For APM emulation, think legacy userspace. */
- int use_for_apm;
- /* Driver private data */
- void *drv_data;//add by bhj
- /* private */
- struct device *dev;
- struct work_struct changed_work;
- spinlock_t changed_lock;
- bool changed;
- struct wake_lock work_wake_lock;
- struct delayed_work deferred_register_work;
- #ifdef CONFIG_LEDS_TRIGGERS
- struct led_trigger *charging_full_trig;
- char *charging_full_trig_name;
- struct led_trigger *charging_trig;
- char *charging_trig_name;
- struct led_trigger *full_trig;
- char *full_trig_name;
- struct led_trigger *online_trig;
- char *online_trig_name;
- struct led_trigger *charging_blink_full_solid_trig;
- char *charging_blink_full_solid_trig_name;
- #endif
- };</span>
核心主要通過get_property這個函式指標來獲得驅動中的有關電池的資訊,而這個函式在核心中只給出了宣告,我們在寫驅動的
時候要自己實現這個函式,即將自己寫的函式賦值給這個函式指標,當核心需要驅動中電源資訊的時候就回調這個get_property函式
。另外,我們寫驅動程式的時候又要給使用者提供介面,核心中提供給使用者的介面就是sysfs,通過讀取sysfs檔案系統中檔案內容,就
可以得到電源的資訊。核心主要通過兩個檔案power_supply_class.c和power_supply_core.c,我們呼叫其中的函式就可以把電源(電
池,USB或AC)的資訊展現給使用者,有關電源的屬性寫在/sys/class/powersupply資料夾下(此資料夾為程式執行後所生成的)。
電池系統從底層向Framework層上報資料的流程: