Merge "Don't wake users up with low battery sounds." into klp-dev
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 50777fd..6f1c6ba 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5920,6 +5920,16 @@
         public static final String DEVELOPMENT_FORCE_RTL = "debug.force_rtl";
 
         /**
+         * Milliseconds after screen-off after which low battery sounds will be silenced.
+         *
+         * If zero, battery sounds will always play.
+         * Defaults to @integer/def_low_battery_sound_timeout in SettingsProvider.
+         *
+         * @hide
+         */
+        public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index bfb0931..a1d8f22 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -168,4 +168,9 @@
 
     <!-- Default for Settings.Secure.USER_SETUP_COMPLETE -->
     <bool name="def_user_setup_complete">false</bool>
+
+    <!-- Default for Settings.Global.LOW_BATTERY_SOUND_TIMEOUT.
+         0 means no timeout; battery sounds will always play
+         >0 is milliseconds of screen-off time after which battery sounds will not play -->
+    <integer name="def_low_battery_sound_timeout">0</integer>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 120b28f2..09c21f3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -72,7 +72,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 97;
+    private static final int DATABASE_VERSION = 98;
 
     private Context mContext;
     private int mUserHandle;
@@ -1541,6 +1541,24 @@
             upgradeVersion = 97;
         }
 
+        if (upgradeVersion == 97) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
+                            R.integer.def_low_battery_sound_timeout);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 98;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -2253,6 +2271,9 @@
                         CdmaSubscriptionSourceManager.PREFERRED_CDMA_SUBSCRIPTION);
             loadSetting(stmt, Settings.Global.CDMA_SUBSCRIPTION_MODE, type);
 
+            loadIntegerSetting(stmt, Settings.Global.LOW_BATTERY_SOUND_TIMEOUT,
+                    R.integer.def_low_battery_sound_timeout);
+
             // --- New global settings start here
         } finally {
             if (stmt != null) stmt.close();
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a08eb9b..28c2772 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -29,9 +29,11 @@
 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 android.view.View;
 import android.view.WindowManager;
 import android.widget.TextView;
@@ -62,6 +64,8 @@
     AlertDialog mLowBatteryDialog;
     TextView mBatteryLevelTextView;
 
+    private long mScreenOffTime = -1;
+
     public void start() {
 
         mLowBatteryAlertCloseLevel = mContext.getResources().getInteger(
@@ -71,10 +75,14 @@
         mLowBatteryReminderLevels[1] = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
 
+        final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+
         // Register for Intent broadcasts for...
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_POWER_CONNECTED);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        filter.addAction(Intent.ACTION_SCREEN_ON);
         mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
     }
 
@@ -126,19 +134,19 @@
                 int bucket = findBatteryLevelBucket(mBatteryLevel);
 
                 if (DEBUG) {
-                    Log.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
+                    Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
                             + " .. " + mLowBatteryReminderLevels[0]
                             + " .. " + mLowBatteryReminderLevels[1]);
-                    Log.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
-                    Log.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
-                    Log.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
-                    Log.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
-                    Log.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
-                    Log.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
+                    Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
+                    Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
+                    Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
+                    Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
+                    Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
+                    Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
                 }
 
                 if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
-                    Log.d(TAG, "showing invalid charger warning");
+                    Slog.d(TAG, "showing invalid charger warning");
                     showInvalidChargerDialog();
                     return;
                 } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
@@ -163,21 +171,25 @@
                 } else if (mBatteryLevelTextView != null) {
                     showLowBatteryWarning();
                 }
+            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                mScreenOffTime = SystemClock.elapsedRealtime();
+            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
+                mScreenOffTime = -1;
             } else {
-                Log.w(TAG, "unknown intent: " + intent);
+                Slog.w(TAG, "unknown intent: " + intent);
             }
         }
     };
 
     void dismissLowBatteryWarning() {
         if (mLowBatteryDialog != null) {
-            Log.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
+            Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
             mLowBatteryDialog.dismiss();
         }
     }
 
     void showLowBatteryWarning() {
-        Log.i(TAG,
+        Slog.i(TAG,
                 ((mBatteryLevelTextView == null) ? "showing" : "updating")
                 + " low battery warning: level=" + mBatteryLevel
                 + " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
@@ -233,11 +245,23 @@
     }
 
     void playLowBatterySound() {
-        if (DEBUG) {
-            Log.i(TAG, "playing low battery sound. WOMP-WOMP!");
+        final ContentResolver cr = mContext.getContentResolver();
+
+        final int silenceAfter = Settings.Global.getInt(cr,
+                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
+        final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
+        if (silenceAfter > 0
+                && mScreenOffTime > 0
+                && offTime > silenceAfter) {
+            Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
+                    + "ms): not waking up the user with low battery sound");
+            return;
         }
 
-        final ContentResolver cr = mContext.getContentResolver();
+        if (DEBUG) {
+            Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
+        }
+
         if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
             final String soundPath = Settings.Global.getString(cr,
                     Settings.Global.LOW_BATTERY_SOUND);
@@ -261,7 +285,7 @@
     }
 
     void showInvalidChargerDialog() {
-        Log.d(TAG, "showing invalid charger dialog");
+        Slog.d(TAG, "showing invalid charger dialog");
 
         dismissLowBatteryWarning();
 
@@ -301,6 +325,17 @@
         pw.println(Integer.toString(mPlugType));
         pw.print("mInvalidCharger=");
         pw.println(Integer.toString(mInvalidCharger));
+        pw.print("mScreenOffTime=");
+        pw.print(mScreenOffTime);
+        if (mScreenOffTime >= 0) {
+            pw.print(" (");
+            pw.print(SystemClock.elapsedRealtime() - mScreenOffTime);
+            pw.print(" ago)");
+        }
+        pw.println();
+        pw.print("soundTimeout=");
+        pw.println(Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
         pw.print("bucket: ");
         pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
     }