PowerUI在SystemUI里的实现比较简单,PowerUI主要处理和Power相关的事件,比如省电模式切换,电池电量变化和开关屏事件等。
PowerUI的启动流程与SystemBars,Recents一样,因为他们都是SystemUI的子类,具体可以看前面的介绍。
public void start() {
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
mWarnings = new PowerNotificationWarnings(mContext, getComponent(PhoneStatusBar.class));
ContentObserver obs = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
updateBatteryWarningLevels();
}
};
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, obs, UserHandle.USER_ALL);
updateBatteryWarningLevels();
mReceiver.init();
}
在PowerUI启动时,会调用start函数,start函数主要实现:
1)实例化PowerManager,因为是处理和Power相关的业务,必须实例化PowerManager.
2)初始化关屏时间,关屏时间会持续刷新。
3)实例化PowerNotificationWarnings,Power相关的事件会通过Notification方式进行处理。
4)监控电池电量,在电量不足是给出警告和提示。
5)更新电池电量等级。
void updateBatteryWarningLevels() {
int critLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
final ContentResolver resolver = mContext.getContentResolver();
int defWarnLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
int warnLevel = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
if (warnLevel == 0) {
warnLevel = defWarnLevel;
}
if (warnLevel < critLevel) {
warnLevel = critLevel;
}
mLowBatteryReminderLevels[0] = warnLevel;
mLowBatteryReminderLevels[1] = critLevel;
mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
+ mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
}
电池电量有三个关键值定义如下(frameworks\base\core\res\res\valuesconfig.xml):
<!– Display low battery warning when battery level dips to this value.
Also, the battery stats are flushed to disk when we hit this level. –>
<integer name=”config_criticalBatteryWarningLevel”>5</integer>
<!– Display low battery warning when battery level dips to this value –>
<integer name=”config_lowBatteryWarningLevel”>15</integer>
<!– Close low battery warning when battery level reaches the lowBatteryWarningLevel
plus this –>
<integer name=”config_lowBatteryCloseWarningBump”>5</integer>
对Receiver进行初始化,注册Receiver处理的广播事件。
public void init() {
// Register for Intent broadcasts for...
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
mContext.registerReceiver(this, filter, null, mHandler);
updateSaverMode();
}
updateSaverMode会查询当时是否是省电模式,并给出Notification通知。
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
final int oldBatteryLevel = mBatteryLevel;
mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
final int oldBatteryStatus = mBatteryStatus;
mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
final int oldPlugType = mPlugType;
mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
final int oldInvalidCharger = mInvalidCharger;
mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);
final boolean plugged = mPlugType != 0;
final boolean oldPlugged = oldPlugType != 0;
int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
int bucket = findBatteryLevelBucket(mBatteryLevel);
if (DEBUG) {
Slog.d(TAG, "buckets ....." + mLowBatteryAlertCloseLevel
+ " .. " + mLowBatteryReminderLevels[0]
+ " .. " + mLowBatteryReminderLevels[1]);
Slog.d(TAG, "level " + oldBatteryLevel + " --> " + mBatteryLevel);
Slog.d(TAG, "status " + oldBatteryStatus + " --> " + mBatteryStatus);
Slog.d(TAG, "plugType " + oldPlugType + " --> " + mPlugType);
Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
Slog.d(TAG, "bucket " + oldBucket + " --> " + bucket);
Slog.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
}
mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
Slog.d(TAG, "showing invalid charger warning");
mWarnings.showInvalidChargerWarning();
return;
} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
mWarnings.dismissInvalidChargerWarning();
} else if (mWarnings.isInvalidChargerWarningShowing()) {
// if invalid charger is showing, don't show low battery
return;
}
if (!plugged
&& (bucket < oldBucket || oldPlugged)
&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& bucket < 0) {
// only play SFX when the dialog comes up or the bucket changes
final boolean playSound = bucket != oldBucket || oldPlugged;
mWarnings.showLowBatteryWarning(playSound);
} else if (plugged || (bucket > oldBucket && bucket > 0)) {
mWarnings.dismissLowBatteryWarning();
} else {
mWarnings.updateLowBatteryWarning();
}
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mScreenOffTime = SystemClock.elapsedRealtime();
} else if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOffTime = -1;
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mWarnings.userSwitched();
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
updateSaverMode();
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGING.equals(action)) {
setSaverMode(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
} else {
Slog.w(TAG, "unknown intent: " + intent);
}
}
};
PowerNotificationWarnings实现PowerUI.WarningsUI函数.。
private void updateNotification() {
if (DEBUG) Slog.d(TAG, "updateNotification mWarning=" + mWarning + " mPlaySound="
+ mPlaySound + " mSaver=" + mSaver + " mInvalidCharger=" + mInvalidCharger);
if (mInvalidCharger) {
showInvalidChargerNotification();
mShowing = SHOWING_INVALID_CHARGER;
} else if (mWarning) {
showWarningNotification();
mShowing = SHOWING_WARNING;
} else if (mSaver) {
showSaverNotification();
mShowing = SHOWING_SAVER;
} else {
mNoMan.cancelAsUser(TAG_NOTIFICATION, R.id.notification_power, UserHandle.ALL);
mShowing = SHOWING_NOTHING;
}
}
会处理PowerUI接收到Power相关事件时fNotification的更新。