blob: f37826853fe5d0776930aa3dda39977c6dc505d1 [file] [log] [blame]
Joe Onorato10523b4d2010-10-25 10:42:46 -07001/*
2 * Copyright (C) 2008 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
Joe Onorato10523b4d2010-10-25 10:42:46 -070019import android.content.BroadcastReceiver;
Dianne Hackborn14272302014-06-10 23:13:02 -070020import android.content.ContentResolver;
Joe Onorato10523b4d2010-10-25 10:42:46 -070021import android.content.Context;
Joe Onorato10523b4d2010-10-25 10:42:46 -070022import android.content.Intent;
23import android.content.IntentFilter;
Adam Lesinski1aab3fa2017-07-31 13:42:00 -070024import android.content.pm.ActivityInfo;
25import android.content.res.Configuration;
Andrew Sappersteine3352562017-01-20 15:41:03 -080026import android.content.res.Resources;
Dianne Hackborn14272302014-06-10 23:13:02 -070027import android.database.ContentObserver;
Joe Onorato4ca7f1e2010-10-27 15:32:23 -070028import android.os.BatteryManager;
Joe Onorato10523b4d2010-10-25 10:42:46 -070029import android.os.Handler;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080030import android.os.HardwarePropertiesManager;
Daniel Sandlerdea64622013-09-23 16:05:57 -040031import android.os.PowerManager;
32import android.os.SystemClock;
Dianne Hackborn14272302014-06-10 23:13:02 -070033import android.os.UserHandle;
Joe Onorato10523b4d2010-10-25 10:42:46 -070034import android.provider.Settings;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080035import android.text.format.DateUtils;
John Spurlock1bb480a2014-08-02 17:12:43 -040036import android.util.Log;
Daniel Sandlerdea64622013-09-23 16:05:57 -040037import android.util.Slog;
Jason Monkd819c312017-08-11 12:53:36 -040038
39import com.android.internal.annotations.VisibleForTesting;
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -080040import com.android.internal.logging.MetricsLogger;
Jason Monkd819c312017-08-11 12:53:36 -040041import com.android.systemui.Dependency;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080042import com.android.systemui.R;
Joe Onorato10523b4d2010-10-25 10:42:46 -070043import com.android.systemui.SystemUI;
Jason Monk2a6ea9c2017-01-26 11:14:51 -050044import com.android.systemui.statusbar.phone.StatusBar;
Jason Monkd819c312017-08-11 12:53:36 -040045
John Spurlockde84f0e2013-06-12 12:41:00 -040046import java.io.FileDescriptor;
47import java.io.PrintWriter;
48import java.util.Arrays;
49
Joe Onorato10523b4d2010-10-25 10:42:46 -070050public class PowerUI extends SystemUI {
51 static final String TAG = "PowerUI";
John Spurlock1bb480a2014-08-02 17:12:43 -040052 static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080053 private static final long TEMPERATURE_INTERVAL = 30 * DateUtils.SECOND_IN_MILLIS;
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -080054 private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS;
55 private static final int MAX_RECENT_TEMPS = 125; // TEMPERATURE_LOGGING_INTERVAL plus a buffer
Joe Onorato10523b4d2010-10-25 10:42:46 -070056
John Spurlocked452c52014-03-06 12:02:31 -050057 private final Handler mHandler = new Handler();
John Spurlock3332ba52014-03-10 17:44:07 -040058 private final Receiver mReceiver = new Receiver();
Joe Onorato4ca7f1e2010-10-27 15:32:23 -070059
John Spurlock3332ba52014-03-10 17:44:07 -040060 private PowerManager mPowerManager;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080061 private HardwarePropertiesManager mHardwarePropertiesManager;
John Spurlock3332ba52014-03-10 17:44:07 -040062 private WarningsUI mWarnings;
Adam Lesinski1aab3fa2017-07-31 13:42:00 -070063 private final Configuration mLastConfiguration = new Configuration();
John Spurlocked452c52014-03-06 12:02:31 -050064 private int mBatteryLevel = 100;
65 private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
66 private int mPlugType = 0;
67 private int mInvalidCharger = 0;
Joe Onorato4ca7f1e2010-10-27 15:32:23 -070068
John Spurlocked452c52014-03-06 12:02:31 -050069 private int mLowBatteryAlertCloseLevel;
70 private final int[] mLowBatteryReminderLevels = new int[2];
Joe Onorato10523b4d2010-10-25 10:42:46 -070071
Daniel Sandlerdea64622013-09-23 16:05:57 -040072 private long mScreenOffTime = -1;
73
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -080074 private float mThresholdTemp;
75 private float[] mRecentTemps = new float[MAX_RECENT_TEMPS];
76 private int mNumTemps;
77 private long mNextLogTime;
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080078
Adam Lesinski1aab3fa2017-07-31 13:42:00 -070079 // We create a method reference here so that we are guaranteed that we can remove a callback
80 // by using the same instance (method references are not guaranteed to be the same object
81 // each time they are created).
82 private final Runnable mUpdateTempCallback = this::updateTemperatureWarning;
83
Joe Onorato10523b4d2010-10-25 10:42:46 -070084 public void start() {
John Spurlock3332ba52014-03-10 17:44:07 -040085 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -080086 mHardwarePropertiesManager = (HardwarePropertiesManager)
87 mContext.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE);
John Spurlock3332ba52014-03-10 17:44:07 -040088 mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
Jason Monkd819c312017-08-11 12:53:36 -040089 mWarnings = Dependency.get(WarningsUI.class);
Adam Lesinski1aab3fa2017-07-31 13:42:00 -070090 mLastConfiguration.setTo(mContext.getResources().getConfiguration());
Daniel Sandlerdea64622013-09-23 16:05:57 -040091
Dianne Hackborn14272302014-06-10 23:13:02 -070092 ContentObserver obs = new ContentObserver(mHandler) {
93 @Override
94 public void onChange(boolean selfChange) {
95 updateBatteryWarningLevels();
96 }
97 };
98 final ContentResolver resolver = mContext.getContentResolver();
99 resolver.registerContentObserver(Settings.Global.getUriFor(
100 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
101 false, obs, UserHandle.USER_ALL);
102 updateBatteryWarningLevels();
John Spurlock3332ba52014-03-10 17:44:07 -0400103 mReceiver.init();
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800104
Salvador Martineza6f7b252017-04-10 10:46:15 -0700105 // Check to see if we need to let the user know that the phone previously shut down due
106 // to the temperature being too high.
107 showThermalShutdownDialog();
108
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800109 initTemperatureWarning();
John Spurlock3332ba52014-03-10 17:44:07 -0400110 }
Dianne Hackborn14272302014-06-10 23:13:02 -0700111
Adam Lesinski1aab3fa2017-07-31 13:42:00 -0700112 @Override
113 protected void onConfigurationChanged(Configuration newConfig) {
114 final int mask = ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC;
115
116 // Safe to modify mLastConfiguration here as it's only updated by the main thread (here).
117 if ((mLastConfiguration.updateFrom(newConfig) & mask) != 0) {
118 mHandler.post(this::initTemperatureWarning);
119 }
120 }
121
Dianne Hackborn14272302014-06-10 23:13:02 -0700122 void updateBatteryWarningLevels() {
123 int critLevel = mContext.getResources().getInteger(
124 com.android.internal.R.integer.config_criticalBatteryWarningLevel);
125
126 final ContentResolver resolver = mContext.getContentResolver();
127 int defWarnLevel = mContext.getResources().getInteger(
128 com.android.internal.R.integer.config_lowBatteryWarningLevel);
129 int warnLevel = Settings.Global.getInt(resolver,
130 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, defWarnLevel);
131 if (warnLevel == 0) {
132 warnLevel = defWarnLevel;
133 }
134 if (warnLevel < critLevel) {
135 warnLevel = critLevel;
136 }
137
138 mLowBatteryReminderLevels[0] = warnLevel;
139 mLowBatteryReminderLevels[1] = critLevel;
140 mLowBatteryAlertCloseLevel = mLowBatteryReminderLevels[0]
141 + mContext.getResources().getInteger(
142 com.android.internal.R.integer.config_lowBatteryCloseWarningBump);
143 }
144
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700145 /**
146 * Buckets the battery level.
147 *
148 * The code in this function is a little weird because I couldn't comprehend
149 * the bucket going up when the battery level was going down. --joeo
150 *
151 * 1 means that the battery is "ok"
152 * 0 means that the battery is between "ok" and what we should warn about.
153 * less than 0 means that the battery is low
154 */
155 private int findBatteryLevelBucket(int level) {
156 if (level >= mLowBatteryAlertCloseLevel) {
157 return 1;
158 }
Dianne Hackborn14272302014-06-10 23:13:02 -0700159 if (level > mLowBatteryReminderLevels[0]) {
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700160 return 0;
161 }
162 final int N = mLowBatteryReminderLevels.length;
163 for (int i=N-1; i>=0; i--) {
164 if (level <= mLowBatteryReminderLevels[i]) {
165 return -1-i;
166 }
167 }
168 throw new RuntimeException("not possible!");
169 }
170
John Spurlock3332ba52014-03-10 17:44:07 -0400171 private final class Receiver extends BroadcastReceiver {
172
173 public void init() {
174 // Register for Intent broadcasts for...
175 IntentFilter filter = new IntentFilter();
176 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
177 filter.addAction(Intent.ACTION_SCREEN_OFF);
178 filter.addAction(Intent.ACTION_SCREEN_ON);
John Spurlockecbc5e82014-10-22 09:05:51 -0400179 filter.addAction(Intent.ACTION_USER_SWITCHED);
John Spurlock3332ba52014-03-10 17:44:07 -0400180 mContext.registerReceiver(this, filter, null, mHandler);
John Spurlock3332ba52014-03-10 17:44:07 -0400181 }
182
Joe Onorato10523b4d2010-10-25 10:42:46 -0700183 @Override
184 public void onReceive(Context context, Intent intent) {
185 String action = intent.getAction();
186 if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700187 final int oldBatteryLevel = mBatteryLevel;
188 mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);
189 final int oldBatteryStatus = mBatteryStatus;
190 mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
191 BatteryManager.BATTERY_STATUS_UNKNOWN);
192 final int oldPlugType = mPlugType;
193 mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
194 final int oldInvalidCharger = mInvalidCharger;
195 mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);
196
197 final boolean plugged = mPlugType != 0;
198 final boolean oldPlugged = oldPlugType != 0;
199
200 int oldBucket = findBatteryLevelBucket(oldBatteryLevel);
201 int bucket = findBatteryLevelBucket(mBatteryLevel);
202
Daniel Sandler71986622011-07-26 13:06:49 -0400203 if (DEBUG) {
Daniel Sandlerdea64622013-09-23 16:05:57 -0400204 Slog.d(TAG, "buckets ....." + mLowBatteryAlertCloseLevel
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700205 + " .. " + mLowBatteryReminderLevels[0]
206 + " .. " + mLowBatteryReminderLevels[1]);
Daniel Sandlerdea64622013-09-23 16:05:57 -0400207 Slog.d(TAG, "level " + oldBatteryLevel + " --> " + mBatteryLevel);
208 Slog.d(TAG, "status " + oldBatteryStatus + " --> " + mBatteryStatus);
209 Slog.d(TAG, "plugType " + oldPlugType + " --> " + mPlugType);
210 Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
211 Slog.d(TAG, "bucket " + oldBucket + " --> " + bucket);
212 Slog.d(TAG, "plugged " + oldPlugged + " --> " + plugged);
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700213 }
214
John Spurlocked452c52014-03-06 12:02:31 -0500215 mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700216 if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
Daniel Sandlerdea64622013-09-23 16:05:57 -0400217 Slog.d(TAG, "showing invalid charger warning");
John Spurlocked452c52014-03-06 12:02:31 -0500218 mWarnings.showInvalidChargerWarning();
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700219 return;
220 } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
John Spurlocked452c52014-03-06 12:02:31 -0500221 mWarnings.dismissInvalidChargerWarning();
222 } else if (mWarnings.isInvalidChargerWarningShowing()) {
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700223 // if invalid charger is showing, don't show low battery
224 return;
225 }
226
Jason Monk919a6802016-03-18 15:32:50 -0400227 boolean isPowerSaver = mPowerManager.isPowerSaveMode();
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700228 if (!plugged
Jason Monk919a6802016-03-18 15:32:50 -0400229 && !isPowerSaver
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700230 && (bucket < oldBucket || oldPlugged)
231 && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
232 && bucket < 0) {
Beverly334bc5f2017-07-31 10:37:17 -0400233
Daniel Sandler71986622011-07-26 13:06:49 -0400234 // only play SFX when the dialog comes up or the bucket changes
John Spurlocked452c52014-03-06 12:02:31 -0500235 final boolean playSound = bucket != oldBucket || oldPlugged;
236 mWarnings.showLowBatteryWarning(playSound);
Jason Monk919a6802016-03-18 15:32:50 -0400237 } else if (isPowerSaver || plugged || (bucket > oldBucket && bucket > 0)) {
John Spurlocked452c52014-03-06 12:02:31 -0500238 mWarnings.dismissLowBatteryWarning();
239 } else {
240 mWarnings.updateLowBatteryWarning();
Joe Onorato10523b4d2010-10-25 10:42:46 -0700241 }
Daniel Sandlerdea64622013-09-23 16:05:57 -0400242 } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
243 mScreenOffTime = SystemClock.elapsedRealtime();
244 } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
245 mScreenOffTime = -1;
John Spurlockecbc5e82014-10-22 09:05:51 -0400246 } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
247 mWarnings.userSwitched();
Joe Onorato10523b4d2010-10-25 10:42:46 -0700248 } else {
Daniel Sandlerdea64622013-09-23 16:05:57 -0400249 Slog.w(TAG, "unknown intent: " + intent);
Joe Onorato10523b4d2010-10-25 10:42:46 -0700250 }
251 }
252 };
253
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800254 private void initTemperatureWarning() {
Andrew Sappersteine3352562017-01-20 15:41:03 -0800255 ContentResolver resolver = mContext.getContentResolver();
256 Resources resources = mContext.getResources();
257 if (Settings.Global.getInt(resolver, Settings.Global.SHOW_TEMPERATURE_WARNING,
258 resources.getInteger(R.integer.config_showTemperatureWarning)) == 0) {
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800259 return;
260 }
261
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800262 mThresholdTemp = Settings.Global.getFloat(resolver, Settings.Global.WARNING_TEMPERATURE,
Andrew Sappersteine3352562017-01-20 15:41:03 -0800263 resources.getInteger(R.integer.config_warningTemperature));
Andrew Sapperstein75184712017-01-05 16:45:37 -0800264
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800265 if (mThresholdTemp < 0f) {
Andrew Sapperstein75184712017-01-05 16:45:37 -0800266 // Get the throttling temperature. No need to check if we're not throttling.
267 float[] throttlingTemps = mHardwarePropertiesManager.getDeviceTemperatures(
268 HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
Jason Monkd819c312017-08-11 12:53:36 -0400269 HardwarePropertiesManager.TEMPERATURE_SHUTDOWN);
Andrew Sapperstein75184712017-01-05 16:45:37 -0800270 if (throttlingTemps == null
271 || throttlingTemps.length == 0
272 || throttlingTemps[0] == HardwarePropertiesManager.UNDEFINED_TEMPERATURE) {
273 return;
274 }
Jason Monkd819c312017-08-11 12:53:36 -0400275 mThresholdTemp = throttlingTemps[0] -
276 resources.getInteger(R.integer.config_warningTemperatureTolerance);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800277 }
Adam Lesinski1aab3fa2017-07-31 13:42:00 -0700278
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800279 setNextLogTime();
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800280
Adam Lesinski1aab3fa2017-07-31 13:42:00 -0700281 // This initialization method may be called on a configuration change. Only one set of
282 // ongoing callbacks should be occurring, so remove any now. updateTemperatureWarning will
283 // schedule an ongoing callback.
284 mHandler.removeCallbacks(mUpdateTempCallback);
285
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800286 // We have passed all of the checks, start checking the temp
287 updateTemperatureWarning();
288 }
289
Salvador Martineza6f7b252017-04-10 10:46:15 -0700290 private void showThermalShutdownDialog() {
291 if (mPowerManager.getLastShutdownReason()
292 == PowerManager.SHUTDOWN_REASON_THERMAL_SHUTDOWN) {
293 mWarnings.showThermalShutdownWarning();
294 }
295 }
296
Jason Monkd819c312017-08-11 12:53:36 -0400297 @VisibleForTesting
298 protected void updateTemperatureWarning() {
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800299 float[] temps = mHardwarePropertiesManager.getDeviceTemperatures(
300 HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN,
301 HardwarePropertiesManager.TEMPERATURE_CURRENT);
302 if (temps.length != 0) {
303 float temp = temps[0];
304 mRecentTemps[mNumTemps++] = temp;
305
306 StatusBar statusBar = getComponent(StatusBar.class);
307 if (statusBar != null && !statusBar.isDeviceInVrMode()
308 && temp >= mThresholdTemp) {
309 logAtTemperatureThreshold(temp);
Salvador Martineza6f7b252017-04-10 10:46:15 -0700310 mWarnings.showHighTemperatureWarning();
Andrew Sapperstein65d8a5f2016-12-19 14:36:33 -0800311 } else {
Salvador Martineza6f7b252017-04-10 10:46:15 -0700312 mWarnings.dismissHighTemperatureWarning();
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800313 }
314 }
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800315
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800316 logTemperatureStats();
317
Adam Lesinski1aab3fa2017-07-31 13:42:00 -0700318 mHandler.postDelayed(mUpdateTempCallback, TEMPERATURE_INTERVAL);
Andrew Sappersteinb7caf1d2016-12-14 15:39:20 -0800319 }
320
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800321 private void logAtTemperatureThreshold(float temp) {
322 StringBuilder sb = new StringBuilder();
323 sb.append("currentTemp=").append(temp)
324 .append(",thresholdTemp=").append(mThresholdTemp)
325 .append(",batteryStatus=").append(mBatteryStatus)
326 .append(",recentTemps=");
327 for (int i = 0; i < mNumTemps; i++) {
328 sb.append(mRecentTemps[i]).append(',');
329 }
330 Slog.i(TAG, sb.toString());
331 }
332
333 /**
334 * Calculates and logs min, max, and average
335 * {@link HardwarePropertiesManager#DEVICE_TEMPERATURE_SKIN} over the past
336 * {@link #TEMPERATURE_LOGGING_INTERVAL}.
337 */
338 private void logTemperatureStats() {
339 if (mNextLogTime > System.currentTimeMillis() && mNumTemps != MAX_RECENT_TEMPS) {
340 return;
341 }
342
343 if (mNumTemps > 0) {
344 float sum = mRecentTemps[0], min = mRecentTemps[0], max = mRecentTemps[0];
345 for (int i = 1; i < mNumTemps; i++) {
346 float temp = mRecentTemps[i];
347 sum += temp;
348 if (temp > max) {
349 max = temp;
350 }
351 if (temp < min) {
352 min = temp;
353 }
354 }
355
356 float avg = sum / mNumTemps;
357 Slog.i(TAG, "avg=" + avg + ",min=" + min + ",max=" + max);
358 MetricsLogger.histogram(mContext, "device_skin_temp_avg", (int) avg);
359 MetricsLogger.histogram(mContext, "device_skin_temp_min", (int) min);
360 MetricsLogger.histogram(mContext, "device_skin_temp_max", (int) max);
361 }
362 setNextLogTime();
363 mNumTemps = 0;
364 }
365
366 private void setNextLogTime() {
367 mNextLogTime = System.currentTimeMillis() + TEMPERATURE_LOGGING_INTERVAL;
368 }
369
Joe Onorato10523b4d2010-10-25 10:42:46 -0700370 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700371 pw.print("mLowBatteryAlertCloseLevel=");
372 pw.println(mLowBatteryAlertCloseLevel);
373 pw.print("mLowBatteryReminderLevels=");
374 pw.println(Arrays.toString(mLowBatteryReminderLevels));
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700375 pw.print("mBatteryLevel=");
376 pw.println(Integer.toString(mBatteryLevel));
377 pw.print("mBatteryStatus=");
378 pw.println(Integer.toString(mBatteryStatus));
379 pw.print("mPlugType=");
380 pw.println(Integer.toString(mPlugType));
381 pw.print("mInvalidCharger=");
382 pw.println(Integer.toString(mInvalidCharger));
Daniel Sandlerdea64622013-09-23 16:05:57 -0400383 pw.print("mScreenOffTime=");
384 pw.print(mScreenOffTime);
385 if (mScreenOffTime >= 0) {
386 pw.print(" (");
387 pw.print(SystemClock.elapsedRealtime() - mScreenOffTime);
388 pw.print(" ago)");
389 }
390 pw.println();
391 pw.print("soundTimeout=");
392 pw.println(Settings.Global.getInt(mContext.getContentResolver(),
393 Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
Joe Onorato4ca7f1e2010-10-27 15:32:23 -0700394 pw.print("bucket: ");
395 pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
Andrew Sappersteina6ed7f82017-02-01 17:13:08 -0800396 pw.print("mThresholdTemp=");
397 pw.println(Float.toString(mThresholdTemp));
398 pw.print("mNextLogTime=");
399 pw.println(Long.toString(mNextLogTime));
John Spurlocked452c52014-03-06 12:02:31 -0500400 mWarnings.dump(pw);
401 }
402
403 public interface WarningsUI {
404 void update(int batteryLevel, int bucket, long screenOffTime);
405 void dismissLowBatteryWarning();
406 void showLowBatteryWarning(boolean playSound);
407 void dismissInvalidChargerWarning();
408 void showInvalidChargerWarning();
409 void updateLowBatteryWarning();
410 boolean isInvalidChargerWarningShowing();
Salvador Martineza6f7b252017-04-10 10:46:15 -0700411 void dismissHighTemperatureWarning();
412 void showHighTemperatureWarning();
413 void showThermalShutdownWarning();
John Spurlocked452c52014-03-06 12:02:31 -0500414 void dump(PrintWriter pw);
John Spurlockecbc5e82014-10-22 09:05:51 -0400415 void userSwitched();
Joe Onorato10523b4d2010-10-25 10:42:46 -0700416 }
Joe Onorato10523b4d2010-10-25 10:42:46 -0700417}
418