前言
加量不加價,更新來一波
整體框圖
不記得從哪保存的好圖了
硬件/內核相關
相關概念
懶的排版了,直接上圖
相關文件關係
再來一發
雜項,電池溫度檢測原理圖
發
充電流程
圖樣圖森破
核心函數特寫
Android 相關
Healthd 就是一個 daemon service,取代以前的 battery JNI ,
1.定期讀取 sys/class/power_supply 的檔案, 包含所有關於電池的必要資訊(電壓, 電流, 溫度,狀態 etc)
2.將上述讀取的資訊寫入至 battery property, 讓 android battery Service update
Healthd 啓動流程
// system\core\rootdir\init.rc
service healthd /sbin/healthd
class core
critical
seclabel u:r:healthd:s0
group root system wakelock
// 對應的代碼路徑爲:
// Healthd.cpp (system\core\healthd)
int main(int argc, char **argv)
//////////////////////////////////////////////////////////////////////////////
// 1. 根據不同的啓動模式,設置 healthd_mode_ops 爲不同的操作函數集
// 當開機充電時變量賦值爲 &android_ops,關機充電時候變量賦值爲 &charger_ops
//healthd_mode_ops = &android_ops;
//
// 2.用 epoll 監聽了:
// 1. Binder 通信事件
// 2. 定時器事件
// 3. Netlink 實現的 uevent 事件
// 然後遍歷 /sys/class/power_supply/ 下的結點,設置全局變量 healthd_config
//ret = healthd_init();
// // 創建了一個 epoll 輪詢象
// epollfd = epoll_create(MAX_EPOLL_EVENTS);
// // 這裏就開機充電的情況下分析,調用 android_ops->init()
// // 主要是進行了 Binder 相關初始化,並註冊了一個服務 "batteryproperties"
// // 到 servicemanager 中進行管理
// healthd_mode_ops->init(&healthd_config);
//
// // 主要是創建了一個定時器,24小時執行一次?
// wakealarm_init();
//
// // 用 epoll 監聽 netlink 上報的 uevent 事件
// uevent_init();
//
// // 創建 BatteryMonitor 的對象,並將其初始化。BatteryMonitor
// // 主要接受 healthd 傳來的數據,做電池狀態的計算並更新
// gBatteryMonitor = new BatteryMonitor();
//
// // 主要是根據路徑下節點設置全局變量 healthd_config
// // POWER_SUPPLY_SYSFS_PATH 定義爲 "/sys/class/power_supply",
// // 在 init 函數中打開系統該文件夾,然後一一讀取該文件夾下的文
// // 件內容,在 while 循環中判斷該文件夾下各個文件節點的內容,
// // 並將其初始化給相關的參數
// gBatteryMonitor->init(&healthd_config);
//
//
// 3. 死循環,
// 監聽 epoll 事件,並調用相應的回調函數進行處理:
// 1> uevent_event() 處理內核 Netlink 上報的數據
// // 當 sys 屬性變化時,寫入 log, 通知監聽者
// 2> wakealarm_event(): 處理定時器喚醒
// 3> binder_event(): 處理 Binder 通信
// 如果沒有事件,則根據 sys 屬性變化,寫入 log, 通知監聽者 BatteryPropertiesRegistrar::notifyListeners()
//healthd_mainloop();
BatteryService
接口:frameworks\base\core\java\com\android\internal\app\IBatteryStats.aidl
【初始化流程】
zygote
SystemServer
// 入口函數
main(String[] args)
new SystemServer().run();
startBootstrapServices();
startCoreServices();
mSystemServiceManager.startService(BatteryService.class);
////////////////////////////////////////////////////////////////////////////
// frameworks\base\services\core\java\com\android\server\SystemServiceManager.java
// 創建一個繼承 SystemService 的子類
public <T extends SystemService> T startService(Class<T> serviceClass)
// 獲得 Class 名稱
final String name = serviceClass.getName();
// 獲得構造函數: public BatteryService(Context context)
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
// 調用構造函數,創建類對象
service = constructor.newInstance(mContext);
///////////////////////////////////////////////////////////////
// frameworks\base\services\core\java\com\android\server\BatteryService.java
BatteryService::BatteryService()
// LED 燈光顯示
mLed = new Led(context, getLocalService(LightsManager.class));
// 相關警告電量配置
// 添加到鏈表中進行管理
mServices.add(service);
// 啓動服務
service.onStart();
// frameworks\base\services\core\java\com\android\server\BatteryService.java
public void onStart()
// 1. 首先將電池監聽註冊到底層去, 底層電量變化,會【調用 update()】
IBinder b = ServiceManager.getService("batteryproperties");
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
//電池監聽,註冊到底層。當底層電量改變會調用此監聽。然後執行 update
batteryPropertiesRegistrar.registerListener(new BatteryListener());
///////////////////////////////////////////////////////////
// 2. 如果是 IPO 開關機的話,需要監聽廣播
if (SystemProperties.get("ro.mtk_ipo_support").equals("1")) 。。。
// 3. 將本地接口 publish 出去,
// 創建一個內部類 BinderService 對象
mBinderService = new BinderService();
底層電量更新流程
// 當底層電池狀態更新時,healthd 會回調 BatteryPropertiesRegistrar::notifyListeners()
// 而此類是通過 Binder 通信註冊了回調的,當有事件時會調用回調 update():
// IBinder b = ServiceManager.getService("batteryproperties"); // BatteryPropertiesRegistrar.cpp 註冊的
// final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
// batteryPropertiesRegistrar.registerListener(new BatteryListener());
private final class BatteryListener extends IBatteryPropertiesListener.Stub
BatteryService.this.update(props);
processValuesLocked(false);
// //解析充電類型
if (mBatteryProps.chargerAcOnline) 。。。
// 充電指示燈更新
mLed.updateLightsLocked();
// 沒電了
shutdownIfNoPowerLocked();
// 溫度過高
shutdownIfOverTempLocked();
// 發送電池狀態變化的廣播
sendIntentLocked();
#什麼!還要了解?請看源碼
地址:鏈接: http://pan.baidu.com/s/1kV3DKNX 密碼: uiyb