Move battery saver notification to QS
Remove the battery saver notification and instead create a detail
panel within QS that allows it to be turned on and off.
Change-Id: I54654d26183586fa171fda04877a840701f8ef33
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 40eb375..fd85953 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -27,7 +27,6 @@
*/
public class MetricsLogger implements MetricsConstants {
// Temporary constants go here, to await migration to MetricsConstants.
- public static final int QS_LOCK_TILE = 257;
public static final int QS_USER_TILE = 258;
public static final int QS_BATTERY_TILE = 259;
public static final int NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 260;
@@ -62,6 +61,8 @@
* credentials UI.
*/
public static final int PROFILE_CHALLENGE = 271;
+ public static final int ACTION_WINDOW_DOCK_SWIPE = 272;
+ public static final int QS_BATTERY_DETAIL = 273;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f7e25db..ac19cf5 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -726,4 +726,41 @@
<!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
<string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
+ <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g>
+ - approx. <xliff:g id="time">%2$s</xliff:g> left</string>
+
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging -->
+ <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> -
+ <xliff:g id="state">%2$s</xliff:g></string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
+ <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> -
+ <xliff:g id="time">%2$s</xliff:g> until full</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
+ <string name="power_charging_duration_ac"><xliff:g id="level">%1$s</xliff:g> -
+ <xliff:g id="time">%2$s</xliff:g> until full on AC</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
+ <string name="power_charging_duration_usb"><xliff:g id="level">%1$s</xliff:g> -
+ <xliff:g id="time">%2$s</xliff:g> until full over USB</string>
+ <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration -->
+ <string name="power_charging_duration_wireless"><xliff:g id="level">%1$s</xliff:g> -
+ <xliff:g id="time">%2$s</xliff:g> until full from wireless</string>
+
+ <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="battery_info_status_unknown">Unknown</string>
+ <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging from an unknown source. -->
+ <string name="battery_info_status_charging">Charging</string>
+ <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging on AC. -->
+ <string name="battery_info_status_charging_ac">Charging on AC</string>
+ <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging over USB. -->
+ <string name="battery_info_status_charging_usb">Charging over USB</string>
+ <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging over a wireless connection. -->
+ <string name="battery_info_status_charging_wireless">Charging wirelessly</string>
+ <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="battery_info_status_discharging">Not charging</string>
+ <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="battery_info_status_not_charging">Not charging</string>
+ <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed -->
+ <string name="battery_info_status_full">Full</string>
+
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
new file mode 100644
index 0000000..d81bdeb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settingslib;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.os.BatteryStats;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.text.format.Formatter;
+import com.android.internal.os.BatteryStatsHelper;
+
+public class BatteryInfo {
+
+ public String mChargeLabelString;
+ public int mBatteryLevel;
+ public boolean mDischarging = true;
+ public long remainingTimeUs = 0;
+
+ public interface Callback {
+ void onBatteryInfoLoaded(BatteryInfo info);
+ }
+
+ public static void getBatteryInfo(final Context context, final Callback callback) {
+ new AsyncTask<Void, Void, BatteryStats>() {
+ @Override
+ protected BatteryStats doInBackground(Void... params) {
+ BatteryStatsHelper statsHelper = new BatteryStatsHelper(context, true);
+ statsHelper.create((Bundle) null);
+ return statsHelper.getStats();
+ }
+
+ @Override
+ protected void onPostExecute(BatteryStats batteryStats) {
+ final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
+ Intent batteryBroadcast = context.registerReceiver(null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context,
+ batteryBroadcast, batteryStats, elapsedRealtimeUs);
+ callback.onBatteryInfoLoaded(batteryInfo);
+ }
+ }.execute();
+ }
+
+ public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
+ BatteryStats stats, long elapsedRealtimeUs) {
+ BatteryInfo info = new BatteryInfo();
+ info.mBatteryLevel = Utils.getBatteryLevel(batteryBroadcast);
+ String batteryPercentString = Utils.formatPercentage(info.mBatteryLevel);
+ if (batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) == 0) {
+ final long drainTime = stats.computeBatteryTimeRemaining(elapsedRealtimeUs);
+ if (drainTime > 0) {
+ info.remainingTimeUs = drainTime;
+ String timeString = Formatter.formatShortElapsedTime(context,
+ drainTime / 1000);
+ info.mChargeLabelString = context.getResources().getString(
+ R.string.power_discharging_duration, batteryPercentString, timeString);
+ } else {
+ info.mChargeLabelString = batteryPercentString;
+ }
+ } else {
+ final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
+ final String statusLabel = Utils.getBatteryStatus(
+ context.getResources(), batteryBroadcast);
+ final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
+ info.mDischarging = false;
+ info.remainingTimeUs = chargeTime;
+ String timeString = Formatter.formatShortElapsedTime(context,
+ chargeTime / 1000);
+ int plugType = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ int resId;
+ if (plugType == BatteryManager.BATTERY_PLUGGED_AC) {
+ resId = R.string.power_charging_duration_ac;
+ } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) {
+ resId = R.string.power_charging_duration_usb;
+ } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
+ resId = R.string.power_charging_duration_wireless;
+ } else {
+ resId = R.string.power_charging_duration;
+ }
+ info.mChargeLabelString = context.getResources().getString(
+ resId, batteryPercentString, timeString);
+ } else {
+ info.mChargeLabelString = context.getResources().getString(
+ R.string.power_charging, batteryPercentString, statusLabel);
+ }
+ }
+ return info;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index 621a09cd..72df96d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -1,17 +1,21 @@
package com.android.settingslib;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.UserInfo;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
+import android.os.BatteryManager;
import android.os.UserManager;
-
import com.android.internal.util.UserIcons;
import com.android.settingslib.drawable.CircleFramedDrawable;
-public final class Utils {
+import java.text.NumberFormat;
+
+public class Utils {
/**
* Return string resource that best describes combination of tethering
@@ -81,4 +85,57 @@
return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap(
UserIcons.getDefaultUserIcon(user.id, /* light= */ false)));
}
+
+ /** Formats the ratio of amount/total as a percentage. */
+ public static String formatPercentage(long amount, long total) {
+ return formatPercentage(((double) amount) / total);
+ }
+
+ /** Formats an integer from 0..100 as a percentage. */
+ public static String formatPercentage(int percentage) {
+ return formatPercentage(((double) percentage) / 100.0);
+ }
+
+ /** Formats a double from 0.0..1.0 as a percentage. */
+ private static String formatPercentage(double percentage) {
+ return NumberFormat.getPercentInstance().format(percentage);
+ }
+
+ public static int getBatteryLevel(Intent batteryChangedIntent) {
+ int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
+ return (level * 100) / scale;
+ }
+
+ public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) {
+ final Intent intent = batteryChangedIntent;
+
+ int plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ String statusString;
+ if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
+ int resId;
+ if (plugType == BatteryManager.BATTERY_PLUGGED_AC) {
+ resId = R.string.battery_info_status_charging_ac;
+ } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) {
+ resId = R.string.battery_info_status_charging_usb;
+ } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
+ resId = R.string.battery_info_status_charging_wireless;
+ } else {
+ resId = R.string.battery_info_status_charging;
+ }
+ statusString = res.getString(resId);
+ } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+ statusString = res.getString(R.string.battery_info_status_discharging);
+ } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
+ statusString = res.getString(R.string.battery_info_status_not_charging);
+ } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
+ statusString = res.getString(R.string.battery_info_status_full);
+ } else {
+ statusString = res.getString(R.string.battery_info_status_unknown);
+ }
+
+ return statusString;
+ }
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 66a3336..6201fd6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -143,6 +143,9 @@
<!-- Block notifications inline notifications -->
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <!-- Access battery information -->
+ <uses-permission android:name="android.permission.BATTERY_STATS" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
new file mode 100644
index 0000000..ea4db4b
--- /dev/null
+++ b/packages/SystemUI/res/layout/battery_detail.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:clickable="true">
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:scaleType="fitCenter"
+ android:adjustViewBounds="true"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="32dp" />
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toStartOf="@android:id/toggle"
+ android:layout_toEndOf="@android:id/icon"
+ android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
+ android:text="@string/battery_detail_switch_title" />
+
+ <TextView
+ android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_toStartOf="@android:id/toggle"
+ android:layout_toEndOf="@android:id/icon"
+ android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary"
+ android:text="@string/battery_detail_switch_summary" />
+
+ <Switch
+ android:id="@android:id/toggle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginEnd="16dp"
+ android:clickable="false"
+ android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index 6102aa6..bf0cba2 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -37,4 +37,18 @@
<item>157</item><item>334</item>
<item>0</item> <item>334</item>
</array>
+ <array name="batterymeter_plus_points">
+ <item>3</item><item>0</item>
+ <item>5</item><item>0</item>
+ <item>5</item><item>3</item>
+ <item>8</item><item>3</item>
+ <item>8</item><item>5</item>
+ <item>5</item><item>5</item>
+ <item>5</item><item>8</item>
+ <item>3</item><item>8</item>
+ <item>3</item><item>5</item>
+ <item>0</item><item>5</item>
+ <item>0</item><item>3</item>
+ <item>3</item><item>3</item>
+ </array>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 876c21e..4136c11 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1269,4 +1269,16 @@
<string name="color_modification_g" translatable="false">G</string>
<string name="color_modification_b" translatable="false">B</string>
+ <!-- Title of the battery settings detail panel [CHAR LIMIT=20] -->
+ <string name="battery_panel_title">Battery (<xliff:g name="pattery_percent" example="52">%1$d</xliff:g>%%)</string>
+
+ <!-- Summary of battery saver not available [CHAR LIMIT=NONE] -->
+ <string name="battery_detail_charging_summary">Battery Saver not available during charging</string>
+
+ <!-- Title of switch for battery saver [CHAR LIMIT=NONE] -->
+ <string name="battery_detail_switch_title">Battery Saver</string>
+
+ <!-- Summary of switch for battery saver [CHAR LIMIT=NONE] -->
+ <string name="battery_detail_switch_summary">Reduces performance and background data</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
index 3eb1271..38ae345 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
@@ -49,7 +49,8 @@
private float mButtonHeightFraction;
private float mSubpixelSmoothingLeft;
private float mSubpixelSmoothingRight;
- private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
+ private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint,
+ mPlusPaint;
private float mTextHeight, mWarningTextHeight;
private int mIconTint = Color.WHITE;
@@ -60,10 +61,13 @@
private int mChargeColor;
private final float[] mBoltPoints;
private final Path mBoltPath = new Path();
+ private final float[] mPlusPoints;
+ private final Path mPlusPath = new Path();
private final RectF mFrame = new RectF();
private final RectF mButtonFrame = new RectF();
private final RectF mBoltFrame = new RectF();
+ private final RectF mPlusFrame = new RectF();
private final Path mShapePath = new Path();
private final Path mClipPath = new Path();
@@ -141,6 +145,9 @@
mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
mBoltPoints = loadBoltPoints(res);
+ mPlusPaint = new Paint(mBoltPaint);
+ mPlusPoints = loadPlusPoints(res);
+
mDarkModeBackgroundColor =
context.getColor(R.color.dark_mode_icon_color_dual_tone_background);
mDarkModeFillColor = context.getColor(R.color.dark_mode_icon_color_dual_tone_fill);
@@ -187,8 +194,8 @@
}
@Override
- public void onPowerSaveChanged() {
- mPowerSaveEnabled = mBatteryController.isPowerSave();
+ public void onPowerSaveChanged(boolean isPowerSave) {
+ mPowerSaveEnabled = isPowerSave;
invalidateSelf();
}
@@ -207,6 +214,21 @@
return ptsF;
}
+ private static float[] loadPlusPoints(Resources res) {
+ final int[] pts = res.getIntArray(R.array.batterymeter_plus_points);
+ int maxX = 0, maxY = 0;
+ for (int i = 0; i < pts.length; i += 2) {
+ maxX = Math.max(maxX, pts[i]);
+ maxY = Math.max(maxY, pts[i + 1]);
+ }
+ final float[] ptsF = new float[pts.length];
+ for (int i = 0; i < pts.length; i += 2) {
+ ptsF[i] = (float)pts[i] / maxX;
+ ptsF[i + 1] = (float)pts[i + 1] / maxY;
+ }
+ return ptsF;
+ }
+
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
@@ -328,9 +350,9 @@
if (mPluggedIn) {
// define the bolt shape
- final float bl = mFrame.left + mFrame.width() / 4.5f;
+ final float bl = mFrame.left + mFrame.width() / 4f;
final float bt = mFrame.top + mFrame.height() / 6f;
- final float br = mFrame.right - mFrame.width() / 7f;
+ final float br = mFrame.right - mFrame.width() / 4f;
final float bb = mFrame.bottom - mFrame.height() / 10f;
if (mBoltFrame.left != bl || mBoltFrame.top != bt
|| mBoltFrame.right != br || mBoltFrame.bottom != bb) {
@@ -358,6 +380,39 @@
// otherwise cut the bolt out of the overall shape
mShapePath.op(mBoltPath, Path.Op.DIFFERENCE);
}
+ } else if (mPowerSaveEnabled) {
+ // define the plus shape
+ final float pw = mFrame.width() * 2 / 3;
+ final float pl = mFrame.left + (mFrame.width() - pw) / 2;
+ final float pt = mFrame.top + (mFrame.height() - pw) / 2;
+ final float pr = mFrame.right - (mFrame.width() - pw) / 2;
+ final float pb = mFrame.bottom - (mFrame.height() - pw) / 2;
+ if (mPlusFrame.left != pl || mPlusFrame.top != pt
+ || mPlusFrame.right != pr || mPlusFrame.bottom != pb) {
+ mPlusFrame.set(pl, pt, pr, pb);
+ mPlusPath.reset();
+ mPlusPath.moveTo(
+ mPlusFrame.left + mPlusPoints[0] * mPlusFrame.width(),
+ mPlusFrame.top + mPlusPoints[1] * mPlusFrame.height());
+ for (int i = 2; i < mPlusPoints.length; i += 2) {
+ mPlusPath.lineTo(
+ mPlusFrame.left + mPlusPoints[i] * mPlusFrame.width(),
+ mPlusFrame.top + mPlusPoints[i + 1] * mPlusFrame.height());
+ }
+ mPlusPath.lineTo(
+ mPlusFrame.left + mPlusPoints[0] * mPlusFrame.width(),
+ mPlusFrame.top + mPlusPoints[1] * mPlusFrame.height());
+ }
+
+ float boltPct = (mPlusFrame.bottom - levelTop) / (mPlusFrame.bottom - mPlusFrame.top);
+ boltPct = Math.min(Math.max(boltPct, 0), 1);
+ if (boltPct <= BOLT_LEVEL_THRESHOLD) {
+ // draw the bolt if opaque
+ c.drawPath(mPlusPath, mPlusPaint);
+ } else {
+ // otherwise cut the bolt out of the overall shape
+ mShapePath.op(mPlusPath, Path.Op.DIFFERENCE);
+ }
}
// compute percentage text
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 6cb8da4..cdbdc22 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -74,7 +74,7 @@
}
@Override
- public void onPowerSaveChanged() {
+ public void onPowerSaveChanged(boolean isPowerSave) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 19b65f7..ea1c9bf 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -52,7 +52,6 @@
private static final int SHOWING_NOTHING = 0;
private static final int SHOWING_WARNING = 1;
- private static final int SHOWING_SAVER = 2;
private static final int SHOWING_INVALID_CHARGER = 3;
private static final String[] SHOWING_STRINGS = {
"SHOWING_NOTHING",
@@ -63,7 +62,6 @@
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 String ACTION_DISMISSED_WARNING = "PNW.dismissedWarning";
private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
@@ -77,7 +75,6 @@
private final Handler mHandler = new Handler();
private final Receiver mReceiver = new Receiver();
private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
- private final Intent mOpenSaverSettings = settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
private int mBatteryLevel;
private int mBucket;
@@ -86,7 +83,6 @@
private long mBucketDroppedNegativeTimeMs;
- private boolean mSaver;
private boolean mWarning;
private boolean mPlaySound;
private boolean mInvalidCharger;
@@ -101,7 +97,6 @@
@Override
public void dump(PrintWriter pw) {
- pw.print("mSaver="); pw.println(mSaver);
pw.print("mWarning="); pw.println(mWarning);
pw.print("mPlaySound="); pw.println(mPlaySound);
pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
@@ -121,27 +116,15 @@
mScreenOffTime = screenOffTime;
}
- @Override
- public void showSaverMode(boolean mode) {
- mSaver = mode;
- if (mSaver && mSaverConfirmation != null) {
- mSaverConfirmation.dismiss();
- }
- updateNotification();
- }
-
private void updateNotification() {
if (DEBUG) Slog.d(TAG, "updateNotification mWarning=" + mWarning + " mPlaySound="
- + mPlaySound + " mSaver=" + mSaver + " mInvalidCharger=" + mInvalidCharger);
+ + mPlaySound + " mInvalidCharger=" + mInvalidCharger);
if (mInvalidCharger) {
showInvalidChargerNotification();
mShowing = SHOWING_INVALID_CHARGER;
} else if (mWarning) {
showWarningNotification();
mShowing = SHOWING_WARNING;
- } else if (mSaver) {
- showSaverNotification();
- mShowing = SHOWING_SAVER;
} else {
mNoMan.cancelAsUser(TAG_NOTIFICATION, R.id.notification_power, UserHandle.ALL);
mShowing = SHOWING_NOTHING;
@@ -165,8 +148,7 @@
}
private void showWarningNotification() {
- final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
- : R.string.battery_low_percent_format;
+ final int textRes = R.string.battery_low_percent_format;
final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);
final Notification.Builder nb = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.ic_power_low)
@@ -184,13 +166,9 @@
if (hasBatterySettings()) {
nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
}
- if (!mSaver) {
- nb.addAction(0,
- mContext.getString(R.string.battery_saver_start_action),
- pendingBroadcast(ACTION_START_SAVER));
- } else {
- addStopSaverAction(nb);
- }
+ nb.addAction(0,
+ mContext.getString(R.string.battery_saver_start_action),
+ pendingBroadcast(ACTION_START_SAVER));
if (mPlaySound) {
attachLowBatterySound(nb);
mPlaySound = false;
@@ -199,35 +177,6 @@
mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, n, UserHandle.ALL);
}
- private void showSaverNotification() {
- final Notification.Builder nb = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_power_saver)
- .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
- .setContentText(mContext.getString(R.string.battery_saver_notification_text))
- .setOngoing(true)
- .setShowWhen(false)
- .setVisibility(Notification.VISIBILITY_PUBLIC)
- .setColor(mContext.getColor(
- com.android.internal.R.color.battery_saver_mode_color));
- addStopSaverAction(nb);
- if (hasSaverSettings()) {
- nb.setContentIntent(pendingActivity(mOpenSaverSettings));
- }
- mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, nb.build(), UserHandle.ALL);
- }
-
- private void addStopSaverAction(Notification.Builder nb) {
- nb.addAction(0,
- 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);
@@ -272,10 +221,6 @@
return mOpenBatterySettings.resolveActivity(mContext.getPackageManager()) != null;
}
- private boolean hasSaverSettings() {
- return mOpenSaverSettings.resolveActivity(mContext.getPackageManager()) != null;
- }
-
@Override
public void showLowBatteryWarning(boolean playSound) {
Slog.i(TAG,
@@ -367,7 +312,6 @@
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
filter.addAction(ACTION_START_SAVER);
- filter.addAction(ACTION_STOP_SAVER);
filter.addAction(ACTION_DISMISSED_WARNING);
mContext.registerReceiverAsUser(this, UserHandle.ALL, filter,
android.Manifest.permission.STATUS_BAR_SERVICE, mHandler);
@@ -383,10 +327,6 @@
} else if (action.equals(ACTION_START_SAVER)) {
dismissLowBatteryNotification();
showStartSaverConfirmation();
- } else if (action.equals(ACTION_STOP_SAVER)) {
- dismissSaverNotification();
- dismissLowBatteryNotification();
- setSaverMode(false);
} else if (action.equals(ACTION_DISMISSED_WARNING)) {
dismissLowBatteryWarning();
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 9459740..522d533 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -76,10 +76,6 @@
mReceiver.init();
}
- private void setSaverMode(boolean mode) {
- mWarnings.showSaverMode(mode);
- }
-
void updateBatteryWarningLevels() {
int critLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
@@ -141,11 +137,6 @@
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
mContext.registerReceiver(this, filter, null, mHandler);
- updateSaverMode();
- }
-
- private void updateSaverMode() {
- setSaverMode(mPowerManager.isPowerSaveMode());
}
@Override
@@ -210,10 +201,6 @@
mScreenOffTime = -1;
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mWarnings.userSwitched();
- } 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 +238,6 @@
public interface WarningsUI {
void update(int batteryLevel, int bucket, long screenOffTime);
- void showSaverMode(boolean mode);
void dismissLowBatteryWarning();
void showLowBatteryWarning(boolean playSound);
void dismissInvalidChargerWarning();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 16fd9eb..91f88b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -466,7 +466,7 @@
MetricsLogger.visible(mContext, detailAdapter.getMetricsCategory());
announceForAccessibility(mContext.getString(
R.string.accessibility_quick_settings_detail,
- mContext.getString(detailAdapter.getTitle())));
+ detailAdapter.getTitle()));
setDetailRecord(r);
listener = mHideGridContentWhenDone;
if (r instanceof TileRecord && visibleDiff) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index b6776bb..8ce6da2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -109,7 +109,7 @@
}
public interface DetailAdapter {
- int getTitle();
+ CharSequence getTitle();
Boolean getToggleState();
View createDetailView(Context context, View convertView, ViewGroup parent);
Intent getSettingsIntent();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 84eac65..60238fc3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -19,7 +19,14 @@
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Checkable;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.settingslib.BatteryInfo;
import com.android.systemui.BatteryMeterDrawable;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
@@ -31,8 +38,11 @@
private final BatteryMeterDrawable mDrawable;
private final BatteryController mBatteryController;
+ private final BatteryDetail mBatteryDetail = new BatteryDetail();
private int mLevel;
+ private boolean mPowerSave;
+ private boolean mCharging;
public BatteryTile(Host host) {
super(host);
@@ -48,6 +58,11 @@
}
@Override
+ public DetailAdapter getDetailAdapter() {
+ return mBatteryDetail;
+ }
+
+ @Override
public int getMetricsCategory() {
return MetricsLogger.QS_BATTERY_TILE;
}
@@ -64,8 +79,16 @@
}
@Override
+ public void setDetailListening(boolean listening) {
+ super.setDetailListening(listening);
+ if (!listening) {
+ mBatteryDetail.mCurrentView = null;
+ }
+ }
+
+ @Override
protected void handleClick() {
- mHost.startActivityDismissingKeyguard(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY));
+ showDetail(true);
}
@Override
@@ -85,11 +108,98 @@
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
mLevel = level;
+ mCharging = charging;
refreshState((Integer) level);
+ if (mBatteryDetail.mCurrentView != null) {
+ mBatteryDetail.bindView();
+ }
}
@Override
- public void onPowerSaveChanged() {
+ public void onPowerSaveChanged(boolean isPowerSave) {
+ mPowerSave = isPowerSave;
+ if (mBatteryDetail.mCurrentView != null) {
+ mBatteryDetail.bindView();
+ }
+ }
+ private final class BatteryDetail implements DetailAdapter, View.OnClickListener {
+ private final BatteryMeterDrawable mDrawable = new BatteryMeterDrawable(mHost.getContext(),
+ new Handler(), mHost.getContext().getColor(R.color.batterymeter_frame_color));
+ private View mCurrentView;
+
+ @Override
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.battery_panel_title, mLevel);
+ }
+
+ @Override
+ public Boolean getToggleState() {
+ return null;
+ }
+
+ @Override
+ public View createDetailView(Context context, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = LayoutInflater.from(mContext).inflate(R.layout.battery_detail, parent,
+ false);
+ }
+ mCurrentView = convertView;
+ bindView();
+ return convertView;
+ }
+
+ private void bindView() {
+ mDrawable.onBatteryLevelChanged(100, false, false);
+ mDrawable.onPowerSaveChanged(true);
+ ((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
+ Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
+ checkbox.setChecked(mPowerSave);
+ if (mCharging) {
+ BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
+ @Override
+ public void onBatteryInfoLoaded(BatteryInfo info) {
+ if (mCurrentView != null && mCharging) {
+ ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
+ info.mChargeLabelString);
+ }
+ }
+ });
+ ((TextView) mCurrentView.findViewById(android.R.id.summary)).setText(
+ R.string.battery_detail_charging_summary);
+ mCurrentView.setClickable(false);
+ mCurrentView.findViewById(android.R.id.icon).setVisibility(View.INVISIBLE);
+ mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.INVISIBLE);
+ } else {
+ ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
+ R.string.battery_detail_switch_title);
+ ((TextView) mCurrentView.findViewById(android.R.id.summary)).setText(
+ R.string.battery_detail_switch_summary);
+ mCurrentView.setClickable(true);
+ mCurrentView.findViewById(android.R.id.icon).setVisibility(View.VISIBLE);
+ mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.VISIBLE);
+ mCurrentView.setOnClickListener(this);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ mBatteryController.setPowerSaveMode(!mPowerSave);
+ }
+
+ @Override
+ public Intent getSettingsIntent() {
+ return new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+ }
+
+ @Override
+ public void setToggleState(boolean state) {
+ // No toggle state.
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsLogger.QS_BATTERY_DETAIL;
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index cfc09a0..3750290 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -165,8 +165,8 @@
private QSDetailItems mItems;
@Override
- public int getTitle() {
- return R.string.quick_settings_bluetooth_label;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_bluetooth_label);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index a8e139c..de4c21c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -160,8 +160,8 @@
private QSDetailItems mItems;
@Override
- public int getTitle() {
- return R.string.quick_settings_cast_title;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_cast_title);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 6c7b337..c1dcfea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -223,8 +223,8 @@
private final class CellularDetailAdapter implements DetailAdapter {
@Override
- public int getTitle() {
- return R.string.quick_settings_cellular_detail_title;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_cellular_detail_title);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4f9f46d..4d9b266 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -218,8 +218,8 @@
private final class DndDetailAdapter implements DetailAdapter, OnAttachStateChangeListener {
@Override
- public int getTitle() {
- return R.string.quick_settings_dnd_label;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_dnd_label);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 48b4096..95ea3f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -240,8 +240,8 @@
private AccessPoint[] mAccessPoints;
@Override
- public int getTitle() {
- return R.string.quick_settings_wifi_label;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_wifi_label);
}
public Intent getSettingsIntent() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index b93fc76..f41e47b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -166,7 +166,7 @@
}
@Override
- public void onPowerSaveChanged() {
+ public void onPowerSaveChanged(boolean isPowerSave) {
// could not care less
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 75337e1..4370c38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -810,10 +810,10 @@
mBatteryController = new BatteryController(mContext);
mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
@Override
- public void onPowerSaveChanged() {
+ public void onPowerSaveChanged(boolean isPowerSave) {
mHandler.post(mCheckBarModes);
if (mDozeServiceHost != null) {
- mDozeServiceHost.firePowerSaveChanged(mBatteryController.isPowerSave());
+ mDozeServiceHost.firePowerSaveChanged(isPowerSave);
}
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 3d21f44..d2f1ca9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -419,7 +419,7 @@
}
@Override
- public void onPowerSaveChanged() {
+ public void onPowerSaveChanged(boolean isPowerSave) {
// could not care less
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index 5071df0..bb3e116 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -70,9 +70,14 @@
pw.print(" mPowerSave="); pw.println(mPowerSave);
}
+ public void setPowerSaveMode(boolean powerSave) {
+ mPowerManager.setPowerSaveMode(powerSave);
+ }
+
public void addStateChangedCallback(BatteryStateChangeCallback cb) {
mChangeCallbacks.add(cb);
cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ cb.onPowerSaveChanged(mPowerSave);
}
public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
@@ -158,12 +163,12 @@
private void firePowerSaveChanged() {
final int N = mChangeCallbacks.size();
for (int i = 0; i < N; i++) {
- mChangeCallbacks.get(i).onPowerSaveChanged();
+ mChangeCallbacks.get(i).onPowerSaveChanged(mPowerSave);
}
}
public interface BatteryStateChangeCallback {
void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
- void onPowerSaveChanged();
+ void onPowerSaveChanged(boolean isPowerSave);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index b010761..f3a3554 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -643,8 +643,8 @@
private final Intent USER_SETTINGS_INTENT = new Intent("android.settings.USER_SETTINGS");
@Override
- public int getTitle() {
- return R.string.quick_settings_user_title;
+ public CharSequence getTitle() {
+ return mContext.getString(R.string.quick_settings_user_title);
}
@Override