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
This commit is contained in:
John Spurlock
2014-09-14 11:10:22 -04:00
parent c68f27625b
commit 8d4e6cb060
5 changed files with 81 additions and 36 deletions

View File

@@ -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);

View File

@@ -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.

View File

@@ -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);
}
});
}

View File

@@ -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.
*

View File

@@ -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.