OSDN Git Service

Battery saver: new policy changes + SystemUI tweaks.
authorJohn Spurlock <jspurlock@google.com>
Sat, 2 Aug 2014 21:12:43 +0000 (17:12 -0400)
committerJohn Spurlock <jspurlock@google.com>
Sat, 2 Aug 2014 21:12:43 +0000 (17:12 -0400)
 - Service policy changes: allow the user to turn off (snooze)
   saver mode below the auto-trigger level.  Plugging in the
   device always exits saver mode.
 - Default trigger level is now 0 (never) instead of 15.
 - SystemUI now also listens to a new POWER_SAVE_MODE_CHANGING,
   since waiting for _CHANGED can take seconds.
 - Move shared feature description text into the framework so it
   can be shared.
 - Tweak dialog title + action strings.
 - Remove trigger-level from SystemUI, it no longer needs it.
 - Add the ability to turn off saver mode directly from the
   notification.
 - Migrate saver confirmation dialog to common system UI dialog
   helper, and add a few convenience methods.
 - Fix bug where the status bar area would be orange over the keyguard
   in SHADE_LOCKED mode.

Bug:16214395
Change-Id: I3d1ded1eec9e63e7d97469486f6a320e1bebbccd

12 files changed:
core/java/android/os/PowerManager.java
core/res/AndroidManifest.xml
core/res/res/values/strings.xml
core/res/res/values/symbols.xml
packages/SystemUI/res/values/strings.xml
packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
packages/SystemUI/src/com/android/systemui/power/PowerUI.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
services/core/java/com/android/server/power/PowerManagerService.java

index dda6d27..6334f76 100644 (file)
@@ -716,6 +716,19 @@ public final class PowerManager {
             = "android.os.action.POWER_SAVE_MODE_CHANGED";
 
     /**
+     * Intent that is broadcast when the state of {@link #isPowerSaveMode()} is about to change.
+     * This broadcast is only sent to registered receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_POWER_SAVE_MODE_CHANGING
+            = "android.os.action.POWER_SAVE_MODE_CHANGING";
+
+    /** @hide */
+    public static final String EXTRA_POWER_SAVE_MODE = "mode";
+
+    /**
      * A wake lock is a mechanism to indicate that your application needs
      * to have the device stay on.
      * <p>
index d7aea39..2a96580 100644 (file)
@@ -75,6 +75,7 @@
     <protected-broadcast android:name="android.intent.action.USER_SWITCHED" />
 
     <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
+    <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
 
     <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" />
     <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" />
index 195851f..8e626e3 100644 (file)
     <string name="description_krtv_12">12세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
     <string name="description_krtv_15">15세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
     <string name="description_krtv_19">19세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 청소년이 시청할 수 없는 등급을 말한다.</string>
+
+     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description -->
+    <string name="battery_saver_description">To help improve battery life, battery saver will reduce your device’s performance and restrict background data.  Email, messaging, and other apps that rely on syncing may not update unless you open them.\n\nBattery saver turns off automatically when your device is charging.</string>
 </resources>
index ccd7005..5c8926e 100644 (file)
   <java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
   <java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
   <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
+  <java-symbol type="string" name="battery_saver_description" />
 
   <java-symbol type="string" name="item_is_selected" />
   <java-symbol type="string" name="day_of_week_label_typeface" />
index 085d2f9..296cdad 100644 (file)
     <string name="battery_low_why">Settings</string>
 
     <!-- Battery saver confirmation dialog title [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_confirmation_title">Start battery saver?</string>
+    <string name="battery_saver_confirmation_title">Turn on battery saver?</string>
 
     <!-- Battery saver confirmation dialog ok text [CHAR LIMIT=40]-->
-    <string name="battery_saver_confirmation_ok">Start</string>
+    <string name="battery_saver_confirmation_ok">Turn on</string>
 
     <!-- Battery saver notification action [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_start_action">Start battery saver</string>
-
-    <!-- Battery saver confirmation dialog text [CHAR LIMIT=NONE]-->
-    <string name="battery_saver_confirmation_text">To help improve battery life, Battery saver will reduce your device’s performance.\n\nBattery saver will be disabled when your device is plugged in.</string>
+    <string name="battery_saver_start_action">Turn on battery saver</string>
 
     <!-- Name of the button that links to the Settings app. [CHAR LIMIT=NONE] -->
     <string name="status_bar_settings_settings_button">Settings</string>
     <string name="battery_saver_notification_title">Battery saver is on</string>
 
     <!-- Battery saver notification text. [CHAR LIMIT=60] -->
-    <string name="battery_saver_notification_text">Device performance is reduced.</string>
+    <string name="battery_saver_notification_text">Reduces performance and background data</string>
 
     <!-- Battery saver notification action text. [CHAR LIMIT=60] -->
-    <string name="battery_saver_notification_action_text">Open battery saver settings</string>
+    <string name="battery_saver_notification_action_text">Turn off battery saver</string>
 
     <!-- Battery level for expanded quick settings [CHAR LIMIT=2] -->
     <string name="battery_level_template"><xliff:g id="level" example="45">%d</xliff:g>%%</string>
index 2943494..79fadbd 100644 (file)
@@ -48,7 +48,6 @@ public class PowerDialogWarnings implements PowerUI.WarningsUI {
     private int mBucket;
     private long mScreenOffTime;
     private boolean mSaver;
-    private int mSaverTriggerLevel;
 
     private AlertDialog mInvalidChargerDialog;
     private AlertDialog mLowBatteryDialog;
@@ -222,9 +221,4 @@ public class PowerDialogWarnings implements PowerUI.WarningsUI {
     public void showSaverMode(boolean mode) {
         mSaver = mode;
     }
-
-    @Override
-    public void setSaverTrigger(int level) {
-        mSaverTriggerLevel = level;
-    }
 }
index 186b570..9ffe0ef 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.systemui.power;
 
-import android.app.AlertDialog;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -25,9 +24,10 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioManager;
+import android.media.AudioAttributes;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
@@ -35,11 +35,10 @@ import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
-import android.view.ContextThemeWrapper;
 import android.view.View;
-import android.view.WindowManager;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 import java.io.PrintWriter;
 
@@ -66,9 +65,14 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
     private static final String ACTION_SHOW_FALLBACK_CHARGER = "PNW.chargerFallback";
     private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
     private static final String ACTION_START_SAVER = "PNW.startSaver";
+    private static final String ACTION_STOP_SAVER = "PNW.stopSaver";
+
+    private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+            .build();
 
     private final Context mContext;
-    private final Context mLightContext;
     private final NotificationManager mNoMan;
     private final Handler mHandler = new Handler();
     private final PowerDialogWarnings mFallbackDialogs;
@@ -84,15 +88,13 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
     private long mBucketDroppedNegativeTimeMs;
 
     private boolean mSaver;
-    private int mSaverTriggerLevel;
     private boolean mWarning;
     private boolean mPlaySound;
     private boolean mInvalidCharger;
+    private SystemUIDialog mSaverConfirmation;
 
     public PowerNotificationWarnings(Context context) {
         mContext = context;
-        mLightContext = new ContextThemeWrapper(mContext,
-                android.R.style.Theme_DeviceDefault_Light);
         mNoMan = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
         mFallbackDialogs = new PowerDialogWarnings(context);
         mReceiver.init();
@@ -105,6 +107,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
         pw.print("mPlaySound="); pw.println(mPlaySound);
         pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
         pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
+        pw.print("mSaverConfirmation="); pw.println(mSaverConfirmation != null ? "not null" : null);
     }
 
     @Override
@@ -123,12 +126,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
     @Override
     public void showSaverMode(boolean mode) {
         mSaver = mode;
-        updateNotification();
-    }
-
-    @Override
-    public void setSaverTrigger(int level) {
-        mSaverTriggerLevel = level;
+        if (mSaver && mSaverConfirmation != null) {
+            mSaverConfirmation.dismiss();
+        }
         updateNotification();
     }
 
@@ -180,6 +180,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
                 .setContentTitle(mContext.getString(R.string.battery_low_title))
                 .setContentText(mContext.getString(textRes, mBatteryLevel))
                 .setOngoing(true)
+                .setOnlyAlertOnce(true)
                 .setPriority(Notification.PRIORITY_MAX)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setVisibility(Notification.VISIBILITY_PUBLIC)
@@ -187,10 +188,12 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
         if (hasBatterySettings()) {
             nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
         }
-        if (!mSaver && mSaverTriggerLevel <= 0) {
+        if (!mSaver) {
             nb.addAction(R.drawable.ic_power_saver,
                     mContext.getString(R.string.battery_saver_start_action),
                     pendingBroadcast(ACTION_START_SAVER));
+        } else {
+            addStopSaverAction(nb);
         }
         if (mPlaySound) {
             attachLowBatterySound(nb);
@@ -208,19 +211,28 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
                 .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
                 .setContentText(mContext.getString(R.string.battery_saver_notification_text))
                 .setOngoing(true)
-                .setWhen(0)
                 .setShowWhen(false)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setVisibility(Notification.VISIBILITY_PUBLIC);
+        addStopSaverAction(nb);
         if (hasSaverSettings()) {
-            nb.addAction(0,
-                    mContext.getString(R.string.battery_saver_notification_action_text),
-                    pendingActivity(mOpenSaverSettings));
             nb.setContentIntent(pendingActivity(mOpenSaverSettings));
         }
         mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT);
     }
 
+    private void addStopSaverAction(Notification.Builder nb) {
+        nb.addAction(R.drawable.ic_power_saver,
+                mContext.getString(R.string.battery_saver_notification_action_text),
+                pendingBroadcast(ACTION_STOP_SAVER));
+    }
+
+    private void dismissSaverNotification() {
+        if (mSaver) Slog.i(TAG, "dismissing saver notification");
+        mSaver = false;
+        updateNotification();
+    }
+
     private PendingIntent pendingActivity(Intent intent) {
         return PendingIntent.getActivityAsUser(mContext,
                 0, intent, 0, null, UserHandle.CURRENT);
@@ -307,8 +319,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
             if (soundPath != null) {
                 final Uri soundUri = Uri.parse("file://" + soundPath);
                 if (soundUri != null) {
-                    b.setSound(soundUri, AudioManager.STREAM_SYSTEM);
-                    Slog.d(TAG, "playing sound " + soundUri);
+                    b.setSound(soundUri, AUDIO_ATTRIBUTES);
+                    if (DEBUG) Slog.d(TAG, "playing sound " + soundUri);
                 }
             }
         }
@@ -333,17 +345,21 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
     }
 
     private void showStartSaverConfirmation() {
-        final AlertDialog d = new AlertDialog.Builder(mLightContext)
-                .setTitle(R.string.battery_saver_confirmation_title)
-                .setMessage(R.string.battery_saver_confirmation_text)
-                .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode)
-                .create();
-
-        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
-        d.getWindow().getAttributes().privateFlags |=
-                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        if (mSaverConfirmation != null) return;
+        final SystemUIDialog d = new SystemUIDialog(mContext);
+        d.setTitle(R.string.battery_saver_confirmation_title);
+        d.setMessage(com.android.internal.R.string.battery_saver_description);
+        d.setNegativeButton(android.R.string.cancel, null);
+        d.setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverMode);
+        d.setShowForAllUsers(true);
+        d.setOnDismissListener(new OnDismissListener() {
+            @Override
+            public void onDismiss(DialogInterface dialog) {
+                mSaverConfirmation = null;
+            }
+        });
         d.show();
+        mSaverConfirmation = d;
     }
 
     private void setSaverSetting(boolean mode) {
@@ -359,6 +375,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
             filter.addAction(ACTION_SHOW_FALLBACK_CHARGER);
             filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
             filter.addAction(ACTION_START_SAVER);
+            filter.addAction(ACTION_STOP_SAVER);
             mContext.registerReceiver(this, filter, null, mHandler);
         }
 
@@ -378,6 +395,10 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
             } else if (action.equals(ACTION_START_SAVER)) {
                 dismissLowBatteryNotification();
                 showStartSaverConfirmation();
+            } else if (action.equals(ACTION_STOP_SAVER)) {
+                dismissSaverNotification();
+                dismissLowBatteryNotification();
+                setSaverSetting(false);
             }
         }
     }
index 1bb7edb..ccef8eb 100644 (file)
@@ -22,13 +22,13 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
-import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.systemui.SystemUI;
@@ -39,11 +39,9 @@ import java.util.Arrays;
 
 public class PowerUI extends SystemUI {
     static final String TAG = "PowerUI";
-    static final boolean DEBUG = false;
-
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Handler mHandler = new Handler();
-    private final SettingsObserver mObserver = new SettingsObserver(mHandler);
     private final Receiver mReceiver = new Receiver();
 
     private PowerManager mPowerManager;
@@ -75,17 +73,12 @@ public class PowerUI extends SystemUI {
                 false, obs, UserHandle.USER_ALL);
         updateBatteryWarningLevels();
         mReceiver.init();
-        mObserver.init();
     }
 
     private void setSaverMode(boolean mode) {
         mWarnings.showSaverMode(mode);
     }
 
-    private void setSaverTrigger(int level) {
-        mWarnings.setSaverTrigger(level);
-    }
-
     void updateBatteryWarningLevels() {
         int critLevel = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -143,6 +136,7 @@ public class PowerUI extends SystemUI {
             filter.addAction(Intent.ACTION_BATTERY_CHANGED);
             filter.addAction(Intent.ACTION_SCREEN_OFF);
             filter.addAction(Intent.ACTION_SCREEN_ON);
+            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
             filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
             mContext.registerReceiver(this, filter, null, mHandler);
             updateSaverMode();
@@ -214,6 +208,8 @@ public class PowerUI extends SystemUI {
                 mScreenOffTime = -1;
             } 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);
             }
@@ -251,7 +247,6 @@ public class PowerUI extends SystemUI {
 
     public interface WarningsUI {
         void update(int batteryLevel, int bucket, long screenOffTime);
-        void setSaverTrigger(int level);
         void showSaverMode(boolean mode);
         void dismissLowBatteryWarning();
         void showLowBatteryWarning(boolean playSound);
@@ -261,29 +256,5 @@ public class PowerUI extends SystemUI {
         boolean isInvalidChargerWarningShowing();
         void dump(PrintWriter pw);
     }
-
-    private final class SettingsObserver extends ContentObserver {
-        private final Uri LOW_POWER_MODE_TRIGGER_LEVEL_URI =
-                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL);
-
-        public SettingsObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void init() {
-            onChange(true, LOW_POWER_MODE_TRIGGER_LEVEL_URI);
-            final ContentResolver cr = mContext.getContentResolver();
-            cr.registerContentObserver(LOW_POWER_MODE_TRIGGER_LEVEL_URI, false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (LOW_POWER_MODE_TRIGGER_LEVEL_URI.equals(uri)) {
-                final int level = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
-                setSaverTrigger(level);
-            }
-        }
-    }
 }
 
index 06c7be2..2be3d5a 100644 (file)
@@ -2436,7 +2436,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         final boolean powerSave = mBatteryController.isPowerSave();
         final boolean anim = (mScreenOn == null || mScreenOn) && windowState != WINDOW_STATE_HIDDEN
                 && !powerSave;
-        if (powerSave && getBarState() != StatusBarState.KEYGUARD) {
+        if (powerSave && getBarState() == StatusBarState.SHADE) {
             mode = MODE_WARNING;
         }
         transitions.transitionTo(mode, anim);
index 86a6622..d701b3c 100644 (file)
@@ -27,8 +27,12 @@ import android.view.WindowManager;
  */
 public class SystemUIDialog extends AlertDialog {
 
+    private final Context mContext;
+
     public SystemUIDialog(Context context) {
         super(context, R.style.Theme_SystemUI_Dialog);
+        mContext = context;
+
         getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@@ -36,4 +40,26 @@ public class SystemUIDialog extends AlertDialog {
         attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
     }
+
+    public void setShowForAllUsers(boolean show) {
+        if (show) {
+            getWindow().getAttributes().privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        } else {
+            getWindow().getAttributes().privateFlags &=
+                    ~WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        }
+    }
+
+    public void setMessage(int resId) {
+        setMessage(mContext.getString(resId));
+    }
+
+    public void setPositiveButton(int resId, OnClickListener onClick) {
+        setButton(BUTTON_POSITIVE, mContext.getString(resId), onClick);
+    }
+
+    public void setNegativeButton(int resId, OnClickListener onClick) {
+        setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
+    }
 }
index 1e65543..d1b69ab 100644 (file)
@@ -47,6 +47,7 @@ public class BatteryController extends BroadcastReceiver {
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+        filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
         context.registerReceiver(this, filter);
 
         updatePowerSave();
@@ -86,6 +87,8 @@ public class BatteryController extends BroadcastReceiver {
             fireBatteryLevelChanged();
         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
             updatePowerSave();
+        } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
+            setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
         }
     }
 
@@ -94,7 +97,10 @@ public class BatteryController extends BroadcastReceiver {
     }
 
     private void updatePowerSave() {
-        final boolean powerSave = mPowerManager.isPowerSaveMode();
+        setPowerSave(mPowerManager.isPowerSaveMode());
+    }
+
+    private void setPowerSave(boolean powerSave) {
         if (powerSave == mPowerSave) return;
         mPowerSave = powerSave;
         if (DEBUG) Log.d(TAG, "Power save is " + (mPowerSave ? "on" : "off"));
index 8c52fad..d1182e9 100644 (file)
@@ -422,6 +422,9 @@ public final class PowerManagerService extends com.android.server.SystemService
     // Current state of whether the settings are allowing auto low power mode.
     private boolean mAutoLowPowerModeEnabled;
 
+   // The user turned off low power mode below the trigger level
+    private boolean mAutoLowPowerModeSnoozing;
+
     // True if the battery level is currently considered low.
     private boolean mBatteryLevelLow;
 
@@ -650,9 +653,23 @@ public final class PowerManagerService extends com.android.server.SystemService
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
         final boolean autoLowPowerModeEnabled = Settings.Global.getInt(resolver,
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15) != 0;
+                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;
+                }
+            }
             mLowPowerModeSetting = lowPowerModeEnabled;
             mAutoLowPowerModeEnabled = autoLowPowerModeEnabled;
             updateLowPowerModeLocked();
@@ -662,8 +679,25 @@ public final class PowerManagerService extends com.android.server.SystemService
     }
 
     void updateLowPowerModeLocked() {
-        final boolean lowPowerModeEnabled = !mIsPowered
-                && (mLowPowerModeSetting || (mAutoLowPowerModeEnabled && mBatteryLevelLow));
+        if (mIsPowered && mLowPowerModeSetting) {
+            if (DEBUG_SPEW) {
+                Slog.d(TAG, "updateLowPowerModeLocked: powered, turning setting off");
+            }
+            // Turn setting off if powered
+            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;
         if (mLowPowerModeEnabled != lowPowerModeEnabled) {
             mLowPowerModeEnabled = lowPowerModeEnabled;
             powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0);
@@ -672,6 +706,10 @@ public final class PowerManagerService extends com.android.server.SystemService
             BackgroundThread.getHandler().post(new Runnable() {
                 @Override
                 public void run() {
+                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
+                            .putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled)
+                            .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    mContext.sendBroadcast(intent);
                     ArrayList<PowerManagerInternal.LowPowerModeListener> listeners;
                     synchronized (mLock) {
                         listeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(
@@ -680,7 +718,7 @@ public final class PowerManagerService extends com.android.server.SystemService
                     for (int i=0; i<listeners.size(); i++) {
                         listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);
                     }
-                    Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+                    intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                     mContext.sendBroadcast(intent);
                 }
@@ -1218,6 +1256,12 @@ public final class PowerManagerService extends com.android.server.SystemService
             }
 
             if (wasPowered != mIsPowered || oldLevelLow != mBatteryLevelLow) {
+                if (oldLevelLow != mBatteryLevelLow && !mBatteryLevelLow) {
+                    if (DEBUG_SPEW) {
+                        Slog.d(TAG, "updateIsPoweredLocked: resetting low power snooze");
+                    }
+                    mAutoLowPowerModeSnoozing = false;
+                }
                 updateLowPowerModeLocked();
             }
         }
@@ -2265,6 +2309,7 @@ public final class PowerManagerService extends com.android.server.SystemService
             pw.println("  mDreamsActivateOnDockSetting=" + mDreamsActivateOnDockSetting);
             pw.println("  mLowPowerModeSetting=" + mLowPowerModeSetting);
             pw.println("  mAutoLowPowerModeEnabled=" + mAutoLowPowerModeEnabled);
+            pw.println("  mAutoLowPowerModeSnoozing=" + mAutoLowPowerModeSnoozing);
             pw.println("  mMinimumScreenOffTimeoutConfig=" + mMinimumScreenOffTimeoutConfig);
             pw.println("  mMaximumScreenDimDurationConfig=" + mMaximumScreenDimDurationConfig);
             pw.println("  mMaximumScreenDimRatioConfig=" + mMaximumScreenDimRatioConfig);