From 8d4e6cb06005a2ce994360340a6191f0690db8f4 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Sun, 14 Sep 2014 11:10:22 -0400 Subject: [PATCH] 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 --- core/java/android/os/IPowerManager.aidl | 1 + core/java/android/os/PowerManager.java | 17 ++++ .../power/PowerNotificationWarnings.java | 12 +-- .../server/power/PowerManagerService.java | 82 ++++++++++++------- .../bridge/android/BridgePowerManager.java | 5 ++ 5 files changed, 81 insertions(+), 36 deletions(-) diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 658180b21342f..182dbee0a85c6 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -42,6 +42,7 @@ interface IPowerManager 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 18b208255cb29..3b6ce53fd6200 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -795,6 +795,23 @@ public final class PowerManager { } } + /** + * 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 4c7f8ec8f9cfb..f184ad2653cb9 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.media.AudioAttributes; 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 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { 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 class PowerNotificationWarnings implements PowerUI.WarningsUI { 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 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { 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 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { } else if (action.equals(ACTION_STOP_SAVER)) { dismissSaverNotification(); dismissLowBatteryNotification(); - setSaverSetting(false); + setSaverMode(false); } } } @@ -395,7 +397,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { 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 eeebe044b8d48..c79a6d64121e2 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 @@ public final class PowerManagerService extends SystemService 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 @@ public final class PowerManagerService extends SystemService 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 @@ public final class PowerManagerService extends SystemService 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 @@ public final class PowerManagerService extends SystemService } } + 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 @@ public final class PowerManagerService extends SystemService 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 @@ public final class PowerManagerService extends SystemService } } + @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 17d990bfe840c..22265a30e9acb 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 @@ -37,6 +37,11 @@ public class BridgePowerManager implements IPowerManager { return false; } + @Override + public boolean setPowerSaveMode(boolean mode) throws RemoteException { + return false; + } + @Override public IBinder asBinder() { // pass for now.