blob: 0b95be15f1575289260bbc3b4d425b1b211e7ea0 [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;
Peter Wang6a92dd42020-01-15 14:11:25 -080049import android.telephony.TelephonyManager;
Jeff Brown96307042012-07-27 15:51:34 -070050import android.util.EventLog;
51import android.util.Slog;
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;
Muhammad Qureshi41166302020-01-28 10:23:36 -080058import com.android.internal.util.FrameworkStatsLog;
Beverlyae79ab92017-12-11 09:20:02 -050059import com.android.server.EventLogTags;
60import com.android.server.LocalServices;
Yohei Yukawac3de83e2018-08-28 16:09:34 -070061import com.android.server.inputmethod.InputMethodManagerInternal;
Beverlyae79ab92017-12-11 09:20:02 -050062import com.android.server.policy.WindowManagerPolicy;
Beverly69721d62018-05-09 17:41:44 -040063import com.android.server.statusbar.StatusBarManagerInternal;
Beverlyae79ab92017-12-11 09:20:02 -050064
Santos Cordon9204cc82019-11-21 11:45:28 +000065import java.io.PrintWriter;
66
Jeff Brown96307042012-07-27 15:51:34 -070067/**
68 * Sends broadcasts about important power state changes.
Jeff Brown54308352012-10-04 17:59:58 -070069 * <p>
Jeff Brown96307042012-07-27 15:51:34 -070070 * This methods of this class may be called by the power manager service while
71 * its lock is being held. Internally it takes care of sending broadcasts to
72 * notify other components of the system or applications asynchronously.
Jeff Brown54308352012-10-04 17:59:58 -070073 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070074 * The notifier is designed to collapse unnecessary broadcasts when it is not
75 * possible for the system to have observed an intermediate state.
Jeff Brown54308352012-10-04 17:59:58 -070076 * </p><p>
77 * For example, if the device wakes up, goes to sleep, wakes up again and goes to
78 * sleep again before the wake up notification is sent, then the system will
79 * be told about only one wake up and sleep. However, we always notify the
80 * fact that at least one transition occurred. It is especially important to
81 * tell the system when we go to sleep so that it can lock the keyguard if needed.
82 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070083 */
Santos Cordon64a6e612018-08-22 19:27:04 +010084@VisibleForTesting
85public class Notifier {
Jeff Brown96307042012-07-27 15:51:34 -070086 private static final String TAG = "PowerManagerNotifier";
87
88 private static final boolean DEBUG = false;
89
Jeff Brownfbe96702014-11-19 18:30:58 -080090 private static final int INTERACTIVE_STATE_UNKNOWN = 0;
91 private static final int INTERACTIVE_STATE_AWAKE = 1;
92 private static final int INTERACTIVE_STATE_ASLEEP = 2;
Jeff Brown96307042012-07-27 15:51:34 -070093
94 private static final int MSG_USER_ACTIVITY = 1;
95 private static final int MSG_BROADCAST = 2;
Jeff Brown84e27562012-12-07 13:56:34 -080096 private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
Pavel Grafov28939982017-10-03 15:11:52 +010097 private static final int MSG_PROFILE_TIMED_OUT = 5;
Beverlyc1313eb2018-01-31 18:07:21 -050098 private static final int MSG_WIRED_CHARGING_STARTED = 6;
Jeff Brown96307042012-07-27 15:51:34 -070099
Beverlyf364d7c2019-10-10 16:44:43 -0400100 private static final long[] CHARGING_VIBRATION_TIME = {
Beverly69721d62018-05-09 17:41:44 -0400101 40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms
102 40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms
103 };
Beverlyf364d7c2019-10-10 16:44:43 -0400104 private static final int[] CHARGING_VIBRATION_AMPLITUDE = {
Beverly69721d62018-05-09 17:41:44 -0400105 1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%)
106 103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude
107 };
Beverlyf364d7c2019-10-10 16:44:43 -0400108 private static final VibrationEffect CHARGING_VIBRATION_EFFECT =
109 VibrationEffect.createWaveform(CHARGING_VIBRATION_TIME, CHARGING_VIBRATION_AMPLITUDE,
Beverly69721d62018-05-09 17:41:44 -0400110 -1);
111 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
112 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
113 .build();
114
Jeff Brown96307042012-07-27 15:51:34 -0700115 private final Object mLock = new Object();
116
117 private final Context mContext;
118 private final IBatteryStats mBatteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800119 private final AppOpsManager mAppOps;
Jeff Brown96307042012-07-27 15:51:34 -0700120 private final SuspendBlocker mSuspendBlocker;
121 private final WindowManagerPolicy mPolicy;
Jeff Brown13014b52014-04-07 19:45:27 -0700122 private final ActivityManagerInternal mActivityManagerInternal;
Jeff Brown037c33e2014-04-09 00:31:55 -0700123 private final InputManagerInternal mInputManagerInternal;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700124 private final InputMethodManagerInternal mInputMethodManagerInternal;
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700125 @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal;
Pavel Grafov28939982017-10-03 15:11:52 +0100126 private final TrustManager mTrustManager;
Beverly69721d62018-05-09 17:41:44 -0400127 private final Vibrator mVibrator;
Santos Cordon9204cc82019-11-21 11:45:28 +0000128 private final WakeLockLog mWakeLockLog;
Jeff Brown96307042012-07-27 15:51:34 -0700129
130 private final NotifierHandler mHandler;
131 private final Intent mScreenOnIntent;
132 private final Intent mScreenOffIntent;
133
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700134 // True if the device should suspend when the screen is off due to proximity.
135 private final boolean mSuspendWhenScreenOffDueToProximityConfig;
136
Beverlyf364d7c2019-10-10 16:44:43 -0400137 // True if the device should show the wireless charging animation when the device
138 // begins charging wirelessly
139 private final boolean mShowWirelessChargingAnimationConfig;
140
Jeff Brown416c49c2015-05-26 19:50:18 -0700141 // The current interactive state. This is set as soon as an interactive state
142 // transition begins so as to capture the reason that it happened. At some point
143 // this state will propagate to the pending state then eventually to the
144 // broadcasted state over the course of reporting the transition asynchronously.
145 private boolean mInteractive = true;
146 private int mInteractiveChangeReason;
Michael Wrighte3001042019-02-05 00:13:14 +0000147 private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
Jeff Brown416c49c2015-05-26 19:50:18 -0700148 private boolean mInteractiveChanging;
Jeff Brown96307042012-07-27 15:51:34 -0700149
Jeff Brown416c49c2015-05-26 19:50:18 -0700150 // The pending interactive state that we will eventually want to broadcast.
151 // This is designed so that we can collapse redundant sequences of awake/sleep
152 // transition pairs while still guaranteeing that at least one transition is observed
153 // whenever this happens.
154 private int mPendingInteractiveState;
Jeff Brown54308352012-10-04 17:59:58 -0700155 private boolean mPendingWakeUpBroadcast;
156 private boolean mPendingGoToSleepBroadcast;
157
Jeff Brownfbe96702014-11-19 18:30:58 -0800158 // The currently broadcasted interactive state. This reflects what other parts of the
Jeff Brown96307042012-07-27 15:51:34 -0700159 // system have observed.
Jeff Brownfbe96702014-11-19 18:30:58 -0800160 private int mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700161 private boolean mBroadcastInProgress;
162 private long mBroadcastStartTime;
163
164 // True if a user activity message should be sent.
165 private boolean mUserActivityPending;
166
167 public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
Svet Ganovf7b47252018-02-26 11:11:27 -0800168 SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
Jeff Brown96307042012-07-27 15:51:34 -0700169 mContext = context;
170 mBatteryStats = batteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800171 mAppOps = mContext.getSystemService(AppOpsManager.class);
Jeff Brown96307042012-07-27 15:51:34 -0700172 mSuspendBlocker = suspendBlocker;
173 mPolicy = policy;
Jeff Brown13014b52014-04-07 19:45:27 -0700174 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700175 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700176 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
Beverlyae79ab92017-12-11 09:20:02 -0500177 mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
Pavel Grafov28939982017-10-03 15:11:52 +0100178 mTrustManager = mContext.getSystemService(TrustManager.class);
Beverly69721d62018-05-09 17:41:44 -0400179 mVibrator = mContext.getSystemService(Vibrator.class);
Jeff Brown96307042012-07-27 15:51:34 -0700180
181 mHandler = new NotifierHandler(looper);
182 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
183 mScreenOnIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700184 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
185 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Jeff Brown96307042012-07-27 15:51:34 -0700186 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
187 mScreenOffIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700188 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
189 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700190
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700191 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
192 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
Beverlyf364d7c2019-10-10 16:44:43 -0400193 mShowWirelessChargingAnimationConfig = context.getResources().getBoolean(
194 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700195
Santos Cordon9204cc82019-11-21 11:45:28 +0000196 mWakeLockLog = new WakeLockLog();
197
Jeff Browne95c3cd2014-05-02 16:59:26 -0700198 // Initialize interactive state for battery stats.
199 try {
200 mBatteryStats.noteInteractive(true);
201 } catch (RemoteException ex) { }
Muhammad Qureshi41166302020-01-28 10:23:36 -0800202 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED,
203 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON);
Jeff Brown96307042012-07-27 15:51:34 -0700204 }
205
206 /**
207 * Called when a wake lock is acquired.
208 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700209 public void onWakeLockAcquired(int flags, String tag, String packageName,
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800210 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700211 if (DEBUG) {
212 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700213 + "\", packageName=" + packageName
214 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700215 + ", workSource=" + workSource);
216 }
217
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700218 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
219 if (monitorType >= 0) {
220 try {
221 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
222 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
223 if (workSource != null) {
224 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
225 historyTag, monitorType, unimportantForLogging);
226 } else {
227 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
228 monitorType, unimportantForLogging);
229 // XXX need to deal with disabled operations.
Svet Ganovf7b47252018-02-26 11:11:27 -0800230 mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700231 }
232 } catch (RemoteException ex) {
233 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700234 }
235 }
Santos Cordon9204cc82019-11-21 11:45:28 +0000236
237 mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags);
Jeff Brown96307042012-07-27 15:51:34 -0700238 }
239
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700240 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
241 String historyTag) {
242 if (DEBUG) {
243 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid
244 + ", workSource=" + workSource);
245 }
246
247 try {
248 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000249 mBatteryStats.noteLongPartialWakelockStartFromSource(tag, historyTag, workSource);
Muhammad Qureshi41166302020-01-28 10:23:36 -0800250 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
251 workSource, tag, historyTag,
252 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700253 } else {
254 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid);
Muhammad Qureshi41166302020-01-28 10:23:36 -0800255 FrameworkStatsLog.write_non_chained(
256 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag,
257 historyTag,
258 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700259 }
260 } catch (RemoteException ex) {
261 // Ignore
262 }
263 }
264
265 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource,
266 String historyTag) {
267 if (DEBUG) {
268 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid
269 + ", workSource=" + workSource);
270 }
271
272 try {
273 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000274 mBatteryStats.noteLongPartialWakelockFinishFromSource(tag, historyTag, workSource);
Muhammad Qureshi41166302020-01-28 10:23:36 -0800275 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
276 workSource, tag, historyTag,
277 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700278 } else {
279 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid);
Muhammad Qureshi41166302020-01-28 10:23:36 -0800280 FrameworkStatsLog.write_non_chained(
281 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag,
282 historyTag,
283 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700284 }
285 } catch (RemoteException ex) {
286 // Ignore
287 }
288 }
289
Jeff Brown96307042012-07-27 15:51:34 -0700290 /**
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800291 * Called when a wake lock is changing.
292 */
293 public void onWakeLockChanging(int flags, String tag, String packageName,
294 int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
295 int newFlags, String newTag, String newPackageName, int newOwnerUid,
296 int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
297
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700298 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
299 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
300 if (workSource != null && newWorkSource != null
301 && monitorType >= 0 && newMonitorType >= 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800302 if (DEBUG) {
303 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
304 + "\", packageName=" + newPackageName
305 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
306 + ", workSource=" + newWorkSource);
307 }
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700308
309 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
310 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800311 try {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700312 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
313 monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800314 newMonitorType, unimportantForLogging);
315 } catch (RemoteException ex) {
316 // Ignore
317 }
318 } else {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700319 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800320 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
321 newWorkSource, newHistoryTag);
322 }
323 }
324
325 /**
Jeff Brown96307042012-07-27 15:51:34 -0700326 * Called when a wake lock is released.
327 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700328 public void onWakeLockReleased(int flags, String tag, String packageName,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700329 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700330 if (DEBUG) {
331 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700332 + "\", packageName=" + packageName
333 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700334 + ", workSource=" + workSource);
335 }
336
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700337 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
338 if (monitorType >= 0) {
339 try {
340 if (workSource != null) {
341 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
342 historyTag, monitorType);
343 } else {
344 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
345 historyTag, monitorType);
Svet Ganovf7b47252018-02-26 11:11:27 -0800346 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700347 }
348 } catch (RemoteException ex) {
349 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700350 }
351 }
Santos Cordon9204cc82019-11-21 11:45:28 +0000352 mWakeLockLog.onWakeLockReleased(tag, ownerUid);
Jeff Brown96307042012-07-27 15:51:34 -0700353 }
354
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700355 private int getBatteryStatsWakeLockMonitorType(int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700356 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
357 case PowerManager.PARTIAL_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700358 return BatteryStats.WAKE_TYPE_PARTIAL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700359
360 case PowerManager.SCREEN_DIM_WAKE_LOCK:
361 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700362 return BatteryStats.WAKE_TYPE_FULL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700363
364 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
365 if (mSuspendWhenScreenOffDueToProximityConfig) {
366 return -1;
367 }
368 return BatteryStats.WAKE_TYPE_PARTIAL;
369
370 case PowerManager.DRAW_WAKE_LOCK:
371 return BatteryStats.WAKE_TYPE_DRAW;
372
373 case PowerManager.DOZE_WAKE_LOCK:
374 // Doze wake locks are an internal implementation detail of the
375 // communication between dream manager service and power manager
376 // service. They have no additive battery impact.
377 return -1;
378
379 default:
380 return -1;
Jeff Brown96307042012-07-27 15:51:34 -0700381 }
382 }
383
384 /**
Jeff Brownfbe96702014-11-19 18:30:58 -0800385 * Notifies that the device is changing wakefulness.
Jeff Brown416c49c2015-05-26 19:50:18 -0700386 * This function may be called even if the previous change hasn't finished in
387 * which case it will assume that the state did not fully converge before the
388 * next transition began and will recover accordingly.
Jeff Brown96307042012-07-27 15:51:34 -0700389 */
Michael Wrighte3001042019-02-05 00:13:14 +0000390 public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
Jeff Brown416c49c2015-05-26 19:50:18 -0700391 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
Jeff Brown96307042012-07-27 15:51:34 -0700392 if (DEBUG) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800393 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
Jeff Brown416c49c2015-05-26 19:50:18 -0700394 + ", reason=" + reason + ", interactive=" + interactive);
Jeff Brown96307042012-07-27 15:51:34 -0700395 }
396
Jeff Brownfbe96702014-11-19 18:30:58 -0800397 // Tell the activity manager about changes in wakefulness, not just interactivity.
398 // It needs more granularity than other components.
399 mHandler.post(new Runnable() {
400 @Override
401 public void run() {
402 mActivityManagerInternal.onWakefulnessChanged(wakefulness);
403 }
404 });
405
Jeff Brown416c49c2015-05-26 19:50:18 -0700406 // Handle any early interactive state changes.
407 // Finish pending incomplete ones from a previous cycle.
408 if (mInteractive != interactive) {
409 // Finish up late behaviors if needed.
410 if (mInteractiveChanging) {
411 handleLateInteractiveChange();
Jeff Brown96307042012-07-27 15:51:34 -0700412 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700413
Jeff Brown416c49c2015-05-26 19:50:18 -0700414 // Start input as soon as we start waking up or going to sleep.
415 mInputManagerInternal.setInteractive(interactive);
Ming-Shin Lu2c6e80b2020-05-13 00:12:26 +0800416 mInputMethodManagerInternal.setInteractive(interactive);
Jeff Brown416c49c2015-05-26 19:50:18 -0700417
418 // Notify battery stats.
Jeff Browne95c3cd2014-05-02 16:59:26 -0700419 try {
Jeff Brownfbe96702014-11-19 18:30:58 -0800420 mBatteryStats.noteInteractive(interactive);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700421 } catch (RemoteException ex) { }
Muhammad Qureshi41166302020-01-28 10:23:36 -0800422 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED,
423 interactive ? FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON :
424 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF);
Jeff Brown416c49c2015-05-26 19:50:18 -0700425
426 // Handle early behaviors.
427 mInteractive = interactive;
428 mInteractiveChangeReason = reason;
Michael Wrighte3001042019-02-05 00:13:14 +0000429 mInteractiveChangeStartTime = eventTime;
Jeff Brown416c49c2015-05-26 19:50:18 -0700430 mInteractiveChanging = true;
431 handleEarlyInteractiveChange();
432 }
433 }
434
435 /**
436 * Notifies that the device has finished changing wakefulness.
437 */
438 public void onWakefulnessChangeFinished() {
439 if (DEBUG) {
440 Slog.d(TAG, "onWakefulnessChangeFinished");
441 }
442
443 if (mInteractiveChanging) {
444 mInteractiveChanging = false;
445 handleLateInteractiveChange();
446 }
447 }
448
449 /**
450 * Handle early interactive state changes such as getting applications or the lock
451 * screen running and ready for the user to see (such as when turning on the screen).
452 */
453 private void handleEarlyInteractiveChange() {
454 synchronized (mLock) {
455 if (mInteractive) {
456 // Waking up...
457 mHandler.post(new Runnable() {
458 @Override
459 public void run() {
Michael Wrighte3001042019-02-05 00:13:14 +0000460 final int why = translateOnReason(mInteractiveChangeReason);
461 mPolicy.startedWakingUp(why);
Jeff Brown416c49c2015-05-26 19:50:18 -0700462 }
463 });
464
465 // Send interactive broadcast.
466 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
467 mPendingWakeUpBroadcast = true;
468 updatePendingBroadcastLocked();
469 } else {
470 // Going to sleep...
471 // Tell the policy that we started going to sleep.
472 final int why = translateOffReason(mInteractiveChangeReason);
473 mHandler.post(new Runnable() {
474 @Override
475 public void run() {
476 mPolicy.startedGoingToSleep(why);
477 }
478 });
479 }
480 }
481 }
482
483 /**
484 * Handle late interactive state changes once they are finished so that the system can
485 * finish pending transitions (such as turning the screen off) before causing
486 * applications to change state visibly.
487 */
488 private void handleLateInteractiveChange() {
489 synchronized (mLock) {
Michael Wrighte3001042019-02-05 00:13:14 +0000490 final int interactiveChangeLatency =
491 (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
Jeff Brown416c49c2015-05-26 19:50:18 -0700492 if (mInteractive) {
493 // Finished waking up...
Michael Wrighte3001042019-02-05 00:13:14 +0000494 final int why = translateOnReason(mInteractiveChangeReason);
Jeff Brown416c49c2015-05-26 19:50:18 -0700495 mHandler.post(new Runnable() {
496 @Override
497 public void run() {
Michael Wrighte3001042019-02-05 00:13:14 +0000498 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
499 log.setType(MetricsEvent.TYPE_OPEN);
500 log.setSubtype(why);
501 log.setLatency(interactiveChangeLatency);
Steven Wu0e6e5de2019-03-12 17:13:14 -0400502 log.addTaggedData(
503 MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason);
Michael Wrighte3001042019-02-05 00:13:14 +0000504 MetricsLogger.action(log);
505 EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
506 mPolicy.finishedWakingUp(why);
Jeff Brown416c49c2015-05-26 19:50:18 -0700507 }
508 });
509 } else {
510 // Finished going to sleep...
511 // This is a good time to make transitions that we don't want the user to see,
512 // such as bringing the key guard to focus. There's no guarantee for this
513 // however because the user could turn the device on again at any time.
514 // Some things may need to be protected by other mechanisms that defer screen on.
515
516 // Cancel pending user activity.
517 if (mUserActivityPending) {
518 mUserActivityPending = false;
519 mHandler.removeMessages(MSG_USER_ACTIVITY);
520 }
521
522 // Tell the policy we finished going to sleep.
523 final int why = translateOffReason(mInteractiveChangeReason);
524 mHandler.post(new Runnable() {
525 @Override
526 public void run() {
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500527 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
528 log.setType(MetricsEvent.TYPE_CLOSE);
529 log.setSubtype(why);
Michael Wrighte3001042019-02-05 00:13:14 +0000530 log.setLatency(interactiveChangeLatency);
Steven Wu0e6e5de2019-03-12 17:13:14 -0400531 log.addTaggedData(
532 MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason);
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500533 MetricsLogger.action(log);
Michael Wrighte3001042019-02-05 00:13:14 +0000534 EventLogTags.writePowerScreenState(0, why, 0, 0, interactiveChangeLatency);
Jeff Brown416c49c2015-05-26 19:50:18 -0700535 mPolicy.finishedGoingToSleep(why);
536 }
537 });
538
539 // Send non-interactive broadcast.
540 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
541 mPendingGoToSleepBroadcast = true;
542 updatePendingBroadcastLocked();
543 }
544 }
545 }
546
547 private static int translateOffReason(int reason) {
548 switch (reason) {
549 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
550 return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
551 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
Robert Horvath5560f382019-07-10 10:46:38 +0200552 case PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE:
Jeff Brown416c49c2015-05-26 19:50:18 -0700553 return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
554 default:
555 return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
Jeff Browne95c3cd2014-05-02 16:59:26 -0700556 }
Jeff Brown96307042012-07-27 15:51:34 -0700557 }
558
Michael Wrighte3001042019-02-05 00:13:14 +0000559 private static @OnReason int translateOnReason(@WakeReason int reason) {
560 switch (reason) {
561 case PowerManager.WAKE_REASON_POWER_BUTTON:
562 case PowerManager.WAKE_REASON_PLUGGED_IN:
563 case PowerManager.WAKE_REASON_GESTURE:
564 case PowerManager.WAKE_REASON_CAMERA_LAUNCH:
565 case PowerManager.WAKE_REASON_WAKE_KEY:
566 case PowerManager.WAKE_REASON_WAKE_MOTION:
567 case PowerManager.WAKE_REASON_LID:
568 return WindowManagerPolicy.ON_BECAUSE_OF_USER;
569 case PowerManager.WAKE_REASON_APPLICATION:
570 return WindowManagerPolicy.ON_BECAUSE_OF_APPLICATION;
571 default:
572 return WindowManagerPolicy.ON_BECAUSE_OF_UNKNOWN;
573 }
574 }
575
Jeff Brown96307042012-07-27 15:51:34 -0700576 /**
577 * 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
Santos Cordon9204cc82019-11-21 11:45:28 +0000662 /**
663 * Dumps data for bugreports.
664 *
665 * @param pw The stream to print to.
666 */
667 public void dump(PrintWriter pw) {
668 if (mWakeLockLog != null) {
669 mWakeLockLog.dump(pw);
670 }
671 }
672
Jeff Brown96307042012-07-27 15:51:34 -0700673 private void updatePendingBroadcastLocked() {
674 if (!mBroadcastInProgress
Jeff Brown416c49c2015-05-26 19:50:18 -0700675 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
Jeff Brown54308352012-10-04 17:59:58 -0700676 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700677 || mPendingInteractiveState != mBroadcastedInteractiveState)) {
Jeff Brown96307042012-07-27 15:51:34 -0700678 mBroadcastInProgress = true;
679 mSuspendBlocker.acquire();
680 Message msg = mHandler.obtainMessage(MSG_BROADCAST);
681 msg.setAsynchronous(true);
682 mHandler.sendMessage(msg);
683 }
684 }
685
Jeff Brown54308352012-10-04 17:59:58 -0700686 private void finishPendingBroadcastLocked() {
687 mBroadcastInProgress = false;
688 mSuspendBlocker.release();
689 }
690
Jeff Brown96307042012-07-27 15:51:34 -0700691 private void sendUserActivity() {
692 synchronized (mLock) {
693 if (!mUserActivityPending) {
694 return;
695 }
696 mUserActivityPending = false;
697 }
Peter Wang6a92dd42020-01-15 14:11:25 -0800698 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
699 tm.notifyUserActivity();
Jeff Brown96307042012-07-27 15:51:34 -0700700 mPolicy.userActivity();
701 }
702
703 private void sendNextBroadcast() {
704 final int powerState;
Jeff Brown96307042012-07-27 15:51:34 -0700705 synchronized (mLock) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800706 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
Robert Horvath4fbab202019-11-29 15:36:39 +0100707 // Broadcasted power state is unknown.
708 // Send wake up or go to sleep.
709 switch (mPendingInteractiveState) {
710 case INTERACTIVE_STATE_ASLEEP:
711 mPendingGoToSleepBroadcast = false;
712 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
713 break;
714
715 case INTERACTIVE_STATE_AWAKE:
716 default:
717 mPendingWakeUpBroadcast = false;
718 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
719 break;
720 }
Jeff Brownfbe96702014-11-19 18:30:58 -0800721 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700722 // Broadcasted power state is awake. Send asleep if needed.
723 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700724 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
Jeff Brown54308352012-10-04 17:59:58 -0700725 mPendingGoToSleepBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800726 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
Jeff Brown54308352012-10-04 17:59:58 -0700727 } else {
728 finishPendingBroadcastLocked();
729 return;
730 }
731 } else {
732 // Broadcasted power state is asleep. Send awake if needed.
733 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700734 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700735 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800736 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
Jeff Brown54308352012-10-04 17:59:58 -0700737 } else {
738 finishPendingBroadcastLocked();
739 return;
740 }
Jeff Brown96307042012-07-27 15:51:34 -0700741 }
742
Jeff Brown96307042012-07-27 15:51:34 -0700743 mBroadcastStartTime = SystemClock.uptimeMillis();
Jeff Brownfbe96702014-11-19 18:30:58 -0800744 powerState = mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700745 }
746
747 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
748
Jeff Brownfbe96702014-11-19 18:30:58 -0800749 if (powerState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown96307042012-07-27 15:51:34 -0700750 sendWakeUpBroadcast();
751 } else {
Jim Millerc522d162014-07-01 17:10:21 -0700752 sendGoToSleepBroadcast();
Jeff Brown96307042012-07-27 15:51:34 -0700753 }
754 }
755
756 private void sendWakeUpBroadcast() {
757 if (DEBUG) {
758 Slog.d(TAG, "Sending wake up broadcast.");
759 }
760
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700761 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700762 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700763 mWakeUpBroadcastDone, mHandler, 0, null, null);
764 } else {
765 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
766 sendNextBroadcast();
767 }
768 }
769
770 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
771 @Override
772 public void onReceive(Context context, Intent intent) {
773 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
774 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
775 sendNextBroadcast();
776 }
777 };
778
Jim Millerc522d162014-07-01 17:10:21 -0700779 private void sendGoToSleepBroadcast() {
Jeff Brown96307042012-07-27 15:51:34 -0700780 if (DEBUG) {
781 Slog.d(TAG, "Sending go to sleep broadcast.");
782 }
783
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700784 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700785 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700786 mGoToSleepBroadcastDone, mHandler, 0, null, null);
787 } else {
788 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
789 sendNextBroadcast();
790 }
791 }
792
793 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
794 @Override
795 public void onReceive(Context context, Intent intent) {
796 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
797 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
798 sendNextBroadcast();
799 }
800 };
801
Beverlyf364d7c2019-10-10 16:44:43 -0400802 private void playChargingStartedFeedback(@UserIdInt int userId, boolean wireless) {
803 if (!isChargingFeedbackEnabled(userId)) {
804 return;
805 }
806
807 // vibrate
808 final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(),
809 Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
810 if (vibrate) {
811 mVibrator.vibrate(CHARGING_VIBRATION_EFFECT, VIBRATION_ATTRIBUTES);
812 }
813
814 // play sound
Jeff Brown84e27562012-12-07 13:56:34 -0800815 final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
Beverlyf364d7c2019-10-10 16:44:43 -0400816 wireless ? Settings.Global.WIRELESS_CHARGING_STARTED_SOUND
817 : Settings.Global.CHARGING_STARTED_SOUND);
818 final Uri soundUri = Uri.parse("file://" + soundPath);
819 if (soundUri != null) {
820 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
821 if (sfx != null) {
822 sfx.setStreamType(AudioManager.STREAM_SYSTEM);
823 sfx.play();
Jeff Brown84e27562012-12-07 13:56:34 -0800824 }
825 }
Beverlyae79ab92017-12-11 09:20:02 -0500826 }
Jeff Brown84e27562012-12-07 13:56:34 -0800827
Beverly91d0a632018-07-02 16:45:00 -0400828 private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
Beverlyf364d7c2019-10-10 16:44:43 -0400829 // play sounds + haptics
830 playChargingStartedFeedback(userId, true /* wireless */);
831
832 // show animation
833 if (mShowWirelessChargingAnimationConfig && mStatusBarManagerInternal != null) {
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700834 mStatusBarManagerInternal.showChargingAnimation(batteryLevel);
835 }
Jeff Brown84e27562012-12-07 13:56:34 -0800836 mSuspendBlocker.release();
837 }
838
Beverly91d0a632018-07-02 16:45:00 -0400839 private void showWiredChargingStarted(@UserIdInt int userId) {
Beverlyf364d7c2019-10-10 16:44:43 -0400840 playChargingStartedFeedback(userId, false /* wireless */);
Beverlyc1313eb2018-01-31 18:07:21 -0500841 mSuspendBlocker.release();
842 }
843
Pavel Grafov28939982017-10-03 15:11:52 +0100844 private void lockProfile(@UserIdInt int userId) {
845 mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
846 }
847
Beverly91d0a632018-07-02 16:45:00 -0400848 private boolean isChargingFeedbackEnabled(@UserIdInt int userId) {
849 final boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
850 Settings.Secure.CHARGING_SOUNDS_ENABLED, 1, userId) != 0;
Beverly69721d62018-05-09 17:41:44 -0400851 final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
852 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
853 == Settings.Global.ZEN_MODE_OFF;
854 return enabled && dndOff;
855 }
856
Jeff Brown96307042012-07-27 15:51:34 -0700857 private final class NotifierHandler extends Handler {
Pavel Grafov28939982017-10-03 15:11:52 +0100858
Jeff Brown96307042012-07-27 15:51:34 -0700859 public NotifierHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700860 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -0700861 }
Jeff Brown96307042012-07-27 15:51:34 -0700862 @Override
863 public void handleMessage(Message msg) {
864 switch (msg.what) {
865 case MSG_USER_ACTIVITY:
866 sendUserActivity();
867 break;
Jeff Brown96307042012-07-27 15:51:34 -0700868 case MSG_BROADCAST:
869 sendNextBroadcast();
870 break;
Jeff Brown84e27562012-12-07 13:56:34 -0800871 case MSG_WIRELESS_CHARGING_STARTED:
Beverly91d0a632018-07-02 16:45:00 -0400872 showWirelessChargingStarted(msg.arg1, msg.arg2);
Jeff Brown84e27562012-12-07 13:56:34 -0800873 break;
Pavel Grafov28939982017-10-03 15:11:52 +0100874 case MSG_PROFILE_TIMED_OUT:
875 lockProfile(msg.arg1);
876 break;
Beverlyc1313eb2018-01-31 18:07:21 -0500877 case MSG_WIRED_CHARGING_STARTED:
Beverly91d0a632018-07-02 16:45:00 -0400878 showWiredChargingStarted(msg.arg1);
Beverly69721d62018-05-09 17:41:44 -0400879 break;
Jeff Brown96307042012-07-27 15:51:34 -0700880 }
881 }
882 }
883}