Merge "Show notification when routine battery mode activates"
diff --git a/core/res/res/drawable/ic_battery.xml b/core/res/res/drawable/ic_battery.xml
new file mode 100644
index 0000000..bd40f4d
--- /dev/null
+++ b/core/res/res/drawable/ic_battery.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2018 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4z"/>
+</vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e4abf8f..8735557 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1169,7 +1169,7 @@
<integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer>
<!-- The app which will handle routine based automatic battery saver, if empty the UI for
- routine based battery saver will be hidden -->
+ routine based battery saver will be hidden -->
<string name="config_batterySaverScheduleProvider"></string>
<!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a7bc57a..0878562 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5238,6 +5238,15 @@
<!-- Content description of the overlay icon in the notification. [CHAR LIMIT=NONE] -->
<string name="notification_appops_overlay_active">displaying over other apps on your screen</string>
+ <!-- Dynamic mode battery saver strings -->
+ <!-- The user visible name of the notification channel for the routine mode battery saver fyi notification [CHAR_LIMIT=80]-->
+ <string name="dynamic_mode_notification_channel_name">Routine Mode info notification</string>
+ <!-- Title of notification letting users know why battery saver was turned on automatically [CHAR_LIMIT=NONE]-->
+ <string name="dynamic_mode_notification_title">Battery may run out before usual charge</string>
+ <!-- Summary of notification letting users know why battery saver was turned on automatically [CHAR_LIMIT=NONE]-->
+ <string name="dynamic_mode_notification_summary">Battery Saver activated to extend battery life</string>
+
+
<!-- Strings for car -->
<!-- String displayed when loading a user in the car [CHAR LIMIT=30] -->
<string name="car_loading_profile">Loading</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e8cbf66..c2d97bc 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3519,4 +3519,9 @@
<!-- For Secondary Launcher -->
<java-symbol type="string" name="config_secondaryHomeComponent" />
+
+ <java-symbol type="string" name="dynamic_mode_notification_channel_name" />
+ <java-symbol type="string" name="dynamic_mode_notification_title" />
+ <java-symbol type="string" name="dynamic_mode_notification_summary" />
+ <java-symbol type="drawable" name="ic_battery" />
</resources>
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index f262f6d..a60f16d 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -15,8 +15,14 @@
*/
package com.android.server.power.batterysaver;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.PowerManager;
@@ -26,6 +32,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
@@ -46,6 +53,8 @@
*/
public class BatterySaverStateMachine {
private static final String TAG = "BatterySaverStateMachine";
+ private static final String DYNAMIC_MODE_NOTIF_CHANNEL_ID = "dynamic_mode_notification";
+ private static final int DYNAMIC_MODE_NOTIFICATION_ID = 1992;
private final Object mLock;
private static final boolean DEBUG = BatterySaverPolicy.DEBUG;
@@ -484,6 +493,13 @@
}
mBatterySaverController.enableBatterySaver(enable, intReason);
+ // Handle triggering the notification to show/hide when appropriate
+ if (intReason == BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON) {
+ runOnBgThread(this::triggerDynamicModeNotification);
+ } else if (!enable) {
+ runOnBgThread(this::hideDynamicModeNotification);
+ }
+
if (DEBUG) {
Slog.d(TAG, "Battery saver: Enabled=" + enable
+ " manual=" + manual
@@ -491,6 +507,44 @@
}
}
+ private void triggerDynamicModeNotification() {
+ NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ ensureNotificationChannelExists(manager);
+
+ manager.notify(DYNAMIC_MODE_NOTIFICATION_ID, buildNotification());
+ }
+
+ private void ensureNotificationChannelExists(NotificationManager manager) {
+ NotificationChannel channel = new NotificationChannel(
+ DYNAMIC_MODE_NOTIF_CHANNEL_ID,
+ mContext.getText(
+ R.string.dynamic_mode_notification_channel_name),
+ NotificationManager.IMPORTANCE_DEFAULT);
+ channel.setSound(null, null);
+ manager.createNotificationChannel(channel);
+ }
+
+ private Notification buildNotification() {
+ Resources res = mContext.getResources();
+ Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ PendingIntent batterySaverIntent = PendingIntent.getActivity(
+ mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ return new Notification.Builder(mContext, DYNAMIC_MODE_NOTIF_CHANNEL_ID)
+ .setSmallIcon(R.drawable.ic_battery)
+ .setContentTitle(res.getString(R.string.dynamic_mode_notification_title))
+ .setContentText(res.getString(R.string.dynamic_mode_notification_summary))
+ .setContentIntent(batterySaverIntent)
+ .setOnlyAlertOnce(true)
+ .build();
+ }
+
+ private void hideDynamicModeNotification() {
+ NotificationManager manager = mContext.getSystemService(NotificationManager.class);
+ manager.cancel(DYNAMIC_MODE_NOTIFICATION_ID);
+ }
+
@GuardedBy("mLock")
private void updateSnoozingLocked(boolean snoozing, String reason) {
if (mBatterySaverSnoozing == snoozing) {