blob: c8cf02a05242962ccb7c3d00986340a44cd6ceec [file] [log] [blame]
John Spurlock3332ba52014-03-10 17:44:07 -04001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.power;
18
Sherry Huangce02ed32019-01-17 20:37:29 +080019import android.app.KeyguardManager;
John Spurlock3332ba52014-03-10 17:44:07 -040020import android.app.Notification;
21import android.app.NotificationManager;
22import android.app.PendingIntent;
Makoto Onukie8bbf952018-04-20 14:04:50 -070023import android.content.ActivityNotFoundException;
John Spurlock3332ba52014-03-10 17:44:07 -040024import android.content.BroadcastReceiver;
Salvador Martinezdf3a5532019-04-05 13:09:18 -070025import android.content.ContentResolver;
John Spurlock3332ba52014-03-10 17:44:07 -040026import android.content.Context;
John Spurlock3332ba52014-03-10 17:44:07 -040027import android.content.Intent;
28import android.content.IntentFilter;
John Spurlock1bb480a2014-08-02 17:12:43 -040029import android.media.AudioAttributes;
Makoto Onukie8bbf952018-04-20 14:04:50 -070030import android.net.Uri;
Salvador Martinezdf3a5532019-04-05 13:09:18 -070031import android.os.Bundle;
John Spurlock3332ba52014-03-10 17:44:07 -040032import android.os.Handler;
Geoffrey Pitsch4a7931d2016-09-15 13:11:47 -040033import android.os.Looper;
John Spurlock8d4e6cb2014-09-14 11:10:22 -040034import android.os.PowerManager;
John Spurlock3332ba52014-03-10 17:44:07 -040035import android.os.UserHandle;
Salvador Martinezdf3a5532019-04-05 13:09:18 -070036import android.provider.Settings;
37import android.provider.Settings.Global;
Salvador Martinezf422b1a2019-03-27 10:35:57 -070038import android.provider.Settings.Secure;
Makoto Onukie8bbf952018-04-20 14:04:50 -070039import android.text.Annotation;
40import android.text.Layout;
41import android.text.SpannableString;
42import android.text.SpannableStringBuilder;
43import android.text.TextPaint;
44import android.text.TextUtils;
45import android.text.method.LinkMovementMethod;
46import android.text.style.URLSpan;
47import android.util.Log;
John Spurlock3332ba52014-03-10 17:44:07 -040048import android.util.Slog;
Makoto Onukie8bbf952018-04-20 14:04:50 -070049import android.view.View;
Sherry Huangce02ed32019-01-17 20:37:29 +080050import android.view.WindowManager;
Gus Prevasab336792018-11-14 13:52:20 -050051
Makoto Onukie8bbf952018-04-20 14:04:50 -070052import androidx.annotation.VisibleForTesting;
John Spurlock3332ba52014-03-10 17:44:07 -040053
Chris Wren5e6c0ff2017-01-05 12:57:06 -050054import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Jason Monk58be7a62017-02-01 20:17:51 -050055import com.android.settingslib.Utils;
Makoto Onuki16a0dd22018-03-20 10:40:37 -070056import com.android.settingslib.fuelgauge.BatterySaverUtils;
Salvador Martinezeb9ab292018-01-19 17:50:24 -080057import com.android.settingslib.utils.PowerUtil;
Sherry Huangce02ed32019-01-17 20:37:29 +080058import com.android.systemui.Dependency;
John Spurlock3332ba52014-03-10 17:44:07 -040059import com.android.systemui.R;
Adrian Roose25c18d2016-06-17 15:59:49 -070060import com.android.systemui.SystemUI;
Sherry Huangce02ed32019-01-17 20:37:29 +080061import com.android.systemui.plugins.ActivityStarter;
John Spurlock1bb480a2014-08-02 17:12:43 -040062import com.android.systemui.statusbar.phone.SystemUIDialog;
Dan Sandler8e032e12017-01-25 13:41:38 -050063import com.android.systemui.util.NotificationChannels;
Sherry Huangce02ed32019-01-17 20:37:29 +080064import com.android.systemui.volume.Events;
John Spurlock3332ba52014-03-10 17:44:07 -040065
66import java.io.PrintWriter;
Elliott Hughes88d25512014-10-03 12:06:17 -070067import java.text.NumberFormat;
Makoto Onukie8bbf952018-04-20 14:04:50 -070068import java.util.Locale;
69import java.util.Objects;
John Spurlock3332ba52014-03-10 17:44:07 -040070
Jason Monk196d6392018-12-20 13:25:34 -050071import javax.inject.Inject;
72import javax.inject.Singleton;
73
74/**
75 */
76@Singleton
John Spurlock3332ba52014-03-10 17:44:07 -040077public class PowerNotificationWarnings implements PowerUI.WarningsUI {
Salvador Martinezf422b1a2019-03-27 10:35:57 -070078
John Spurlock3332ba52014-03-10 17:44:07 -040079 private static final String TAG = PowerUI.TAG + ".Notification";
80 private static final boolean DEBUG = PowerUI.DEBUG;
81
Chris Wren5e6c0ff2017-01-05 12:57:06 -050082 private static final String TAG_BATTERY = "low_battery";
83 private static final String TAG_TEMPERATURE = "high_temp";
Makoto Onuki52c62952018-03-22 10:43:03 -070084 private static final String TAG_AUTO_SAVER = "auto_saver";
John Spurlock3332ba52014-03-10 17:44:07 -040085
86 private static final int SHOWING_NOTHING = 0;
87 private static final int SHOWING_WARNING = 1;
John Spurlock3332ba52014-03-10 17:44:07 -040088 private static final int SHOWING_INVALID_CHARGER = 3;
Makoto Onuki52c62952018-03-22 10:43:03 -070089 private static final int SHOWING_AUTO_SAVER_SUGGESTION = 4;
John Spurlock3332ba52014-03-10 17:44:07 -040090 private static final String[] SHOWING_STRINGS = {
91 "SHOWING_NOTHING",
92 "SHOWING_WARNING",
93 "SHOWING_SAVER",
94 "SHOWING_INVALID_CHARGER",
Makoto Onuki52c62952018-03-22 10:43:03 -070095 "SHOWING_AUTO_SAVER_SUGGESTION",
John Spurlock3332ba52014-03-10 17:44:07 -040096 };
97
John Spurlock3332ba52014-03-10 17:44:07 -040098 private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
99 private static final String ACTION_START_SAVER = "PNW.startSaver";
John Spurlock42bfc9a2014-10-29 11:13:01 -0400100 private static final String ACTION_DISMISSED_WARNING = "PNW.dismissedWarning";
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800101 private static final String ACTION_CLICKED_TEMP_WARNING = "PNW.clickedTempWarning";
102 private static final String ACTION_DISMISSED_TEMP_WARNING = "PNW.dismissedTempWarning";
Salvador Martineza6f7b252017-04-10 10:46:15 -0700103 private static final String ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING =
104 "PNW.clickedThermalShutdownWarning";
105 private static final String ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING =
106 "PNW.dismissedThermalShutdownWarning";
Makoto Onuki16a0dd22018-03-20 10:40:37 -0700107 private static final String ACTION_SHOW_START_SAVER_CONFIRMATION =
108 BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION;
Makoto Onuki52c62952018-03-22 10:43:03 -0700109 private static final String ACTION_SHOW_AUTO_SAVER_SUGGESTION =
110 BatterySaverUtils.ACTION_SHOW_AUTO_SAVER_SUGGESTION;
111 private static final String ACTION_DISMISS_AUTO_SAVER_SUGGESTION =
112 "PNW.dismissAutoSaverSuggestion";
113
114 private static final String ACTION_ENABLE_AUTO_SAVER =
115 "PNW.enableAutoSaver";
116 private static final String ACTION_AUTO_SAVER_NO_THANKS =
117 "PNW.autoSaverNoThanks";
118
119 private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
120 "android.settings.BATTERY_SAVER_SETTINGS";
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700121 public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION =
122 "com.android.settings.BATTERY_SAVER_SCHEDULE_SETTINGS";
John Spurlock1bb480a2014-08-02 17:12:43 -0400123
Makoto Onukie8bbf952018-04-20 14:04:50 -0700124 private static final String BATTERY_SAVER_DESCRIPTION_URL_KEY = "url";
125
John Spurlock1bb480a2014-08-02 17:12:43 -0400126 private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
127 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
128 .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
129 .build();
Salvador Martinezf422b1a2019-03-27 10:35:57 -0700130 public static final String EXTRA_CONFIRM_ONLY = "extra_confirm_only";
John Spurlock3332ba52014-03-10 17:44:07 -0400131
132 private final Context mContext;
John Spurlock3332ba52014-03-10 17:44:07 -0400133 private final NotificationManager mNoMan;
John Spurlock8d4e6cb2014-09-14 11:10:22 -0400134 private final PowerManager mPowerMan;
Sherry Huangce02ed32019-01-17 20:37:29 +0800135 private final KeyguardManager mKeyguard;
Geoffrey Pitsch4a7931d2016-09-15 13:11:47 -0400136 private final Handler mHandler = new Handler(Looper.getMainLooper());
John Spurlock3332ba52014-03-10 17:44:07 -0400137 private final Receiver mReceiver = new Receiver();
138 private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
John Spurlock3332ba52014-03-10 17:44:07 -0400139
140 private int mBatteryLevel;
141 private int mBucket;
142 private long mScreenOffTime;
143 private int mShowing;
144
Salvador Martinezf9e47502018-01-04 13:45:48 -0800145 private long mWarningTriggerTimeMs;
John Spurlock3332ba52014-03-10 17:44:07 -0400146 private boolean mWarning;
Makoto Onuki52c62952018-03-22 10:43:03 -0700147 private boolean mShowAutoSaverSuggestion;
John Spurlock3332ba52014-03-10 17:44:07 -0400148 private boolean mPlaySound;
149 private boolean mInvalidCharger;
John Spurlock1bb480a2014-08-02 17:12:43 -0400150 private SystemUIDialog mSaverConfirmation;
Makoto Onuki52c62952018-03-22 10:43:03 -0700151 private SystemUIDialog mSaverEnabledConfirmation;
Salvador Martineza6f7b252017-04-10 10:46:15 -0700152 private boolean mHighTempWarning;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800153 private SystemUIDialog mHighTempDialog;
Salvador Martineza6f7b252017-04-10 10:46:15 -0700154 private SystemUIDialog mThermalShutdownDialog;
Sherry Huangce02ed32019-01-17 20:37:29 +0800155 @VisibleForTesting SystemUIDialog mUsbHighTempDialog;
Salvador Martinez4387bd52019-02-21 16:16:28 -0800156 private BatteryStateSnapshot mCurrentBatterySnapshot;
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700157 private ActivityStarter mActivityStarter;
John Spurlock3332ba52014-03-10 17:44:07 -0400158
Jason Monk196d6392018-12-20 13:25:34 -0500159 /**
160 */
161 @Inject
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700162 public PowerNotificationWarnings(Context context, ActivityStarter activityStarter) {
John Spurlock3332ba52014-03-10 17:44:07 -0400163 mContext = context;
Jason Monkd819c312017-08-11 12:53:36 -0400164 mNoMan = mContext.getSystemService(NotificationManager.class);
John Spurlock8d4e6cb2014-09-14 11:10:22 -0400165 mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
Sherry Huangce02ed32019-01-17 20:37:29 +0800166 mKeyguard = mContext.getSystemService(KeyguardManager.class);
John Spurlock3332ba52014-03-10 17:44:07 -0400167 mReceiver.init();
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700168 mActivityStarter = activityStarter;
John Spurlock3332ba52014-03-10 17:44:07 -0400169 }
170
171 @Override
172 public void dump(PrintWriter pw) {
John Spurlock3332ba52014-03-10 17:44:07 -0400173 pw.print("mWarning="); pw.println(mWarning);
174 pw.print("mPlaySound="); pw.println(mPlaySound);
175 pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
176 pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
John Spurlock1bb480a2014-08-02 17:12:43 -0400177 pw.print("mSaverConfirmation="); pw.println(mSaverConfirmation != null ? "not null" : null);
Makoto Onuki52c62952018-03-22 10:43:03 -0700178 pw.print("mSaverEnabledConfirmation=");
Salvador Martineza6f7b252017-04-10 10:46:15 -0700179 pw.print("mHighTempWarning="); pw.println(mHighTempWarning);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800180 pw.print("mHighTempDialog="); pw.println(mHighTempDialog != null ? "not null" : null);
Salvador Martineza6f7b252017-04-10 10:46:15 -0700181 pw.print("mThermalShutdownDialog=");
182 pw.println(mThermalShutdownDialog != null ? "not null" : null);
Sherry Huangce02ed32019-01-17 20:37:29 +0800183 pw.print("mUsbHighTempDialog=");
184 pw.println(mUsbHighTempDialog != null ? "not null" : null);
John Spurlock3332ba52014-03-10 17:44:07 -0400185 }
186
Makoto Onuki52c62952018-03-22 10:43:03 -0700187 private int getLowBatteryAutoTriggerDefaultLevel() {
188 return mContext.getResources().getInteger(
189 com.android.internal.R.integer.config_lowBatteryAutoTriggerDefaultLevel);
190 }
191
John Spurlock3332ba52014-03-10 17:44:07 -0400192 @Override
193 public void update(int batteryLevel, int bucket, long screenOffTime) {
194 mBatteryLevel = batteryLevel;
Christoph Studer65fa0a92014-06-26 16:50:09 +0200195 if (bucket >= 0) {
Salvador Martinezf9e47502018-01-04 13:45:48 -0800196 mWarningTriggerTimeMs = 0;
Christoph Studer65fa0a92014-06-26 16:50:09 +0200197 } else if (bucket < mBucket) {
Salvador Martinezf9e47502018-01-04 13:45:48 -0800198 mWarningTriggerTimeMs = System.currentTimeMillis();
Christoph Studer65fa0a92014-06-26 16:50:09 +0200199 }
John Spurlock3332ba52014-03-10 17:44:07 -0400200 mBucket = bucket;
201 mScreenOffTime = screenOffTime;
John Spurlock3332ba52014-03-10 17:44:07 -0400202 }
203
Salvador Martinezf9e47502018-01-04 13:45:48 -0800204 @Override
Salvador Martinez4387bd52019-02-21 16:16:28 -0800205 public void updateSnapshot(BatteryStateSnapshot snapshot) {
206 mCurrentBatterySnapshot = snapshot;
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800207 }
208
John Spurlock3332ba52014-03-10 17:44:07 -0400209 private void updateNotification() {
John Spurlock86c3de82014-08-19 13:37:44 -0400210 if (DEBUG) Slog.d(TAG, "updateNotification mWarning=" + mWarning + " mPlaySound="
Jason Monkc06fbb12016-01-08 14:12:18 -0500211 + mPlaySound + " mInvalidCharger=" + mInvalidCharger);
John Spurlock3332ba52014-03-10 17:44:07 -0400212 if (mInvalidCharger) {
John Spurlock3332ba52014-03-10 17:44:07 -0400213 showInvalidChargerNotification();
214 mShowing = SHOWING_INVALID_CHARGER;
215 } else if (mWarning) {
John Spurlock3332ba52014-03-10 17:44:07 -0400216 showWarningNotification();
217 mShowing = SHOWING_WARNING;
Makoto Onuki52c62952018-03-22 10:43:03 -0700218 } else if (mShowAutoSaverSuggestion) {
Makoto Onuki60b8f182018-05-07 13:56:40 -0700219 // Once we showed the notification, don't show it again until it goes SHOWING_NOTHING.
220 // This shouldn't be needed, because we have a delete intent on this notification
221 // so when it's dismissed we should notice it and clear mShowAutoSaverSuggestion,
222 // However we double check here just in case the dismiss intent broadcast is delayed.
223 if (mShowing != SHOWING_AUTO_SAVER_SUGGESTION) {
224 showAutoSaverSuggestionNotification();
225 }
Makoto Onuki52c62952018-03-22 10:43:03 -0700226 mShowing = SHOWING_AUTO_SAVER_SUGGESTION;
John Spurlock3332ba52014-03-10 17:44:07 -0400227 } else {
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500228 mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
229 mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, UserHandle.ALL);
Makoto Onuki52c62952018-03-22 10:43:03 -0700230 mNoMan.cancelAsUser(TAG_AUTO_SAVER,
231 SystemMessage.NOTE_AUTO_SAVER_SUGGESTION, UserHandle.ALL);
John Spurlock3332ba52014-03-10 17:44:07 -0400232 mShowing = SHOWING_NOTHING;
233 }
234 }
235
236 private void showInvalidChargerNotification() {
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500237 final Notification.Builder nb =
238 new Notification.Builder(mContext, NotificationChannels.ALERTS)
239 .setSmallIcon(R.drawable.ic_power_low)
240 .setWhen(0)
241 .setShowWhen(false)
242 .setOngoing(true)
243 .setContentTitle(mContext.getString(R.string.invalid_charger_title))
244 .setContentText(mContext.getString(R.string.invalid_charger_text))
245 .setColor(mContext.getColor(
246 com.android.internal.R.color.system_notification_accent_color));
Julia Reynolds037d8082018-03-18 15:25:19 -0400247 SystemUI.overrideNotificationAppName(mContext, nb, false);
John Spurlock3332ba52014-03-10 17:44:07 -0400248 final Notification n = nb.build();
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500249 mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, UserHandle.ALL);
250 mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, n, UserHandle.ALL);
John Spurlock3332ba52014-03-10 17:44:07 -0400251 }
252
Salvador Martinezf9e47502018-01-04 13:45:48 -0800253 protected void showWarningNotification() {
Salvador Martinezbb902fc2018-01-22 19:46:55 -0800254 final String percentage = NumberFormat.getPercentInstance()
Salvador Martinez4387bd52019-02-21 16:16:28 -0800255 .format((double) mCurrentBatterySnapshot.getBatteryLevel() / 100.0);
Beverly334bc5f2017-07-31 10:37:17 -0400256
Salvador Martinez4387bd52019-02-21 16:16:28 -0800257 // get shared standard notification copy
Salvador Martinezf9e47502018-01-04 13:45:48 -0800258 String title = mContext.getString(R.string.battery_low_title);
Salvador Martinez4387bd52019-02-21 16:16:28 -0800259 String contentText;
Salvador Martinezf9e47502018-01-04 13:45:48 -0800260
Salvador Martinez4387bd52019-02-21 16:16:28 -0800261 // get correct content text if notification is hybrid or not
262 if (mCurrentBatterySnapshot.isHybrid()) {
Salvador Martinezeb9ab292018-01-19 17:50:24 -0800263 contentText = getHybridContentString(percentage);
Salvador Martinez4387bd52019-02-21 16:16:28 -0800264 } else {
265 contentText = mContext.getString(R.string.battery_low_percent_format, percentage);
Salvador Martinezf9e47502018-01-04 13:45:48 -0800266 }
267
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500268 final Notification.Builder nb =
Beverly334bc5f2017-07-31 10:37:17 -0400269 new Notification.Builder(mContext, NotificationChannels.BATTERY)
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500270 .setSmallIcon(R.drawable.ic_power_low)
271 // Bump the notification when the bucket dropped.
Salvador Martinezf9e47502018-01-04 13:45:48 -0800272 .setWhen(mWarningTriggerTimeMs)
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500273 .setShowWhen(false)
Salvador Martinezf9e47502018-01-04 13:45:48 -0800274 .setContentText(contentText)
Salvador Martinez086ab742018-04-03 13:05:39 -0700275 .setContentTitle(title)
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500276 .setOnlyAlertOnce(true)
277 .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
Salvador Martinez086ab742018-04-03 13:05:39 -0700278 .setStyle(new Notification.BigTextStyle().bigText(contentText))
Salvador Martinezf9e47502018-01-04 13:45:48 -0800279 .setVisibility(Notification.VISIBILITY_PUBLIC);
John Spurlock3332ba52014-03-10 17:44:07 -0400280 if (hasBatterySettings()) {
281 nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
282 }
Salvador Martinezf9e47502018-01-04 13:45:48 -0800283 // Make the notification red if the percentage goes below a certain amount or the time
284 // remaining estimate is disabled
Salvador Martinez4387bd52019-02-21 16:16:28 -0800285 if (!mCurrentBatterySnapshot.isHybrid() || mBucket < 0
286 || mCurrentBatterySnapshot.getTimeRemainingMillis()
287 < mCurrentBatterySnapshot.getSevereThresholdMillis()) {
Jason Changb4e879d2018-04-11 11:17:58 +0800288 nb.setColor(Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError));
Salvador Martinezf9e47502018-01-04 13:45:48 -0800289 }
Salvador Martinezc25604b2018-08-03 14:07:44 -0700290
291 if (!mPowerMan.isPowerSaveMode()) {
292 nb.addAction(0,
293 mContext.getString(R.string.battery_saver_start_action),
294 pendingBroadcast(ACTION_START_SAVER));
295 }
Beverly334bc5f2017-07-31 10:37:17 -0400296 nb.setOnlyAlertOnce(!mPlaySound);
297 mPlaySound = false;
Julia Reynolds037d8082018-03-18 15:25:19 -0400298 SystemUI.overrideNotificationAppName(mContext, nb, false);
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500299 final Notification n = nb.build();
300 mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
301 mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL);
John Spurlock3332ba52014-03-10 17:44:07 -0400302 }
303
Makoto Onuki52c62952018-03-22 10:43:03 -0700304 private void showAutoSaverSuggestionNotification() {
305 final Notification.Builder nb =
306 new Notification.Builder(mContext, NotificationChannels.HINTS)
307 .setSmallIcon(R.drawable.ic_power_saver)
308 .setWhen(0)
309 .setShowWhen(false)
310 .setContentTitle(mContext.getString(R.string.auto_saver_title))
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700311 .setContentText(mContext.getString(R.string.auto_saver_text));
Makoto Onuki52c62952018-03-22 10:43:03 -0700312 nb.setContentIntent(pendingBroadcast(ACTION_ENABLE_AUTO_SAVER));
313 nb.setDeleteIntent(pendingBroadcast(ACTION_DISMISS_AUTO_SAVER_SUGGESTION));
314 nb.addAction(0,
315 mContext.getString(R.string.no_auto_saver_action),
316 pendingBroadcast(ACTION_AUTO_SAVER_NO_THANKS));
317
318 SystemUI.overrideNotificationAppName(mContext, nb, false);
319
320 final Notification n = nb.build();
321 mNoMan.notifyAsUser(
322 TAG_AUTO_SAVER, SystemMessage.NOTE_AUTO_SAVER_SUGGESTION, n, UserHandle.ALL);
323 }
324
Salvador Martinezeb9ab292018-01-19 17:50:24 -0800325 private String getHybridContentString(String percentage) {
326 return PowerUtil.getBatteryRemainingStringFormatted(
Salvador Martinez4387bd52019-02-21 16:16:28 -0800327 mContext,
328 mCurrentBatterySnapshot.getTimeRemainingMillis(),
329 percentage,
330 mCurrentBatterySnapshot.isBasedOnUsage());
Salvador Martinezf9e47502018-01-04 13:45:48 -0800331 }
332
John Spurlock3332ba52014-03-10 17:44:07 -0400333 private PendingIntent pendingBroadcast(String action) {
Makoto Onuki52c62952018-03-22 10:43:03 -0700334 return PendingIntent.getBroadcastAsUser(mContext, 0,
Makoto Onuki60b8f182018-05-07 13:56:40 -0700335 new Intent(action).setPackage(mContext.getPackageName())
336 .setFlags(Intent.FLAG_RECEIVER_FOREGROUND),
337 0, UserHandle.CURRENT);
John Spurlock3332ba52014-03-10 17:44:07 -0400338 }
339
340 private static Intent settings(String action) {
341 return new Intent(action).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
342 | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
343 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
344 | Intent.FLAG_ACTIVITY_NO_HISTORY
345 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
346 }
347
348 @Override
349 public boolean isInvalidChargerWarningShowing() {
350 return mInvalidCharger;
351 }
352
353 @Override
Salvador Martineza6f7b252017-04-10 10:46:15 -0700354 public void dismissHighTemperatureWarning() {
355 if (!mHighTempWarning) {
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800356 return;
357 }
Salvador Martineza6f7b252017-04-10 10:46:15 -0700358 dismissHighTemperatureWarningInternal();
Andrew Sapperstein97bfa0f2017-01-24 16:38:50 -0800359 }
360
361 /**
Salvador Martineza6f7b252017-04-10 10:46:15 -0700362 * Internal only version of {@link #dismissHighTemperatureWarning()} that simply dismisses
Andrew Sapperstein97bfa0f2017-01-24 16:38:50 -0800363 * the notification. As such, the notification will not show again until
Salvador Martineza6f7b252017-04-10 10:46:15 -0700364 * {@link #dismissHighTemperatureWarning()} is called.
Andrew Sapperstein97bfa0f2017-01-24 16:38:50 -0800365 */
Salvador Martineza6f7b252017-04-10 10:46:15 -0700366 private void dismissHighTemperatureWarningInternal() {
Andrew Sapperstein97bfa0f2017-01-24 16:38:50 -0800367 mNoMan.cancelAsUser(TAG_TEMPERATURE, SystemMessage.NOTE_HIGH_TEMP, UserHandle.ALL);
Sherry Huang18d27042019-03-19 21:45:28 +0800368 mHighTempWarning = false;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800369 }
370
371 @Override
Salvador Martineza6f7b252017-04-10 10:46:15 -0700372 public void showHighTemperatureWarning() {
373 if (mHighTempWarning) {
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800374 return;
375 }
Salvador Martineza6f7b252017-04-10 10:46:15 -0700376 mHighTempWarning = true;
Geoffrey Pitsch1dc93bc2017-01-31 16:38:11 -0500377 final Notification.Builder nb =
378 new Notification.Builder(mContext, NotificationChannels.ALERTS)
379 .setSmallIcon(R.drawable.ic_device_thermostat_24)
380 .setWhen(0)
381 .setShowWhen(false)
382 .setContentTitle(mContext.getString(R.string.high_temp_title))
383 .setContentText(mContext.getString(R.string.high_temp_notif_message))
384 .setVisibility(Notification.VISIBILITY_PUBLIC)
385 .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
386 .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
Jason Changb4e879d2018-04-11 11:17:58 +0800387 .setColor(Utils.getColorAttrDefaultColor(mContext,
388 android.R.attr.colorError));
Julia Reynolds037d8082018-03-18 15:25:19 -0400389 SystemUI.overrideNotificationAppName(mContext, nb, false);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800390 final Notification n = nb.build();
Chris Wren5e6c0ff2017-01-05 12:57:06 -0500391 mNoMan.notifyAsUser(TAG_TEMPERATURE, SystemMessage.NOTE_HIGH_TEMP, n, UserHandle.ALL);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800392 }
393
Salvador Martineza6f7b252017-04-10 10:46:15 -0700394 private void showHighTemperatureDialog() {
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800395 if (mHighTempDialog != null) return;
396 final SystemUIDialog d = new SystemUIDialog(mContext);
Andrew Sappersteine26dc3d2017-01-04 11:25:20 -0800397 d.setIconAttribute(android.R.attr.alertDialogIcon);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800398 d.setTitle(R.string.high_temp_title);
399 d.setMessage(R.string.high_temp_dialog_message);
400 d.setPositiveButton(com.android.internal.R.string.ok, null);
401 d.setShowForAllUsers(true);
402 d.setOnDismissListener(dialog -> mHighTempDialog = null);
403 d.show();
404 mHighTempDialog = d;
405 }
406
Salvador Martineza6f7b252017-04-10 10:46:15 -0700407 @VisibleForTesting
408 void dismissThermalShutdownWarning() {
409 mNoMan.cancelAsUser(TAG_TEMPERATURE, SystemMessage.NOTE_THERMAL_SHUTDOWN, UserHandle.ALL);
410 }
411
412 private void showThermalShutdownDialog() {
413 if (mThermalShutdownDialog != null) return;
414 final SystemUIDialog d = new SystemUIDialog(mContext);
415 d.setIconAttribute(android.R.attr.alertDialogIcon);
416 d.setTitle(R.string.thermal_shutdown_title);
417 d.setMessage(R.string.thermal_shutdown_dialog_message);
418 d.setPositiveButton(com.android.internal.R.string.ok, null);
419 d.setShowForAllUsers(true);
420 d.setOnDismissListener(dialog -> mThermalShutdownDialog = null);
421 d.show();
422 mThermalShutdownDialog = d;
423 }
424
425 @Override
426 public void showThermalShutdownWarning() {
427 final Notification.Builder nb =
428 new Notification.Builder(mContext, NotificationChannels.ALERTS)
429 .setSmallIcon(R.drawable.ic_device_thermostat_24)
430 .setWhen(0)
431 .setShowWhen(false)
432 .setContentTitle(mContext.getString(R.string.thermal_shutdown_title))
433 .setContentText(mContext.getString(R.string.thermal_shutdown_message))
434 .setVisibility(Notification.VISIBILITY_PUBLIC)
435 .setContentIntent(pendingBroadcast(ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING))
436 .setDeleteIntent(
437 pendingBroadcast(ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING))
Jason Changb4e879d2018-04-11 11:17:58 +0800438 .setColor(Utils.getColorAttrDefaultColor(mContext,
439 android.R.attr.colorError));
Julia Reynolds037d8082018-03-18 15:25:19 -0400440 SystemUI.overrideNotificationAppName(mContext, nb, false);
Salvador Martineza6f7b252017-04-10 10:46:15 -0700441 final Notification n = nb.build();
442 mNoMan.notifyAsUser(
443 TAG_TEMPERATURE, SystemMessage.NOTE_THERMAL_SHUTDOWN, n, UserHandle.ALL);
444 }
445
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800446 @Override
Sherry Huangce02ed32019-01-17 20:37:29 +0800447 public void showUsbHighTemperatureAlarm() {
448 mHandler.post(() -> showUsbHighTemperatureAlarmInternal());
449 }
450
451 private void showUsbHighTemperatureAlarmInternal() {
452 if (mUsbHighTempDialog != null) {
453 return;
454 }
455
456 final SystemUIDialog d = new SystemUIDialog(mContext, R.style.Theme_SystemUI_Dialog_Alert);
457 d.setCancelable(false);
458 d.setIconAttribute(android.R.attr.alertDialogIcon);
459 d.setTitle(R.string.high_temp_alarm_title);
460 d.setShowForAllUsers(true);
461 d.setMessage(mContext.getString(R.string.high_temp_alarm_notify_message, ""));
462 d.setPositiveButton((com.android.internal.R.string.ok),
463 (dialogInterface, which) -> mUsbHighTempDialog = null);
464 d.setNegativeButton((R.string.high_temp_alarm_help_care_steps),
465 (dialogInterface, which) -> {
466 final String contextString = mContext.getString(
467 R.string.high_temp_alarm_help_url);
468 final Intent helpIntent = new Intent();
469 helpIntent.setClassName("com.android.settings",
470 "com.android.settings.HelpTrampoline");
471 helpIntent.putExtra(Intent.EXTRA_TEXT, contextString);
472 Dependency.get(ActivityStarter.class).startActivity(helpIntent,
473 true /* dismissShade */, resultCode -> {
474 mUsbHighTempDialog = null;
475 });
476 });
477 d.setOnDismissListener(dialogInterface -> {
478 mUsbHighTempDialog = null;
Will Brockman1d716b22019-11-26 10:10:07 -0500479 Events.writeEvent(Events.EVENT_DISMISS_USB_OVERHEAT_ALARM,
Sherry Huangce02ed32019-01-17 20:37:29 +0800480 Events.DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED,
481 mKeyguard.isKeyguardLocked());
482 });
483 d.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
484 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
485 d.show();
486 mUsbHighTempDialog = d;
487
Will Brockman1d716b22019-11-26 10:10:07 -0500488 Events.writeEvent(Events.EVENT_SHOW_USB_OVERHEAT_ALARM,
Sherry Huangce02ed32019-01-17 20:37:29 +0800489 Events.SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED,
490 mKeyguard.isKeyguardLocked());
491 }
492
493 @Override
John Spurlock3332ba52014-03-10 17:44:07 -0400494 public void updateLowBatteryWarning() {
495 updateNotification();
John Spurlock3332ba52014-03-10 17:44:07 -0400496 }
497
498 @Override
499 public void dismissLowBatteryWarning() {
John Spurlock3ff2de62014-06-16 13:32:48 -0400500 if (DEBUG) Slog.d(TAG, "dismissing low battery warning: level=" + mBatteryLevel);
John Spurlock3332ba52014-03-10 17:44:07 -0400501 dismissLowBatteryNotification();
John Spurlock3332ba52014-03-10 17:44:07 -0400502 }
503
504 private void dismissLowBatteryNotification() {
John Spurlock3ff2de62014-06-16 13:32:48 -0400505 if (mWarning) Slog.i(TAG, "dismissing low battery notification");
John Spurlock3332ba52014-03-10 17:44:07 -0400506 mWarning = false;
507 updateNotification();
508 }
509
510 private boolean hasBatterySettings() {
511 return mOpenBatterySettings.resolveActivity(mContext.getPackageManager()) != null;
512 }
513
John Spurlock3332ba52014-03-10 17:44:07 -0400514 @Override
515 public void showLowBatteryWarning(boolean playSound) {
516 Slog.i(TAG,
517 "show low battery warning: level=" + mBatteryLevel
Beverly334bc5f2017-07-31 10:37:17 -0400518 + " [" + mBucket + "] playSound=" + playSound);
John Spurlock3332ba52014-03-10 17:44:07 -0400519 mPlaySound = playSound;
520 mWarning = true;
521 updateNotification();
John Spurlock3332ba52014-03-10 17:44:07 -0400522 }
523
John Spurlock3332ba52014-03-10 17:44:07 -0400524 @Override
525 public void dismissInvalidChargerWarning() {
John Spurlockeb44a7d2014-06-12 13:00:55 -0400526 dismissInvalidChargerNotification();
John Spurlockeb44a7d2014-06-12 13:00:55 -0400527 }
528
529 private void dismissInvalidChargerNotification() {
John Spurlock3ff2de62014-06-16 13:32:48 -0400530 if (mInvalidCharger) Slog.i(TAG, "dismissing invalid charger notification");
John Spurlock3332ba52014-03-10 17:44:07 -0400531 mInvalidCharger = false;
532 updateNotification();
533 }
534
535 @Override
536 public void showInvalidChargerWarning() {
537 mInvalidCharger = true;
538 updateNotification();
539 }
540
Makoto Onuki52c62952018-03-22 10:43:03 -0700541 private void showAutoSaverSuggestion() {
542 mShowAutoSaverSuggestion = true;
543 updateNotification();
544 }
545
546 private void dismissAutoSaverSuggestion() {
547 mShowAutoSaverSuggestion = false;
548 updateNotification();
549 }
550
John Spurlockecbc5e82014-10-22 09:05:51 -0400551 @Override
552 public void userSwitched() {
553 updateNotification();
554 }
555
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700556 private void showStartSaverConfirmation(Bundle extras) {
John Spurlock1bb480a2014-08-02 17:12:43 -0400557 if (mSaverConfirmation != null) return;
558 final SystemUIDialog d = new SystemUIDialog(mContext);
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700559 final boolean confirmOnly = extras.getBoolean(BatterySaverUtils.EXTRA_CONFIRM_TEXT_ONLY);
560 final int batterySaverTriggerMode =
561 extras.getInt(BatterySaverUtils.EXTRA_POWER_SAVE_MODE_TRIGGER,
562 PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
563 final int batterySaverTriggerLevel =
564 extras.getInt(BatterySaverUtils.EXTRA_POWER_SAVE_MODE_TRIGGER_LEVEL, 0);
Makoto Onukie8bbf952018-04-20 14:04:50 -0700565 d.setMessage(getBatterySaverDescription());
566
567 // Sad hack for http://b/78261259 and http://b/78298335. Otherwise "Battery" may be split
568 // into "Bat-tery".
569 if (isEnglishLocale()) {
570 d.setMessageHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
571 }
572 // We need to set LinkMovementMethod to make the link clickable.
573 d.setMessageMovementMethod(LinkMovementMethod.getInstance());
574
Salvador Martinezf422b1a2019-03-27 10:35:57 -0700575 if (confirmOnly) {
576 d.setTitle(R.string.battery_saver_confirmation_title_generic);
577 d.setPositiveButton(com.android.internal.R.string.confirm_battery_saver,
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700578 (dialog, which) -> {
579 final ContentResolver resolver = mContext.getContentResolver();
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700580 Settings.Global.putInt(
581 resolver,
582 Global.AUTOMATIC_POWER_SAVE_MODE,
583 batterySaverTriggerMode);
584 Settings.Global.putInt(
585 resolver,
586 Global.LOW_POWER_MODE_TRIGGER_LEVEL,
587 batterySaverTriggerLevel);
Raff Tsai92cdc542019-12-23 09:11:04 +0800588 Secure.putIntForUser(
Salvador Martinezf3cae282019-05-01 13:12:50 -0700589 resolver,
590 Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
Raff Tsai92cdc542019-12-23 09:11:04 +0800591 1, UserHandle.USER_CURRENT);
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700592 });
Salvador Martinezf422b1a2019-03-27 10:35:57 -0700593 } else {
594 d.setTitle(R.string.battery_saver_confirmation_title);
595 d.setPositiveButton(R.string.battery_saver_confirmation_ok,
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700596 (dialog, which) -> setSaverMode(true, false));
Salvador Martinezf422b1a2019-03-27 10:35:57 -0700597 d.setNegativeButton(android.R.string.cancel, null);
598 }
John Spurlock1bb480a2014-08-02 17:12:43 -0400599 d.setShowForAllUsers(true);
Makoto Onuki52c62952018-03-22 10:43:03 -0700600 d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
John Spurlock3332ba52014-03-10 17:44:07 -0400601 d.show();
John Spurlock1bb480a2014-08-02 17:12:43 -0400602 mSaverConfirmation = d;
John Spurlock3332ba52014-03-10 17:44:07 -0400603 }
604
Makoto Onukie8bbf952018-04-20 14:04:50 -0700605 private boolean isEnglishLocale() {
606 return Objects.equals(Locale.getDefault().getLanguage(),
607 Locale.ENGLISH.getLanguage());
608 }
609
610 /**
611 * Generates the message for the "want to start battery saver?" dialog with a "learn more" link.
612 */
613 private CharSequence getBatterySaverDescription() {
614 final String learnMoreUrl = mContext.getText(
615 R.string.help_uri_battery_saver_learn_more_link_target).toString();
616
617 // If there's no link, use the string with no "learn more".
618 if (TextUtils.isEmpty(learnMoreUrl)) {
619 return mContext.getText(
620 com.android.internal.R.string.battery_saver_description);
621 }
622
623 // If we have a link, use the string with the "learn more" link.
624 final CharSequence rawText = mContext.getText(
625 com.android.internal.R.string.battery_saver_description_with_learn_more);
626 final SpannableString message = new SpannableString(rawText);
627 final SpannableStringBuilder builder = new SpannableStringBuilder(message);
628
629 // Look for the "learn more" part of the string, and set a URL span on it.
630 // We use a customized URLSpan to add FLAG_RECEIVER_FOREGROUND to the intent, and
631 // also to close the dialog.
632 for (Annotation annotation : message.getSpans(0, message.length(), Annotation.class)) {
633 final String key = annotation.getValue();
634
635 if (!BATTERY_SAVER_DESCRIPTION_URL_KEY.equals(key)) {
636 continue;
637 }
638 final int start = message.getSpanStart(annotation);
639 final int end = message.getSpanEnd(annotation);
640
641 // Replace the "learn more" with a custom URL span, with
642 // - No underline.
643 // - When clicked, close the dialog and the notification shade.
644 final URLSpan urlSpan = new URLSpan(learnMoreUrl) {
645 @Override
646 public void updateDrawState(TextPaint ds) {
647 super.updateDrawState(ds);
648 ds.setUnderlineText(false);
649 }
650
651 @Override
652 public void onClick(View widget) {
653 // Close the parent dialog.
654 if (mSaverConfirmation != null) {
655 mSaverConfirmation.dismiss();
656 }
657 // Also close the notification shade, if it's open.
658 mContext.sendBroadcast(
659 new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
660 .setFlags(Intent.FLAG_RECEIVER_FOREGROUND));
661
662 final Uri uri = Uri.parse(getURL());
663 Context context = widget.getContext();
664 Intent intent = new Intent(Intent.ACTION_VIEW, uri)
665 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
666 try {
667 context.startActivity(intent);
668 } catch (ActivityNotFoundException e) {
669 Log.w(TAG, "Activity was not found for intent, " + intent.toString());
670 }
671 }
672 };
673 builder.setSpan(urlSpan, start, end, message.getSpanFlags(urlSpan));
674 }
675 return builder;
676 }
677
Makoto Onuki16a0dd22018-03-20 10:40:37 -0700678 private void setSaverMode(boolean mode, boolean needFirstTimeWarning) {
679 BatterySaverUtils.setPowerSaveMode(mContext, mode, needFirstTimeWarning);
John Spurlock3332ba52014-03-10 17:44:07 -0400680 }
681
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700682 private void startBatterySaverSchedulePage() {
683 Intent intent = new Intent(BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION);
684 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
685 mActivityStarter.startActivity(intent, true /* dismissShade */);
Makoto Onuki52c62952018-03-22 10:43:03 -0700686 }
687
John Spurlock3332ba52014-03-10 17:44:07 -0400688 private final class Receiver extends BroadcastReceiver {
689
690 public void init() {
691 IntentFilter filter = new IntentFilter();
John Spurlock3332ba52014-03-10 17:44:07 -0400692 filter.addAction(ACTION_SHOW_BATTERY_SETTINGS);
693 filter.addAction(ACTION_START_SAVER);
John Spurlock42bfc9a2014-10-29 11:13:01 -0400694 filter.addAction(ACTION_DISMISSED_WARNING);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800695 filter.addAction(ACTION_CLICKED_TEMP_WARNING);
696 filter.addAction(ACTION_DISMISSED_TEMP_WARNING);
Salvador Martineza6f7b252017-04-10 10:46:15 -0700697 filter.addAction(ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING);
698 filter.addAction(ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING);
Makoto Onuki16a0dd22018-03-20 10:40:37 -0700699 filter.addAction(ACTION_SHOW_START_SAVER_CONFIRMATION);
Makoto Onuki52c62952018-03-22 10:43:03 -0700700 filter.addAction(ACTION_SHOW_AUTO_SAVER_SUGGESTION);
701 filter.addAction(ACTION_ENABLE_AUTO_SAVER);
702 filter.addAction(ACTION_AUTO_SAVER_NO_THANKS);
Makoto Onuki5ac8d5e2018-04-13 15:53:57 -0700703 filter.addAction(ACTION_DISMISS_AUTO_SAVER_SUGGESTION);
John Spurlock05e07052015-06-01 10:56:42 -0400704 mContext.registerReceiverAsUser(this, UserHandle.ALL, filter,
Makoto Onuki16a0dd22018-03-20 10:40:37 -0700705 android.Manifest.permission.DEVICE_POWER, mHandler);
John Spurlock3332ba52014-03-10 17:44:07 -0400706 }
707
708 @Override
709 public void onReceive(Context context, Intent intent) {
710 final String action = intent.getAction();
John Spurlockeb44a7d2014-06-12 13:00:55 -0400711 Slog.i(TAG, "Received " + action);
John Spurlock86c3de82014-08-19 13:37:44 -0400712 if (action.equals(ACTION_SHOW_BATTERY_SETTINGS)) {
John Spurlock3332ba52014-03-10 17:44:07 -0400713 dismissLowBatteryNotification();
714 mContext.startActivityAsUser(mOpenBatterySettings, UserHandle.CURRENT);
715 } else if (action.equals(ACTION_START_SAVER)) {
Makoto Onuki16a0dd22018-03-20 10:40:37 -0700716 setSaverMode(true, true);
717 dismissLowBatteryNotification();
718 } else if (action.equals(ACTION_SHOW_START_SAVER_CONFIRMATION)) {
John Spurlock3332ba52014-03-10 17:44:07 -0400719 dismissLowBatteryNotification();
Salvador Martinezdf3a5532019-04-05 13:09:18 -0700720 showStartSaverConfirmation(intent.getExtras());
John Spurlock42bfc9a2014-10-29 11:13:01 -0400721 } else if (action.equals(ACTION_DISMISSED_WARNING)) {
722 dismissLowBatteryWarning();
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800723 } else if (ACTION_CLICKED_TEMP_WARNING.equals(action)) {
Salvador Martineza6f7b252017-04-10 10:46:15 -0700724 dismissHighTemperatureWarningInternal();
725 showHighTemperatureDialog();
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800726 } else if (ACTION_DISMISSED_TEMP_WARNING.equals(action)) {
Salvador Martineza6f7b252017-04-10 10:46:15 -0700727 dismissHighTemperatureWarningInternal();
728 } else if (ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING.equals(action)) {
729 dismissThermalShutdownWarning();
730 showThermalShutdownDialog();
731 } else if (ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING.equals(action)) {
732 dismissThermalShutdownWarning();
Makoto Onuki52c62952018-03-22 10:43:03 -0700733 } else if (ACTION_SHOW_AUTO_SAVER_SUGGESTION.equals(action)) {
734 showAutoSaverSuggestion();
735 } else if (ACTION_DISMISS_AUTO_SAVER_SUGGESTION.equals(action)) {
736 dismissAutoSaverSuggestion();
737 } else if (ACTION_ENABLE_AUTO_SAVER.equals(action)) {
738 dismissAutoSaverSuggestion();
Salvador Martinez84b5bff2019-05-16 13:03:55 -0700739 startBatterySaverSchedulePage();
Makoto Onuki52c62952018-03-22 10:43:03 -0700740 } else if (ACTION_AUTO_SAVER_NO_THANKS.equals(action)) {
741 dismissAutoSaverSuggestion();
742 BatterySaverUtils.suppressAutoBatterySaver(context);
John Spurlock3332ba52014-03-10 17:44:07 -0400743 }
744 }
745 }
John Spurlock3332ba52014-03-10 17:44:07 -0400746}