Saver: PowerManager call to set low power mode.
- Add an explicit power manager call to set the low power mode state,
instead of trying manage everything around a single setting.
- When low-power mode is triggered by falling below the configured
threshold, it does not update the setting.
- The "is-enabled" api returns setting || below configured trigger.
- Move the snooze management into the new api call.
- Callers (sysui + settings) updated to use the api instead of the
setting.
- Handles the case where the level does an unpowered leap out of the
low battery level. (Possible if powered in-between while the device
is off)
Bug:17460535
Change-Id: Ic030504c9cad9868a7137abbe837b170da37852b
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 658180b..182dbee 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -42,6 +42,7 @@
void nap(long time);
boolean isInteractive();
boolean isPowerSaveMode();
+ boolean setPowerSaveMode(boolean mode);
void reboot(boolean confirm, String reason, boolean wait);
void shutdown(boolean confirm, boolean wait);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 18b2082..3b6ce53 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -796,6 +796,23 @@
}
/**
+ * Set the current power save mode.
+ *
+ * @return True if the set was allowed.
+ *
+ * @see #isPowerSaveMode()
+ *
+ * @hide
+ */
+ public boolean setPowerSaveMode(boolean mode) {
+ try {
+ return mService.setPowerSaveMode(mode);
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
* Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes.
* This broadcast is only sent to registered receivers.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 4c7f8ec..f184ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -31,6 +31,7 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -72,6 +73,7 @@
private final Context mContext;
private final NotificationManager mNoMan;
+ private final PowerManager mPowerMan;
private final Handler mHandler = new Handler();
private final Receiver mReceiver = new Receiver();
private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
@@ -93,6 +95,7 @@
public PowerNotificationWarnings(Context context, PhoneStatusBar phoneStatusBar) {
mContext = context;
mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mReceiver.init();
}
@@ -356,9 +359,8 @@
mSaverConfirmation = d;
}
- private void setSaverSetting(boolean mode) {
- final int val = mode ? 1 : 0;
- Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.LOW_POWER_MODE, val);
+ private void setSaverMode(boolean mode) {
+ mPowerMan.setPowerSaveMode(mode);
}
private final class Receiver extends BroadcastReceiver {
@@ -384,7 +386,7 @@
} else if (action.equals(ACTION_STOP_SAVER)) {
dismissSaverNotification();
dismissLowBatteryNotification();
- setSaverSetting(false);
+ setSaverMode(false);
}
}
}
@@ -395,7 +397,7 @@
AsyncTask.execute(new Runnable() {
@Override
public void run() {
- setSaverSetting(true);
+ setSaverMode(true);
}
});
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index eeebe04..c79a6d6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -416,9 +416,9 @@
private boolean mLowPowerModeSetting;
// Current state of whether the settings are allowing auto low power mode.
- private boolean mAutoLowPowerModeEnabled;
+ private boolean mAutoLowPowerModeConfigured;
- // The user turned off low power mode below the trigger level
+ // The user turned off low power mode below the trigger level
private boolean mAutoLowPowerModeSnoozing;
// True if the battery level is currently considered low.
@@ -659,26 +659,12 @@
final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE, 0) != 0;
- final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
+ final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) != 0;
if (lowPowerModeEnabled != mLowPowerModeSetting
- || autoLowPowerModeEnabled != mAutoLowPowerModeEnabled) {
- if (lowPowerModeEnabled != mLowPowerModeSetting) {
- if (!mAutoLowPowerModeSnoozing && !lowPowerModeEnabled && !mIsPowered
- && mAutoLowPowerModeEnabled) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateSettingsLocked: snoozing low power mode");
- }
- mAutoLowPowerModeSnoozing = true;
- } else if (mAutoLowPowerModeSnoozing && lowPowerModeEnabled) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateSettingsLocked: no longer snoozing low power mode");
- }
- mAutoLowPowerModeSnoozing = true;
- }
- }
+ || autoLowPowerModeConfigured != mAutoLowPowerModeConfigured) {
mLowPowerModeSetting = lowPowerModeEnabled;
- mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
+ mAutoLowPowerModeConfigured = autoLowPowerModeConfigured;
updateLowPowerModeLocked();
}
@@ -694,21 +680,14 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, 0);
mLowPowerModeSetting = false;
- } else if (!mIsPowered && mAutoLowPowerModeEnabled && !mAutoLowPowerModeSnoozing
- && mBatteryLevelLow && !mLowPowerModeSetting) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateLowPowerModeLocked: trigger level reached, turning setting on");
- }
- // Turn setting on if trigger level is enabled, and we're now below it
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.LOW_POWER_MODE, 1);
- mLowPowerModeSetting = true;
}
- final boolean lowPowerModeEnabled = mLowPowerModeSetting;
+ final boolean autoLowPowerModeEnabled = !mIsPowered && mAutoLowPowerModeConfigured
+ && !mAutoLowPowerModeSnoozing && mBatteryLevelLow;
+ final boolean lowPowerModeEnabled = mLowPowerModeSetting || autoLowPowerModeEnabled;
+
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
- mLowPowerModeEnabled = lowPowerModeEnabled;
BackgroundThread.getHandler().post(new Runnable() {
@Override
public void run() {
@@ -2083,6 +2062,35 @@
}
}
+ private boolean setLowPowerModeInternal(boolean mode) {
+ synchronized (mLock) {
+ if (DEBUG) Slog.d(TAG, "setLowPowerModeInternal " + mode + " mIsPowered=" + mIsPowered);
+ if (mIsPowered) {
+ return false;
+ }
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.LOW_POWER_MODE, mode ? 1 : 0);
+ mLowPowerModeSetting = mode;
+
+ if (mAutoLowPowerModeConfigured && mBatteryLevelLow) {
+ if (mode && mAutoLowPowerModeSnoozing) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "setLowPowerModeInternal: clearing low power mode snooze");
+ }
+ mAutoLowPowerModeSnoozing = false;
+ } else if (!mode && !mAutoLowPowerModeSnoozing) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "setLowPowerModeInternal: snoozing low power mode");
+ }
+ mAutoLowPowerModeSnoozing = true;
+ }
+ }
+
+ updateLowPowerModeLocked();
+ return true;
+ }
+ }
+
private void handleBatteryStateChangedLocked() {
mDirty |= DIRTY_BATTERY_STATE;
updatePowerStateLocked();
@@ -2347,7 +2355,7 @@
pw.println(" mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
pw.println(" mDozeAfterScreenOffConfig=" + mDozeAfterScreenOffConfig);
pw.println(" mLowPowerModeSetting=" + mLowPowerModeSetting);
- pw.println(" mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
+ pw.println(" mAutoLowPowerModeConfigured=" + mAutoLowPowerModeConfigured);
pw.println(" mAutoLowPowerModeSnoozing=" + mAutoLowPowerModeSnoozing);
pw.println(" mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
pw.println(" mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
@@ -2963,6 +2971,18 @@
}
}
+ @Override // Binder call
+ public boolean setPowerSaveMode(boolean mode) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return setLowPowerModeInternal(mode);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
/**
* Reboots the device.
*
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 17d990b..22265a3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -38,6 +38,11 @@
}
@Override
+ public boolean setPowerSaveMode(boolean mode) throws RemoteException {
+ return false;
+ }
+
+ @Override
public IBinder asBinder() {
// pass for now.
return null;