blob: b81d969a1bb243643b51220a41ba3b543d9dffbe [file] [log] [blame]
Jeff Brown96307042012-07-27 15:51:34 -07001/*
2 * Copyright (C) 2012 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.server.power;
18
Andrew Zeng6d07baf2018-04-20 14:13:16 -070019import android.annotation.Nullable;
Pavel Grafov28939982017-10-03 15:11:52 +010020import android.annotation.UserIdInt;
Jeff Brown13014b52014-04-07 19:45:27 -070021import android.app.ActivityManagerInternal;
Dianne Hackborn713df152013-05-17 11:27:57 -070022import android.app.AppOpsManager;
Pavel Grafov28939982017-10-03 15:11:52 +010023import android.app.trust.TrustManager;
Jeff Brown96307042012-07-27 15:51:34 -070024import android.content.BroadcastReceiver;
25import android.content.Context;
26import android.content.Intent;
Jeff Brown037c33e2014-04-09 00:31:55 -070027import android.hardware.input.InputManagerInternal;
Beverly69721d62018-05-09 17:41:44 -040028import android.media.AudioAttributes;
Jeff Brown84e27562012-12-07 13:56:34 -080029import android.media.AudioManager;
30import android.media.Ringtone;
31import android.media.RingtoneManager;
Alison Cichowlas5c38fc22017-01-25 17:11:06 -050032import android.metrics.LogMaker;
Jeff Brown84e27562012-12-07 13:56:34 -080033import android.net.Uri;
Jeff Brown96307042012-07-27 15:51:34 -070034import android.os.BatteryStats;
35import android.os.Handler;
36import android.os.Looper;
37import android.os.Message;
38import android.os.PowerManager;
Michael Wrighte3001042019-02-05 00:13:14 +000039import android.os.PowerManager.WakeReason;
Jeff Brownfbe96702014-11-19 18:30:58 -080040import android.os.PowerManagerInternal;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -080041import android.os.Process;
Jeff Brown96307042012-07-27 15:51:34 -070042import android.os.RemoteException;
43import android.os.SystemClock;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070044import android.os.UserHandle;
Beverly69721d62018-05-09 17:41:44 -040045import android.os.VibrationEffect;
46import android.os.Vibrator;
Jeff Brown96307042012-07-27 15:51:34 -070047import android.os.WorkSource;
Jeff Brown84e27562012-12-07 13:56:34 -080048import android.provider.Settings;
Jeff Brown96307042012-07-27 15:51:34 -070049import android.util.EventLog;
50import android.util.Slog;
Bookatzd888df22018-05-29 11:46:47 -070051import android.util.StatsLog;
Michael Wrighte3001042019-02-05 00:13:14 +000052import android.view.WindowManagerPolicyConstants.OnReason;
Jeff Brown96307042012-07-27 15:51:34 -070053
Santos Cordon64a6e612018-08-22 19:27:04 +010054import com.android.internal.annotations.VisibleForTesting;
Beverlyae79ab92017-12-11 09:20:02 -050055import com.android.internal.app.IBatteryStats;
56import com.android.internal.logging.MetricsLogger;
57import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
58import com.android.server.EventLogTags;
59import com.android.server.LocalServices;
Yohei Yukawac3de83e2018-08-28 16:09:34 -070060import com.android.server.inputmethod.InputMethodManagerInternal;
Beverlyae79ab92017-12-11 09:20:02 -050061import com.android.server.policy.WindowManagerPolicy;
Beverly69721d62018-05-09 17:41:44 -040062import com.android.server.statusbar.StatusBarManagerInternal;
Beverlyae79ab92017-12-11 09:20:02 -050063
Jeff Brown96307042012-07-27 15:51:34 -070064/**
65 * Sends broadcasts about important power state changes.
Jeff Brown54308352012-10-04 17:59:58 -070066 * <p>
Jeff Brown96307042012-07-27 15:51:34 -070067 * This methods of this class may be called by the power manager service while
68 * its lock is being held. Internally it takes care of sending broadcasts to
69 * notify other components of the system or applications asynchronously.
Jeff Brown54308352012-10-04 17:59:58 -070070 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070071 * The notifier is designed to collapse unnecessary broadcasts when it is not
72 * possible for the system to have observed an intermediate state.
Jeff Brown54308352012-10-04 17:59:58 -070073 * </p><p>
74 * For example, if the device wakes up, goes to sleep, wakes up again and goes to
75 * sleep again before the wake up notification is sent, then the system will
76 * be told about only one wake up and sleep. However, we always notify the
77 * fact that at least one transition occurred. It is especially important to
78 * tell the system when we go to sleep so that it can lock the keyguard if needed.
79 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070080 */
Santos Cordon64a6e612018-08-22 19:27:04 +010081@VisibleForTesting
82public class Notifier {
Jeff Brown96307042012-07-27 15:51:34 -070083 private static final String TAG = "PowerManagerNotifier";
84
85 private static final boolean DEBUG = false;
86
Jeff Brownfbe96702014-11-19 18:30:58 -080087 private static final int INTERACTIVE_STATE_UNKNOWN = 0;
88 private static final int INTERACTIVE_STATE_AWAKE = 1;
89 private static final int INTERACTIVE_STATE_ASLEEP = 2;
Jeff Brown96307042012-07-27 15:51:34 -070090
91 private static final int MSG_USER_ACTIVITY = 1;
92 private static final int MSG_BROADCAST = 2;
Jeff Brown84e27562012-12-07 13:56:34 -080093 private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
Bryce Lee84d6c0f2015-03-17 10:43:08 -070094 private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;
Pavel Grafov28939982017-10-03 15:11:52 +010095 private static final int MSG_PROFILE_TIMED_OUT = 5;
Beverlyc1313eb2018-01-31 18:07:21 -050096 private static final int MSG_WIRED_CHARGING_STARTED = 6;
Jeff Brown96307042012-07-27 15:51:34 -070097
Beverly69721d62018-05-09 17:41:44 -040098 private static final long[] WIRELESS_VIBRATION_TIME = {
99 40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms
100 40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms
101 };
102 private static final int[] WIRELESS_VIBRATION_AMPLITUDE = {
103 1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%)
104 103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude
105 };
106 private static final VibrationEffect WIRELESS_CHARGING_VIBRATION_EFFECT =
107 VibrationEffect.createWaveform(WIRELESS_VIBRATION_TIME, WIRELESS_VIBRATION_AMPLITUDE,
108 -1);
109 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
110 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
111 .build();
112
Jeff Brown96307042012-07-27 15:51:34 -0700113 private final Object mLock = new Object();
114
115 private final Context mContext;
116 private final IBatteryStats mBatteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800117 private final AppOpsManager mAppOps;
Jeff Brown96307042012-07-27 15:51:34 -0700118 private final SuspendBlocker mSuspendBlocker;
119 private final WindowManagerPolicy mPolicy;
Jeff Brown13014b52014-04-07 19:45:27 -0700120 private final ActivityManagerInternal mActivityManagerInternal;
Jeff Brown037c33e2014-04-09 00:31:55 -0700121 private final InputManagerInternal mInputManagerInternal;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700122 private final InputMethodManagerInternal mInputMethodManagerInternal;
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700123 @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal;
Pavel Grafov28939982017-10-03 15:11:52 +0100124 private final TrustManager mTrustManager;
Beverly69721d62018-05-09 17:41:44 -0400125 private final Vibrator mVibrator;
Jeff Brown96307042012-07-27 15:51:34 -0700126
127 private final NotifierHandler mHandler;
128 private final Intent mScreenOnIntent;
129 private final Intent mScreenOffIntent;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700130 private final Intent mScreenBrightnessBoostIntent;
Jeff Brown96307042012-07-27 15:51:34 -0700131
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700132 // True if the device should suspend when the screen is off due to proximity.
133 private final boolean mSuspendWhenScreenOffDueToProximityConfig;
134
Jeff Brown416c49c2015-05-26 19:50:18 -0700135 // The current interactive state. This is set as soon as an interactive state
136 // transition begins so as to capture the reason that it happened. At some point
137 // this state will propagate to the pending state then eventually to the
138 // broadcasted state over the course of reporting the transition asynchronously.
139 private boolean mInteractive = true;
140 private int mInteractiveChangeReason;
Michael Wrighte3001042019-02-05 00:13:14 +0000141 private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
Jeff Brown416c49c2015-05-26 19:50:18 -0700142 private boolean mInteractiveChanging;
Jeff Brown96307042012-07-27 15:51:34 -0700143
Jeff Brown416c49c2015-05-26 19:50:18 -0700144 // The pending interactive state that we will eventually want to broadcast.
145 // This is designed so that we can collapse redundant sequences of awake/sleep
146 // transition pairs while still guaranteeing that at least one transition is observed
147 // whenever this happens.
148 private int mPendingInteractiveState;
Jeff Brown54308352012-10-04 17:59:58 -0700149 private boolean mPendingWakeUpBroadcast;
150 private boolean mPendingGoToSleepBroadcast;
151
Jeff Brownfbe96702014-11-19 18:30:58 -0800152 // The currently broadcasted interactive state. This reflects what other parts of the
Jeff Brown96307042012-07-27 15:51:34 -0700153 // system have observed.
Jeff Brownfbe96702014-11-19 18:30:58 -0800154 private int mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700155 private boolean mBroadcastInProgress;
156 private long mBroadcastStartTime;
157
158 // True if a user activity message should be sent.
159 private boolean mUserActivityPending;
160
161 public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
Svet Ganovf7b47252018-02-26 11:11:27 -0800162 SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
Jeff Brown96307042012-07-27 15:51:34 -0700163 mContext = context;
164 mBatteryStats = batteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800165 mAppOps = mContext.getSystemService(AppOpsManager.class);
Jeff Brown96307042012-07-27 15:51:34 -0700166 mSuspendBlocker = suspendBlocker;
167 mPolicy = policy;
Jeff Brown13014b52014-04-07 19:45:27 -0700168 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700169 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700170 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
Beverlyae79ab92017-12-11 09:20:02 -0500171 mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
Pavel Grafov28939982017-10-03 15:11:52 +0100172 mTrustManager = mContext.getSystemService(TrustManager.class);
Beverly69721d62018-05-09 17:41:44 -0400173 mVibrator = mContext.getSystemService(Vibrator.class);
Jeff Brown96307042012-07-27 15:51:34 -0700174
175 mHandler = new NotifierHandler(looper);
176 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
177 mScreenOnIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700178 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
179 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Jeff Brown96307042012-07-27 15:51:34 -0700180 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
181 mScreenOffIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700182 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
183 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700184 mScreenBrightnessBoostIntent =
185 new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
186 mScreenBrightnessBoostIntent.addFlags(
187 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700188
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700189 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
190 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
191
Jeff Browne95c3cd2014-05-02 16:59:26 -0700192 // Initialize interactive state for battery stats.
193 try {
194 mBatteryStats.noteInteractive(true);
195 } catch (RemoteException ex) { }
Bookatza66083f2018-09-20 17:24:00 -0700196 StatsLog.write(StatsLog.INTERACTIVE_STATE_CHANGED,
197 StatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON);
Jeff Brown96307042012-07-27 15:51:34 -0700198 }
199
200 /**
201 * Called when a wake lock is acquired.
202 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700203 public void onWakeLockAcquired(int flags, String tag, String packageName,
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800204 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700205 if (DEBUG) {
206 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700207 + "\", packageName=" + packageName
208 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700209 + ", workSource=" + workSource);
210 }
211
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700212 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
213 if (monitorType >= 0) {
214 try {
215 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
216 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
217 if (workSource != null) {
218 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
219 historyTag, monitorType, unimportantForLogging);
220 } else {
221 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
222 monitorType, unimportantForLogging);
223 // XXX need to deal with disabled operations.
Svet Ganovf7b47252018-02-26 11:11:27 -0800224 mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700225 }
226 } catch (RemoteException ex) {
227 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700228 }
229 }
230 }
231
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700232 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
233 String historyTag) {
234 if (DEBUG) {
235 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid
236 + ", workSource=" + workSource);
237 }
238
239 try {
240 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000241 mBatteryStats.noteLongPartialWakelockStartFromSource(tag, historyTag, workSource);
Bookatzd888df22018-05-29 11:46:47 -0700242 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, workSource,
243 tag, historyTag, StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700244 } else {
245 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid);
Bookatzd888df22018-05-29 11:46:47 -0700246 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
247 ownerUid, null, tag, historyTag,
248 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700249 }
250 } catch (RemoteException ex) {
251 // Ignore
252 }
253 }
254
255 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource,
256 String historyTag) {
257 if (DEBUG) {
258 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid
259 + ", workSource=" + workSource);
260 }
261
262 try {
263 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000264 mBatteryStats.noteLongPartialWakelockFinishFromSource(tag, historyTag, workSource);
Bookatzd888df22018-05-29 11:46:47 -0700265 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, workSource,
266 tag, historyTag, StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700267 } else {
268 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid);
Bookatzd888df22018-05-29 11:46:47 -0700269 StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
270 ownerUid, null, tag, historyTag,
271 StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700272 }
273 } catch (RemoteException ex) {
274 // Ignore
275 }
276 }
277
Jeff Brown96307042012-07-27 15:51:34 -0700278 /**
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800279 * Called when a wake lock is changing.
280 */
281 public void onWakeLockChanging(int flags, String tag, String packageName,
282 int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
283 int newFlags, String newTag, String newPackageName, int newOwnerUid,
284 int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
285
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700286 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
287 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
288 if (workSource != null && newWorkSource != null
289 && monitorType >= 0 && newMonitorType >= 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800290 if (DEBUG) {
291 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
292 + "\", packageName=" + newPackageName
293 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
294 + ", workSource=" + newWorkSource);
295 }
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700296
297 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
298 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800299 try {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700300 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
301 monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800302 newMonitorType, unimportantForLogging);
303 } catch (RemoteException ex) {
304 // Ignore
305 }
306 } else {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700307 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800308 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
309 newWorkSource, newHistoryTag);
310 }
311 }
312
313 /**
Jeff Brown96307042012-07-27 15:51:34 -0700314 * Called when a wake lock is released.
315 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700316 public void onWakeLockReleased(int flags, String tag, String packageName,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700317 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700318 if (DEBUG) {
319 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700320 + "\", packageName=" + packageName
321 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700322 + ", workSource=" + workSource);
323 }
324
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700325 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
326 if (monitorType >= 0) {
327 try {
328 if (workSource != null) {
329 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
330 historyTag, monitorType);
331 } else {
332 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
333 historyTag, monitorType);
Svet Ganovf7b47252018-02-26 11:11:27 -0800334 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700335 }
336 } catch (RemoteException ex) {
337 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700338 }
339 }
340 }
341
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700342 private int getBatteryStatsWakeLockMonitorType(int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700343 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
344 case PowerManager.PARTIAL_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700345 return BatteryStats.WAKE_TYPE_PARTIAL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700346
347 case PowerManager.SCREEN_DIM_WAKE_LOCK:
348 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700349 return BatteryStats.WAKE_TYPE_FULL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700350
351 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
352 if (mSuspendWhenScreenOffDueToProximityConfig) {
353 return -1;
354 }
355 return BatteryStats.WAKE_TYPE_PARTIAL;
356
357 case PowerManager.DRAW_WAKE_LOCK:
358 return BatteryStats.WAKE_TYPE_DRAW;
359
360 case PowerManager.DOZE_WAKE_LOCK:
361 // Doze wake locks are an internal implementation detail of the
362 // communication between dream manager service and power manager
363 // service. They have no additive battery impact.
364 return -1;
365
366 default:
367 return -1;
Jeff Brown96307042012-07-27 15:51:34 -0700368 }
369 }
370
371 /**
Jeff Brownfbe96702014-11-19 18:30:58 -0800372 * Notifies that the device is changing wakefulness.
Jeff Brown416c49c2015-05-26 19:50:18 -0700373 * This function may be called even if the previous change hasn't finished in
374 * which case it will assume that the state did not fully converge before the
375 * next transition began and will recover accordingly.
Jeff Brown96307042012-07-27 15:51:34 -0700376 */
Michael Wrighte3001042019-02-05 00:13:14 +0000377 public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
Jeff Brown416c49c2015-05-26 19:50:18 -0700378 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
Jeff Brown96307042012-07-27 15:51:34 -0700379 if (DEBUG) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800380 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
Jeff Brown416c49c2015-05-26 19:50:18 -0700381 + ", reason=" + reason + ", interactive=" + interactive);
Jeff Brown96307042012-07-27 15:51:34 -0700382 }
383
Jeff Brownfbe96702014-11-19 18:30:58 -0800384 // Tell the activity manager about changes in wakefulness, not just interactivity.
385 // It needs more granularity than other components.
386 mHandler.post(new Runnable() {
387 @Override
388 public void run() {
389 mActivityManagerInternal.onWakefulnessChanged(wakefulness);
390 }
391 });
392
Jeff Brown416c49c2015-05-26 19:50:18 -0700393 // Handle any early interactive state changes.
394 // Finish pending incomplete ones from a previous cycle.
395 if (mInteractive != interactive) {
396 // Finish up late behaviors if needed.
397 if (mInteractiveChanging) {
398 handleLateInteractiveChange();
Jeff Brown96307042012-07-27 15:51:34 -0700399 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700400
Jeff Brown416c49c2015-05-26 19:50:18 -0700401 // Start input as soon as we start waking up or going to sleep.
402 mInputManagerInternal.setInteractive(interactive);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700403 mInputMethodManagerInternal.setInteractive(interactive);
Jeff Brown416c49c2015-05-26 19:50:18 -0700404
405 // Notify battery stats.
Jeff Browne95c3cd2014-05-02 16:59:26 -0700406 try {
Jeff Brownfbe96702014-11-19 18:30:58 -0800407 mBatteryStats.noteInteractive(interactive);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700408 } catch (RemoteException ex) { }
Bookatza66083f2018-09-20 17:24:00 -0700409 StatsLog.write(StatsLog.INTERACTIVE_STATE_CHANGED,
410 interactive ? StatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON :
411 StatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
Jeff Brown416c49c2015-05-26 19:50:18 -0700412
413 // Handle early behaviors.
414 mInteractive = interactive;
415 mInteractiveChangeReason = reason;
Michael Wrighte3001042019-02-05 00:13:14 +0000416 mInteractiveChangeStartTime = eventTime;
Jeff Brown416c49c2015-05-26 19:50:18 -0700417 mInteractiveChanging = true;
418 handleEarlyInteractiveChange();
419 }
420 }
421
422 /**
423 * Notifies that the device has finished changing wakefulness.
424 */
425 public void onWakefulnessChangeFinished() {
426 if (DEBUG) {
427 Slog.d(TAG, "onWakefulnessChangeFinished");
428 }
429
430 if (mInteractiveChanging) {
431 mInteractiveChanging = false;
432 handleLateInteractiveChange();
433 }
434 }
435
436 /**
437 * Handle early interactive state changes such as getting applications or the lock
438 * screen running and ready for the user to see (such as when turning on the screen).
439 */
440 private void handleEarlyInteractiveChange() {
441 synchronized (mLock) {
442 if (mInteractive) {
443 // Waking up...
444 mHandler.post(new Runnable() {
445 @Override
446 public void run() {
Michael Wrighte3001042019-02-05 00:13:14 +0000447 final int why = translateOnReason(mInteractiveChangeReason);
448 mPolicy.startedWakingUp(why);
Jeff Brown416c49c2015-05-26 19:50:18 -0700449 }
450 });
451
452 // Send interactive broadcast.
453 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
454 mPendingWakeUpBroadcast = true;
455 updatePendingBroadcastLocked();
456 } else {
457 // Going to sleep...
458 // Tell the policy that we started going to sleep.
459 final int why = translateOffReason(mInteractiveChangeReason);
460 mHandler.post(new Runnable() {
461 @Override
462 public void run() {
463 mPolicy.startedGoingToSleep(why);
464 }
465 });
466 }
467 }
468 }
469
470 /**
471 * Handle late interactive state changes once they are finished so that the system can
472 * finish pending transitions (such as turning the screen off) before causing
473 * applications to change state visibly.
474 */
475 private void handleLateInteractiveChange() {
476 synchronized (mLock) {
Michael Wrighte3001042019-02-05 00:13:14 +0000477 final int interactiveChangeLatency =
478 (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
Jeff Brown416c49c2015-05-26 19:50:18 -0700479 if (mInteractive) {
480 // Finished waking up...
Michael Wrighte3001042019-02-05 00:13:14 +0000481 final int why = translateOnReason(mInteractiveChangeReason);
Jeff Brown416c49c2015-05-26 19:50:18 -0700482 mHandler.post(new Runnable() {
483 @Override
484 public void run() {
Michael Wrighte3001042019-02-05 00:13:14 +0000485 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
486 log.setType(MetricsEvent.TYPE_OPEN);
487 log.setSubtype(why);
488 log.setLatency(interactiveChangeLatency);
Steven Wu0e6e5de2019-03-12 17:13:14 -0400489 log.addTaggedData(
490 MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason);
Michael Wrighte3001042019-02-05 00:13:14 +0000491 MetricsLogger.action(log);
492 EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
493 mPolicy.finishedWakingUp(why);
Jeff Brown416c49c2015-05-26 19:50:18 -0700494 }
495 });
496 } else {
497 // Finished going to sleep...
498 // This is a good time to make transitions that we don't want the user to see,
499 // such as bringing the key guard to focus. There's no guarantee for this
500 // however because the user could turn the device on again at any time.
501 // Some things may need to be protected by other mechanisms that defer screen on.
502
503 // Cancel pending user activity.
504 if (mUserActivityPending) {
505 mUserActivityPending = false;
506 mHandler.removeMessages(MSG_USER_ACTIVITY);
507 }
508
509 // Tell the policy we finished going to sleep.
510 final int why = translateOffReason(mInteractiveChangeReason);
511 mHandler.post(new Runnable() {
512 @Override
513 public void run() {
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500514 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
515 log.setType(MetricsEvent.TYPE_CLOSE);
516 log.setSubtype(why);
Michael Wrighte3001042019-02-05 00:13:14 +0000517 log.setLatency(interactiveChangeLatency);
Steven Wu0e6e5de2019-03-12 17:13:14 -0400518 log.addTaggedData(
519 MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason);
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500520 MetricsLogger.action(log);
Michael Wrighte3001042019-02-05 00:13:14 +0000521 EventLogTags.writePowerScreenState(0, why, 0, 0, interactiveChangeLatency);
Jeff Brown416c49c2015-05-26 19:50:18 -0700522 mPolicy.finishedGoingToSleep(why);
523 }
524 });
525
526 // Send non-interactive broadcast.
527 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
528 mPendingGoToSleepBroadcast = true;
529 updatePendingBroadcastLocked();
530 }
531 }
532 }
533
534 private static int translateOffReason(int reason) {
535 switch (reason) {
536 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
537 return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
538 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
539 return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
540 default:
541 return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
Jeff Browne95c3cd2014-05-02 16:59:26 -0700542 }
Jeff Brown96307042012-07-27 15:51:34 -0700543 }
544
Michael Wrighte3001042019-02-05 00:13:14 +0000545 private static @OnReason int translateOnReason(@WakeReason int reason) {
546 switch (reason) {
547 case PowerManager.WAKE_REASON_POWER_BUTTON:
548 case PowerManager.WAKE_REASON_PLUGGED_IN:
549 case PowerManager.WAKE_REASON_GESTURE:
550 case PowerManager.WAKE_REASON_CAMERA_LAUNCH:
551 case PowerManager.WAKE_REASON_WAKE_KEY:
552 case PowerManager.WAKE_REASON_WAKE_MOTION:
553 case PowerManager.WAKE_REASON_LID:
554 return WindowManagerPolicy.ON_BECAUSE_OF_USER;
555 case PowerManager.WAKE_REASON_APPLICATION:
556 return WindowManagerPolicy.ON_BECAUSE_OF_APPLICATION;
557 default:
558 return WindowManagerPolicy.ON_BECAUSE_OF_UNKNOWN;
559 }
560 }
561
Jeff Brown96307042012-07-27 15:51:34 -0700562 /**
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700563 * Called when screen brightness boost begins or ends.
564 */
565 public void onScreenBrightnessBoostChanged() {
566 if (DEBUG) {
567 Slog.d(TAG, "onScreenBrightnessBoostChanged");
568 }
569
570 mSuspendBlocker.acquire();
571 Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
572 msg.setAsynchronous(true);
573 mHandler.sendMessage(msg);
574 }
Jeff Brown416c49c2015-05-26 19:50:18 -0700575
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700576 /**
Jeff Brown96307042012-07-27 15:51:34 -0700577 * Called when there has been user activity.
578 */
579 public void onUserActivity(int event, int uid) {
580 if (DEBUG) {
581 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
582 }
583
584 try {
585 mBatteryStats.noteUserActivity(uid, event);
586 } catch (RemoteException ex) {
587 // Ignore
588 }
589
590 synchronized (mLock) {
591 if (!mUserActivityPending) {
592 mUserActivityPending = true;
593 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
594 msg.setAsynchronous(true);
595 mHandler.sendMessage(msg);
596 }
597 }
598 }
599
Jeff Brown84e27562012-12-07 13:56:34 -0800600 /**
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700601 * Called when the screen has turned on.
602 */
Michael Wrighte3001042019-02-05 00:13:14 +0000603 public void onWakeUp(int reason, String details, int reasonUid, String opPackageName,
604 int opUid) {
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700605 if (DEBUG) {
Michael Wrighte3001042019-02-05 00:13:14 +0000606 Slog.d(TAG, "onWakeUp: reason=" + PowerManager.wakeReasonToString(reason)
607 + ", details=" + details + ", reasonUid=" + reasonUid
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700608 + " opPackageName=" + opPackageName + " opUid=" + opUid);
609 }
610
611 try {
Michael Wrighte3001042019-02-05 00:13:14 +0000612 mBatteryStats.noteWakeUp(details, reasonUid);
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700613 if (opPackageName != null) {
Svet Ganovf7b47252018-02-26 11:11:27 -0800614 mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700615 }
616 } catch (RemoteException ex) {
617 // Ignore
618 }
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700619 }
620
621 /**
Beverlyae79ab92017-12-11 09:20:02 -0500622 * Called when profile screen lock timeout has expired.
Jeff Brown84e27562012-12-07 13:56:34 -0800623 */
Beverlyae79ab92017-12-11 09:20:02 -0500624 public void onProfileTimeout(@UserIdInt int userId) {
625 final Message msg = mHandler.obtainMessage(MSG_PROFILE_TIMED_OUT);
626 msg.setAsynchronous(true);
627 msg.arg1 = userId;
628 mHandler.sendMessage(msg);
629 }
630
631 /**
Beverly91d0a632018-07-02 16:45:00 -0400632 * Called when wireless charging has started - to provide user feedback (sound and visual).
Beverlyae79ab92017-12-11 09:20:02 -0500633 */
Beverly91d0a632018-07-02 16:45:00 -0400634 public void onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
Jeff Brown84e27562012-12-07 13:56:34 -0800635 if (DEBUG) {
636 Slog.d(TAG, "onWirelessChargingStarted");
637 }
638
639 mSuspendBlocker.acquire();
640 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
641 msg.setAsynchronous(true);
Beverlyae79ab92017-12-11 09:20:02 -0500642 msg.arg1 = batteryLevel;
Beverly91d0a632018-07-02 16:45:00 -0400643 msg.arg2 = userId;
Pavel Grafov28939982017-10-03 15:11:52 +0100644 mHandler.sendMessage(msg);
645 }
646
Beverlyc1313eb2018-01-31 18:07:21 -0500647 /**
Beverly91d0a632018-07-02 16:45:00 -0400648 * Called when wired charging has started - to provide user feedback
Beverlyc1313eb2018-01-31 18:07:21 -0500649 */
Beverly91d0a632018-07-02 16:45:00 -0400650 public void onWiredChargingStarted(@UserIdInt int userId) {
Beverlyc1313eb2018-01-31 18:07:21 -0500651 if (DEBUG) {
652 Slog.d(TAG, "onWiredChargingStarted");
653 }
654
655 mSuspendBlocker.acquire();
656 Message msg = mHandler.obtainMessage(MSG_WIRED_CHARGING_STARTED);
657 msg.setAsynchronous(true);
Beverly91d0a632018-07-02 16:45:00 -0400658 msg.arg1 = userId;
Beverlyc1313eb2018-01-31 18:07:21 -0500659 mHandler.sendMessage(msg);
660 }
661
Jeff Brown96307042012-07-27 15:51:34 -0700662 private void updatePendingBroadcastLocked() {
663 if (!mBroadcastInProgress
Jeff Brown416c49c2015-05-26 19:50:18 -0700664 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
Jeff Brown54308352012-10-04 17:59:58 -0700665 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700666 || mPendingInteractiveState != mBroadcastedInteractiveState)) {
Jeff Brown96307042012-07-27 15:51:34 -0700667 mBroadcastInProgress = true;
668 mSuspendBlocker.acquire();
669 Message msg = mHandler.obtainMessage(MSG_BROADCAST);
670 msg.setAsynchronous(true);
671 mHandler.sendMessage(msg);
672 }
673 }
674
Jeff Brown54308352012-10-04 17:59:58 -0700675 private void finishPendingBroadcastLocked() {
676 mBroadcastInProgress = false;
677 mSuspendBlocker.release();
678 }
679
Jeff Brown96307042012-07-27 15:51:34 -0700680 private void sendUserActivity() {
681 synchronized (mLock) {
682 if (!mUserActivityPending) {
683 return;
684 }
685 mUserActivityPending = false;
686 }
Jeff Brown96307042012-07-27 15:51:34 -0700687 mPolicy.userActivity();
688 }
689
690 private void sendNextBroadcast() {
691 final int powerState;
Jeff Brown96307042012-07-27 15:51:34 -0700692 synchronized (mLock) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800693 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
Jeff Brown54308352012-10-04 17:59:58 -0700694 // Broadcasted power state is unknown. Send wake up.
695 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800696 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
697 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700698 // Broadcasted power state is awake. Send asleep if needed.
699 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700700 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
Jeff Brown54308352012-10-04 17:59:58 -0700701 mPendingGoToSleepBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800702 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
Jeff Brown54308352012-10-04 17:59:58 -0700703 } else {
704 finishPendingBroadcastLocked();
705 return;
706 }
707 } else {
708 // Broadcasted power state is asleep. Send awake if needed.
709 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700710 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700711 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800712 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
Jeff Brown54308352012-10-04 17:59:58 -0700713 } else {
714 finishPendingBroadcastLocked();
715 return;
716 }
Jeff Brown96307042012-07-27 15:51:34 -0700717 }
718
Jeff Brown96307042012-07-27 15:51:34 -0700719 mBroadcastStartTime = SystemClock.uptimeMillis();
Jeff Brownfbe96702014-11-19 18:30:58 -0800720 powerState = mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700721 }
722
723 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
724
Jeff Brownfbe96702014-11-19 18:30:58 -0800725 if (powerState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown96307042012-07-27 15:51:34 -0700726 sendWakeUpBroadcast();
727 } else {
Jim Millerc522d162014-07-01 17:10:21 -0700728 sendGoToSleepBroadcast();
Jeff Brown96307042012-07-27 15:51:34 -0700729 }
730 }
731
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700732 private void sendBrightnessBoostChangedBroadcast() {
733 if (DEBUG) {
734 Slog.d(TAG, "Sending brightness boost changed broadcast.");
735 }
736
737 mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
738 mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
739 }
740
741 private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
742 @Override
743 public void onReceive(Context context, Intent intent) {
744 mSuspendBlocker.release();
745 }
746 };
747
Jeff Brown96307042012-07-27 15:51:34 -0700748 private void sendWakeUpBroadcast() {
749 if (DEBUG) {
750 Slog.d(TAG, "Sending wake up broadcast.");
751 }
752
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700753 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700754 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700755 mWakeUpBroadcastDone, mHandler, 0, null, null);
756 } else {
757 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
758 sendNextBroadcast();
759 }
760 }
761
762 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
763 @Override
764 public void onReceive(Context context, Intent intent) {
765 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
766 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
767 sendNextBroadcast();
768 }
769 };
770
Jim Millerc522d162014-07-01 17:10:21 -0700771 private void sendGoToSleepBroadcast() {
Jeff Brown96307042012-07-27 15:51:34 -0700772 if (DEBUG) {
773 Slog.d(TAG, "Sending go to sleep broadcast.");
774 }
775
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700776 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700777 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700778 mGoToSleepBroadcastDone, mHandler, 0, null, null);
779 } else {
780 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
781 sendNextBroadcast();
782 }
783 }
784
785 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
786 @Override
787 public void onReceive(Context context, Intent intent) {
788 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
789 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
790 sendNextBroadcast();
791 }
792 };
793
Beverlyc1313eb2018-01-31 18:07:21 -0500794 /**
Beverlye21f4dd2019-01-03 10:02:58 -0500795 * If enabled, plays a sound and/or vibration when wireless or non-wireless charging has started
Beverlyc1313eb2018-01-31 18:07:21 -0500796 */
Beverlye21f4dd2019-01-03 10:02:58 -0500797 private void playChargingStartedFeedback(@UserIdInt int userId) {
798 playChargingStartedVibration(userId);
Jeff Brown84e27562012-12-07 13:56:34 -0800799 final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
Beverlyc1313eb2018-01-31 18:07:21 -0500800 Settings.Global.CHARGING_STARTED_SOUND);
Beverly91d0a632018-07-02 16:45:00 -0400801 if (isChargingFeedbackEnabled(userId) && soundPath != null) {
Jeff Brown84e27562012-12-07 13:56:34 -0800802 final Uri soundUri = Uri.parse("file://" + soundPath);
803 if (soundUri != null) {
804 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
805 if (sfx != null) {
806 sfx.setStreamType(AudioManager.STREAM_SYSTEM);
807 sfx.play();
808 }
809 }
810 }
Beverlyae79ab92017-12-11 09:20:02 -0500811 }
Jeff Brown84e27562012-12-07 13:56:34 -0800812
Beverly91d0a632018-07-02 16:45:00 -0400813 private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
Beverlye21f4dd2019-01-03 10:02:58 -0500814 playChargingStartedFeedback(userId);
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700815 if (mStatusBarManagerInternal != null) {
816 mStatusBarManagerInternal.showChargingAnimation(batteryLevel);
817 }
Jeff Brown84e27562012-12-07 13:56:34 -0800818 mSuspendBlocker.release();
819 }
820
Beverly91d0a632018-07-02 16:45:00 -0400821 private void showWiredChargingStarted(@UserIdInt int userId) {
Beverlye21f4dd2019-01-03 10:02:58 -0500822 playChargingStartedFeedback(userId);
Beverlyc1313eb2018-01-31 18:07:21 -0500823 mSuspendBlocker.release();
824 }
825
Pavel Grafov28939982017-10-03 15:11:52 +0100826 private void lockProfile(@UserIdInt int userId) {
827 mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
828 }
829
Beverlye21f4dd2019-01-03 10:02:58 -0500830 private void playChargingStartedVibration(@UserIdInt int userId) {
Beverly91d0a632018-07-02 16:45:00 -0400831 final boolean vibrateEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
832 Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
833 if (vibrateEnabled && isChargingFeedbackEnabled(userId)) {
Beverly69721d62018-05-09 17:41:44 -0400834 mVibrator.vibrate(WIRELESS_CHARGING_VIBRATION_EFFECT, VIBRATION_ATTRIBUTES);
835 }
836 }
837
Beverly91d0a632018-07-02 16:45:00 -0400838 private boolean isChargingFeedbackEnabled(@UserIdInt int userId) {
839 final boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
840 Settings.Secure.CHARGING_SOUNDS_ENABLED, 1, userId) != 0;
Beverly69721d62018-05-09 17:41:44 -0400841 final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
842 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
843 == Settings.Global.ZEN_MODE_OFF;
844 return enabled && dndOff;
845 }
846
Jeff Brown96307042012-07-27 15:51:34 -0700847 private final class NotifierHandler extends Handler {
Pavel Grafov28939982017-10-03 15:11:52 +0100848
Jeff Brown96307042012-07-27 15:51:34 -0700849 public NotifierHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700850 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -0700851 }
Jeff Brown96307042012-07-27 15:51:34 -0700852 @Override
853 public void handleMessage(Message msg) {
854 switch (msg.what) {
855 case MSG_USER_ACTIVITY:
856 sendUserActivity();
857 break;
Jeff Brown96307042012-07-27 15:51:34 -0700858 case MSG_BROADCAST:
859 sendNextBroadcast();
860 break;
Jeff Brown84e27562012-12-07 13:56:34 -0800861 case MSG_WIRELESS_CHARGING_STARTED:
Beverly91d0a632018-07-02 16:45:00 -0400862 showWirelessChargingStarted(msg.arg1, msg.arg2);
Jeff Brown84e27562012-12-07 13:56:34 -0800863 break;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700864 case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
865 sendBrightnessBoostChangedBroadcast();
866 break;
Pavel Grafov28939982017-10-03 15:11:52 +0100867 case MSG_PROFILE_TIMED_OUT:
868 lockProfile(msg.arg1);
869 break;
Beverlyc1313eb2018-01-31 18:07:21 -0500870 case MSG_WIRED_CHARGING_STARTED:
Beverly91d0a632018-07-02 16:45:00 -0400871 showWiredChargingStarted(msg.arg1);
Beverly69721d62018-05-09 17:41:44 -0400872 break;
Jeff Brown96307042012-07-27 15:51:34 -0700873 }
874 }
875 }
876}