BatteryService作为电池及充电相关的服务,它的实现非常简单:
o 监听UEvent,读取sysfs里中的状态。
实现了一个UEvent的观察者。uevent是Linux内核用来向用户空间主动上报事件的机制,对于JAVA程序来说,只实现UEventObserver的虚函数onUEvent,然后注册即可。
private UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
update();
}
};
这里只关注power_supply的事件:
mUEventObserver.startObserving("SUBSYSTEM=power_supply");
当有power_supply相关的事件上报时,就会调用update函数。
update先调用native_update从sysfs中读取相关状态(com_android_server_BatteryService.cpp):
Linux驱动提供了下列文件,供应用程序获取电源相关状态:
#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"
#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"
#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"
#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"
#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"
#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"
#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"
#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"
#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"
在<DA9034驱动程序阅读笔记(6)>一文中,我已经提到drivers/power/micco_power.c里注册了充电器(ac)、 usb和电池(battery)三个power_supply。各个power_supply提供的属性和上述文件是对应的,从这些文件中可以读到充电器 (ac)、usb和电池(battery)三个power_supply的相应状态。
update然后根据读到的状态更新BatteryService的成员变量,并广播一个Intent来通知其它关注电源状态的组件。
private final void sendIntent() {
// Pack up the values and broadcast them to everyone
Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
try {
mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel);
} catch (RemoteException e) {
// Should never happen.
}
int icon = getIcon(mBatteryLevel);
intent.putExtra("status", mBatteryStatus);
intent.putExtra("health", mBatteryHealth);
intent.putExtra("present", mBatteryPresent);
intent.putExtra("level", mBatteryLevel);
intent.putExtra("scale", BATTERY_SCALE);
intent.putExtra("icon-small", icon);
intent.putExtra("plugged", mPlugType);
intent.putExtra("voltage", mBatteryVoltage);
intent.putExtra("temperature", mBatteryTemperature);
intent.putExtra("technology", mBatteryTechnology );
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
关注ACTION_BATTERY_CHANGED的地方有好几个:
o KeyguardUpdateMonitor 这里主要是用来更新锁屏界面下的电池状态。还有低电警告和关机也是在这里做的。
private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
final boolean pluggedIn = isPluggedIn(pluggedInStatus);
if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) {
mBatteryLevel = batteryLevel;
mDevicePluggedIn = pluggedIn;
for (int i = 0; i < mInfoCallbacks.size(); i++) {
mInfoCallbacks.get(i).onRefreshBatteryInfo(
shouldShowBatteryInfo(), pluggedIn, batteryLevel);
}
}
// shut down gracefully if our battery is critically low and we are not powered
if (batteryLevel == 0 &&
pluggedInStatus != BATTERY_STATUS_CHARGING &&
pluggedInStatus != BATTERY_STATUS_UNKNOWN) {
ShutdownThread.shutdownAfterDisablingRadio(mContext, false);
}
}
o NotificationManagerService 用来更新充电状态(LED)
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
boolean batteryCharging = (intent.getIntExtra("plugged", 0) != 0);
int level = intent.getIntExtra("level", -1);
boolean batteryLow = (level >= 0 && level <= Power.LOW_BATTERY_THRESHOLD);
int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
boolean batteryFull = (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90);
if (batteryCharging != mBatteryCharging ||
batteryLow != mBatteryLow ||
batteryFull != mBatteryFull) {
mBatteryCharging = batteryCharging;
mBatteryLow = batteryLow;
mBatteryFull = batteryFull;
updateLights();
}
}
o PowerManagerService 这里主要是做两件事件,先是检查是否在充电时不允许睡眠,并采用相应的行动,其次是触发一个用户行为(会影响下一次睡眠的时间)。
private final class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLocks) {
boolean wasPowered = mIsPowered;
mIsPowered = mBatteryService.isPowered();
if (mIsPowered != wasPowered) {
// update mStayOnWhilePluggedIn wake lock
updateWakeLockLocked();
// treat plugging and unplugging the devices as a user activity.
// users find it disconcerting when they unplug the device
// and it shuts off right away.
// temporarily set mUserActivityAllowed to true so this will work
// even when the keyguard is on.
synchronized (mLocks) {
boolean savedActivityAllowed = mUserActivityAllowed;
mUserActivityAllowed = true;
userActivity(SystemClock.uptimeMillis(), false);
mUserActivityAllowed = savedActivityAllowed;
}
}
}
}
}
o LocationManagerService 这里似乎没有什么用处,我没找到mCollector赋值的地方。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
log("PowerStateBroadcastReceiver: Battery changed");
synchronized (mLocationListeners) {
int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;
// Notify collector battery state
if (mCollector != null) {
mCollector.updateBatteryState(scale, level, plugged);
}
}
}
o WifiService 根据电源状态来决定是否需要定时唤醒(没搞得太明白,看Wifi服务时再研究)。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
* AND we are transitioning from a state in which the device was supposed
* to stay awake to a state in which it is not supposed to stay awake.
* If "stay awake" state is not changing, we do nothing, to avoid resetting
* the already-set timer.
*/
int pluggedType = intent.getIntExtra("plugged", 0);
if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
!shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
long triggerTime = System.currentTimeMillis() + idleMillis;
mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
mPluggedType = pluggedType;
return;
}
mPluggedType = pluggedType;
}
o StatusBarPolicy用来更新状态栏上的充电图标。
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
updateBattery(intent);
}
分享到:
相关推荐
Wakelock是Android电源管理中的另一关键组件,它允许应用程序或服务请求保持设备的部分或全部活跃。Wakelocks可以阻止设备进入休眠状态,直到释放Wakelock。根据需要,Wakelocks可以是全局的(阻止整个设备休眠)或...
1. **Power HAL**(Hardware Abstraction Layer):是Android电源管理的核心接口,它提供了一套标准的接口供上层系统服务调用,用于控制硬件的电源状态。Power HAL实现了与具体硬件平台相关的电源管理功能。 2. **...
Android电源管理可以分为两部分:硬件电源管理和软件电源管理。硬件电源管理主要是通过硬件设备来控制电源的使用,如关闭不必要的设备、降低CPU的频率等。软件电源管理主要是通过软件来控制电源的使用,如使用Wake...
### Android电源管理相关应用技巧详解 #### 一、引言 随着智能手机的普及和技术的发展,Android作为主流的移动操作系统之一,其电源管理技术对于提升用户体验至关重要。本文将深入探讨Android电源管理的技术细节,...
Android电源管理分为软件和硬件两部分,前者主要通过系统服务进行,后者则依赖于硬件平台的固件支持。 Android电源管理系统主要由以下几个组件组成: 1. **Power HAL(Hardware Abstraction Layer)**:这是硬件...
Android电源管理是操作系统中一个至关重要的部分,它涉及到设备的电池寿命、性能优化以及用户体验。在Android系统中,电源管理主要目标是确保设备在不牺牲用户体验的前提下尽可能地节省电力。本文将深入探讨Android...
### Android电源管理详解 #### 一、概述 在Android系统中,电源管理是一个非常重要的功能模块,它直接关系到移动设备的续航能力。良好的电源管理不仅能够提升用户体验,还能增加设备的整体性能。本文将深入探讨...
本示例项目"android电源管理显示例子"提供了一个完整的实现,展示了如何获取并显示设备的电源状态信息。以下是这个项目涉及的一些核心知识点: 1. **PowerManager**: PowerManager是Android SDK中的一个关键类,...
Wake_Lock是Android电源管理中的一个重要机制,它允许开发者或系统服务阻止设备进入休眠状态。当应用程序或服务需要保持活动时(例如,后台下载、闹钟或电话通话),它可以通过获取Wake_Lock来确保CPU和相关硬件保持...
这个“android 部分学习资料”压缩包很可能是包含了一系列与Android开发相关的教程、文档、代码示例等资源,帮助初学者或者有经验的开发者深入理解Android平台的工作原理和开发技巧。 1. **Android基础知识** - **...
### Android的电话部分(Telephony)原理及实现 #### 第一部分 Android电话部分的综述 Android作为一款全球广泛使用的智能手机操作系统,其电话部分(Telephony)功能是核心且不可或缺的一部分。这一部分主要负责...
2. **HAL(硬件抽象层)**: 在system层下,硬件抽象层允许Android与特定硬件设备进行交互。HAL封装了硬件接口,为上层的系统服务和框架层提供统一的API,确保不同硬件平台上的兼容性。例如,Camera HAL、Display HAL、...
虽然这部分源码可能不包括完整的内核,但会包含与Android系统相关的驱动和子系统,如电源管理、内存管理、网络堆栈等。理解这部分源码有助于进行底层优化和硬件集成。 4. **Framework层**: 这包括Activity...
Android SDK Platforms 21包含了开发Android 5.0应用所需的所有工具和库,是Android开发者不可或缺的部分。 1. **Material Design**:Android 5.0引入了全新的设计语言——Material Design。这种设计风格强调层次感...
### Android的电话部分知识点 #### 一、Android电话部分的综述 Android作为现代智能手机操作系统的重要组成部分,其电话部分的设计尤为关键。这部分不仅涉及到基本的通话功能,还包括短信(SMS)、数据连接(Data ...
3. **Build Tools**:这部分工具用于构建和打包Android应用,包括AAPT2(Android Asset Packaging Tool)用于资源处理,dx和D8用于字节码转换,以及ProGuard和R8用于代码混淆和优化。 4. **Android Emulator**:SDK...