PowerUI 的启动流程及其功用。
PowerUI
PowerUI
是 SystemUI
显示电池相关信息的模块,包括低电量提醒、危急电量关机提醒、高温关机提醒、省电模式等功能。
启动流程
上一篇介绍 SystemUI
启动时会加载众多功能模块其中就包含 PowerUI
,其会直接调用 PowerUI.start()
方法来启动。
PowerUI.start()
|
|
低电量警告
updateBatteryWarningLevels()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
void updateBatteryWarningLevels() { // 获取系统配置的危急电量值,默认:5 int critLevel = mContext.getResources() .getInteger(com.android.internal.R.integer.config_criticalBatteryWarningLevel); // 获取系统配置的低电量值,默认:15 int warnLevel = mContext.getResources() .getInteger(com.android.internal.R.integer.config_lowBatteryWarningLevel); if (warnLevel < critLevel) { warnLevel = critLevel; } mLowBatteryReminderLevels[0] = warnLevel; mLowBatteryReminderLevels[1] = critLevel; // 获取系统配置的关闭低电量警告状态的电量值,默认:20(15+5) mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0] + mContext.getResources() .getInteger(com.android.internal.R.integer.config_lowBatteryCloseWarningBump); }
电池相关广播监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
final class Receiver extends BroadcastReceiver { public void init() { // Register for Intent broadcasts for... IntentFilter filter = new IntentFilter(); // 省电模式改变 filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); // 电池状态改变 filter.addAction(Intent.ACTION_BATTERY_CHANGED); // 开关屏 filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); // 切换用户 filter.addAction(Intent.ACTION_USER_SWITCHED); mContext.registerReceiver(this, filter, null, mHandler); } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) { ThreadUtils.postOnBackgroundThread(() -> { if (mPowerManager.isPowerSaveMode()) { // 开启省电模式则关闭低电量警告 mWarnings.dismissLowBatteryWarning(); } }); } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { // 电量 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); // 更新电池警告信息 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; } // Show the correct version of low battery warning if needed ThreadUtils.postOnBackgroundThread(() -> { // 判断是否要显示低电量警告 maybeShowBatteryWarning( oldBatteryLevel, plugged, oldPlugged, oldBucket, bucket); }); } 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 { Slog.w(TAG, "unknown intent: " + intent); } } }
maybeShowBatteryWarning()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
protected void maybeShowBatteryWarning(int oldBatteryLevel, boolean plugged, boolean oldPlugged, int oldBucket, int bucket) { boolean isPowerSaver = mPowerManager.isPowerSaveMode(); // only play SFX when the dialog comes up or the bucket changes final boolean playSound = bucket != oldBucket || oldPlugged; // ...... if (shouldShowLowBatteryWarning(plugged, oldPlugged, oldBucket, bucket, mTimeRemaining, isPowerSaver, mBatteryStatus)) { mWarnings.showLowBatteryWarning(playSound); } else if (shouldDismissLowBatteryWarning(plugged, oldBucket, bucket, mTimeRemaining, isPowerSaver)) { mWarnings.dismissLowBatteryWarning(); } else { mWarnings.updateLowBatteryWarning(); } }
高温警告
initTemperatureWarning()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
private void initTemperatureWarning() { // 是否开启高温警告,默认关闭 ContentResolver resolver = mContext.getContentResolver(); Resources resources = mContext.getResources(); if (Settings.Global.getInt(resolver, Settings.Global.SHOW_TEMPERATURE_WARNING, resources.getInteger(R.integer.config_showTemperatureWarning)) == 0) { return; } // 获取高温警告阀值,默认:-1 mThresholdTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE, resources.getInteger(R.integer.config_warningTemperature)); if (mThresholdTemp < 0f) { // Get the shutdown temperature, adjust for warning tolerance. // 获取关机温度 float[] throttlingTemps = mHardwarePropertiesManager .getDeviceTemperatures(HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN, HardwarePropertiesManager.TEMPERATURE_SHUTDOWN); if (throttlingTemps == null || throttlingTemps.length == 0 || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) { return; } // 高温警告的温度阀值 mThresholdTemp = throttlingTemps[0] - resources.getInteger(R.integer.config_warningTemperatureTolerance); } if (mThermalService == null) { // Enable push notifications of throttling from vendor thermal // management subsystem via thermalservice, in addition to our // usual polling, to react to temperature jumps more quickly. IBinder b = ServiceManager.getService("thermalservice"); if (b != null) { mThermalService = IThermalService.Stub.asInterface(b); try { mThermalService.registerThermalEventListener( new ThermalEventListener()); } catch (RemoteException e) { // Should never happen. } } } setNextLogTime(); // This initialization method may be called on a configuration change. Only one set of // ongoing callbacks should be occurring, so remove any now. updateTemperatureWarning will // schedule an ongoing callback. mHandler.removeCallbacks(mUpdateTempCallback); // We have passed all of the checks, start checking the temp // 轮询检查温度 updateTemperatureWarning(); }
updateTemperatureWarning()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
protected void updateTemperatureWarning() { // 获取当前温度 float[] temps = mHardwarePropertiesManager .getDeviceTemperatures(HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN, HardwarePropertiesManager.TEMPERATURE_CURRENT); if (temps.length != 0) { float temp = temps[0]; // 记录温度 mRecentTemps[mNumTemps++] = temp; StatusBar statusBar = getComponent(StatusBar.class); if (statusBar != null && !statusBar.isDeviceInVrMode() && temp >= mThresholdTemp) { logAtTemperatureThreshold(temp); // 开启高温警告 mWarnings.showHighTemperatureWarning(); } else { // 关闭高温警告 mWarnings.dismissHighTemperatureWarning(); } } logTemperatureStats(); // 每 30s 检查一次 mHandler.postDelayed(mUpdateTempCallback, TEMPERATURE_INTERVAL); }