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);
}
分享到:
相关推荐
本文档是一份对android之kernel3.0的电源管理部分的简单介绍与流程分析,是通过能源码的分析总结而成,内容涉及到kernel电源管理,与android系统的交互,各驱动模块的注册以及休眠与唤醒,同时也介绍了wakelock的...
第4章分析了Android电源管理模块的机制与实现;第5章全面地剖析了Android硬件设备驱动(显示、视频、音频、MTD、Event、蓝牙、WLAN等)的工作原理和实现,掌握这部分内容即可修改和编写基于Android的设备驱动程序;...
第4章分析了Android电源管理模块的机制与实现;第5章全面地剖析了Android硬件设备驱动(显示、视频、音频、MTD、Event、蓝牙、WLAN等)的工作原理和实现,掌握这部分内容即可修改和编写基于Android的设备驱动程序;...
第一部分中将首先介绍Android,内容涉及如何安装Android模拟器,如何使用IDE(Intergrated Development Environment,集成开发环境)编写第一个程序。然后,我们将介绍一些基本的概念,比如Android中的生命周期。...
拯救电源键】最详尽的android开发一键锁屏实例 源码.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
内容包括Android平台概览、Android应用程序设计精髓、Android用户界面设计精髓、Android应用程序设计精髓、对外发布你的Android应用程序和附录6个部分。附录还包含了Android开发常用工具(模拟器、DDMS和Eclipse)的...
1.使用Android电源管理widget 从Android 2.1系统开始内置了一个非常强大的带能源管理widget,通过这个widget你可以快速开启或者关闭Wi-Fi,蓝牙,GPS,同步这些手机耗电大户,还可以方便的设定手机屏幕亮度,长按手机...
第4章分析了Android电源管理模块的机制与实现;第5章全面地剖析了Android硬件设备驱动(显示、视频、音频、MTD、Event、蓝牙、WLAN等)的工作原理和实现,掌握这部分内容即可修改和编写基于Android的设备驱动程序;...
第4章分析了Android电源管理模块的机制与实现;第5章全面地剖析了Android硬件设备驱动(显示、视频、音频、MTD、Event、蓝牙、WLAN等)的工作原理和实现,掌握这部分内容即可修改和编写基于Android的设备驱动程序;...
首先我们发现现在我们所用的android智能手机大部分都有当你在打电话时按power键来挂断电话,一般都是在设置中。 我主要是在原生源码中添加这一功能,主要用于学习。。。。先看一张图: 看到那个按电源键挂断电话吧,...
本文实例讲述了Android电源管理。分享给大家供大家参考,具体如下: 一、 相关概念 1. 出于节电的需要,一般应用在用户一段时间无操作的情况下屏幕变暗,然后进入休眠状态 2. 用户只能在”设置->声音和显示”中设置...
FT311D硬件接口应用程序主要包括两部分,即用户层User Layer和接口层Layer,用户层面向高层应用程序开发,程序员不需要过多考虑Android设备与FT311D接口芯片通信的具体细节,只需要借助相应的用户函数即可实现USB转...
Android的电源管理也是很重要的一部分。比如在待机的时候关掉不用的设备,timeout之后的屏幕和键盘背光的关闭,用户操作的时候该打开多少设备等等,这些都直接关系到产品的待机时间,以及用户体验。
c) Java运⾏环境(ANDROIDRUNTIME) Android运⾏库包括两部分:⼀是核⼼库,⼆是⾃⾝的Dalvik虚拟机。 核⼼库提供Java编程语⾔核⼼库的⼤多数功能。 Dalvik虚拟机是Google专为Android开发的 。每⼀个Android应⽤程序都...
1.11 android系统支持app2sd(修改boot.img) 27 2 基本概念 30 2.1 Android组件 31 2.1.1 基本组件 31 2.1.2 组件间的通讯 32 2.1.3 intent使用方法 33 2.2 界面开发 35 2.2.1 界面元素 35 2.2.2 布局的实现 36 ...
Android 电源管理 -- wakelock机制,通过控制wakelock 实现保持pad 禁止休眠状态; Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠, 可以被用户态程序和内核获得. 这个锁可以是有超时的 或者 是...
Chapter Eight:指南一 按键、电源部分介绍 Chapter Nine:指南二 添加自己的项目相关内容 Chapter Ten 指南三 Chapter Eleven:指南四 扩展外设的应用及实践 Chapter Twelve:指南五 应用开发和实践 p ...
2、android编译环境以及相关指令(包括各个模块的编译以及编译命令) 3、代码自动生成, 4、FLASH以及各个模块在FLASH上的地址 5、Bootloader 6、DCT的使用:按键、中断、ADC、GPIO、电源设置 7、灯控制 8、电源芯片...