blob: eecf17acba3f3e3be78d6616d9ca77b53661716a [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;
Beverlydf9f36d2018-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;
Jeff Brownfbe96702014-11-19 18:30:58 -080039import android.os.PowerManagerInternal;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -080040import android.os.Process;
Jeff Brown96307042012-07-27 15:51:34 -070041import android.os.RemoteException;
42import android.os.SystemClock;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070043import android.os.UserHandle;
Beverlydf9f36d2018-05-09 17:41:44 -040044import android.os.VibrationEffect;
45import android.os.Vibrator;
Jeff Brown96307042012-07-27 15:51:34 -070046import android.os.WorkSource;
Jeff Brown84e27562012-12-07 13:56:34 -080047import android.provider.Settings;
Jeff Brown96307042012-07-27 15:51:34 -070048import android.util.EventLog;
49import android.util.Slog;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -070050import android.view.inputmethod.InputMethodManagerInternal;
Jeff Brown96307042012-07-27 15:51:34 -070051
Beverlyae79ab92017-12-11 09:20:02 -050052import com.android.internal.app.IBatteryStats;
53import com.android.internal.logging.MetricsLogger;
54import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
55import com.android.server.EventLogTags;
56import com.android.server.LocalServices;
Beverlyae79ab92017-12-11 09:20:02 -050057import com.android.server.policy.WindowManagerPolicy;
Beverlydf9f36d2018-05-09 17:41:44 -040058import com.android.server.statusbar.StatusBarManagerInternal;
Beverlyae79ab92017-12-11 09:20:02 -050059
Jeff Brown96307042012-07-27 15:51:34 -070060/**
61 * Sends broadcasts about important power state changes.
Jeff Brown54308352012-10-04 17:59:58 -070062 * <p>
Jeff Brown96307042012-07-27 15:51:34 -070063 * This methods of this class may be called by the power manager service while
64 * its lock is being held. Internally it takes care of sending broadcasts to
65 * notify other components of the system or applications asynchronously.
Jeff Brown54308352012-10-04 17:59:58 -070066 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070067 * The notifier is designed to collapse unnecessary broadcasts when it is not
68 * possible for the system to have observed an intermediate state.
Jeff Brown54308352012-10-04 17:59:58 -070069 * </p><p>
70 * For example, if the device wakes up, goes to sleep, wakes up again and goes to
71 * sleep again before the wake up notification is sent, then the system will
72 * be told about only one wake up and sleep. However, we always notify the
73 * fact that at least one transition occurred. It is especially important to
74 * tell the system when we go to sleep so that it can lock the keyguard if needed.
75 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070076 */
77final class Notifier {
78 private static final String TAG = "PowerManagerNotifier";
79
80 private static final boolean DEBUG = false;
81
Jeff Brownfbe96702014-11-19 18:30:58 -080082 private static final int INTERACTIVE_STATE_UNKNOWN = 0;
83 private static final int INTERACTIVE_STATE_AWAKE = 1;
84 private static final int INTERACTIVE_STATE_ASLEEP = 2;
Jeff Brown96307042012-07-27 15:51:34 -070085
86 private static final int MSG_USER_ACTIVITY = 1;
87 private static final int MSG_BROADCAST = 2;
Jeff Brown84e27562012-12-07 13:56:34 -080088 private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
Bryce Lee84d6c0f2015-03-17 10:43:08 -070089 private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;
Pavel Grafov28939982017-10-03 15:11:52 +010090 private static final int MSG_PROFILE_TIMED_OUT = 5;
Beverlyc1313eb2018-01-31 18:07:21 -050091 private static final int MSG_WIRED_CHARGING_STARTED = 6;
Jeff Brown96307042012-07-27 15:51:34 -070092
Beverlydf9f36d2018-05-09 17:41:44 -040093 private static final long[] WIRELESS_VIBRATION_TIME = {
94 40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms
95 40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms
96 };
97 private static final int[] WIRELESS_VIBRATION_AMPLITUDE = {
98 1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%)
99 103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude
100 };
101 private static final VibrationEffect WIRELESS_CHARGING_VIBRATION_EFFECT =
102 VibrationEffect.createWaveform(WIRELESS_VIBRATION_TIME, WIRELESS_VIBRATION_AMPLITUDE,
103 -1);
104 private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
105 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
106 .build();
107
Jeff Brown96307042012-07-27 15:51:34 -0700108 private final Object mLock = new Object();
109
110 private final Context mContext;
111 private final IBatteryStats mBatteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800112 private final AppOpsManager mAppOps;
Jeff Brown96307042012-07-27 15:51:34 -0700113 private final SuspendBlocker mSuspendBlocker;
114 private final WindowManagerPolicy mPolicy;
Jeff Brown13014b52014-04-07 19:45:27 -0700115 private final ActivityManagerInternal mActivityManagerInternal;
Jeff Brown037c33e2014-04-09 00:31:55 -0700116 private final InputManagerInternal mInputManagerInternal;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700117 private final InputMethodManagerInternal mInputMethodManagerInternal;
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700118 @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal;
Pavel Grafov28939982017-10-03 15:11:52 +0100119 private final TrustManager mTrustManager;
Beverlydf9f36d2018-05-09 17:41:44 -0400120 private final Vibrator mVibrator;
Jeff Brown96307042012-07-27 15:51:34 -0700121
122 private final NotifierHandler mHandler;
123 private final Intent mScreenOnIntent;
124 private final Intent mScreenOffIntent;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700125 private final Intent mScreenBrightnessBoostIntent;
Jeff Brown96307042012-07-27 15:51:34 -0700126
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700127 // True if the device should suspend when the screen is off due to proximity.
128 private final boolean mSuspendWhenScreenOffDueToProximityConfig;
129
Jeff Brown416c49c2015-05-26 19:50:18 -0700130 // The current interactive state. This is set as soon as an interactive state
131 // transition begins so as to capture the reason that it happened. At some point
132 // this state will propagate to the pending state then eventually to the
133 // broadcasted state over the course of reporting the transition asynchronously.
134 private boolean mInteractive = true;
135 private int mInteractiveChangeReason;
136 private boolean mInteractiveChanging;
Jeff Brown96307042012-07-27 15:51:34 -0700137
Jeff Brown416c49c2015-05-26 19:50:18 -0700138 // The pending interactive state that we will eventually want to broadcast.
139 // This is designed so that we can collapse redundant sequences of awake/sleep
140 // transition pairs while still guaranteeing that at least one transition is observed
141 // whenever this happens.
142 private int mPendingInteractiveState;
Jeff Brown54308352012-10-04 17:59:58 -0700143 private boolean mPendingWakeUpBroadcast;
144 private boolean mPendingGoToSleepBroadcast;
145
Jeff Brownfbe96702014-11-19 18:30:58 -0800146 // The currently broadcasted interactive state. This reflects what other parts of the
Jeff Brown96307042012-07-27 15:51:34 -0700147 // system have observed.
Jeff Brownfbe96702014-11-19 18:30:58 -0800148 private int mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700149 private boolean mBroadcastInProgress;
150 private long mBroadcastStartTime;
151
152 // True if a user activity message should be sent.
153 private boolean mUserActivityPending;
154
155 public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
Svet Ganovf7b47252018-02-26 11:11:27 -0800156 SuspendBlocker suspendBlocker, WindowManagerPolicy policy) {
Jeff Brown96307042012-07-27 15:51:34 -0700157 mContext = context;
158 mBatteryStats = batteryStats;
Svet Ganovf7b47252018-02-26 11:11:27 -0800159 mAppOps = mContext.getSystemService(AppOpsManager.class);
Jeff Brown96307042012-07-27 15:51:34 -0700160 mSuspendBlocker = suspendBlocker;
161 mPolicy = policy;
Jeff Brown13014b52014-04-07 19:45:27 -0700162 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700163 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700164 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
Beverlyae79ab92017-12-11 09:20:02 -0500165 mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
Pavel Grafov28939982017-10-03 15:11:52 +0100166 mTrustManager = mContext.getSystemService(TrustManager.class);
Beverlydf9f36d2018-05-09 17:41:44 -0400167 mVibrator = mContext.getSystemService(Vibrator.class);
Jeff Brown96307042012-07-27 15:51:34 -0700168
169 mHandler = new NotifierHandler(looper);
170 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
171 mScreenOnIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700172 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
173 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Jeff Brown96307042012-07-27 15:51:34 -0700174 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
175 mScreenOffIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700176 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
177 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700178 mScreenBrightnessBoostIntent =
179 new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
180 mScreenBrightnessBoostIntent.addFlags(
181 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700182
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700183 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
184 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
185
Jeff Browne95c3cd2014-05-02 16:59:26 -0700186 // Initialize interactive state for battery stats.
187 try {
188 mBatteryStats.noteInteractive(true);
189 } catch (RemoteException ex) { }
Jeff Brown96307042012-07-27 15:51:34 -0700190 }
191
192 /**
193 * Called when a wake lock is acquired.
194 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700195 public void onWakeLockAcquired(int flags, String tag, String packageName,
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800196 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700197 if (DEBUG) {
198 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700199 + "\", packageName=" + packageName
200 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700201 + ", workSource=" + workSource);
202 }
203
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700204 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
205 if (monitorType >= 0) {
206 try {
207 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
208 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
209 if (workSource != null) {
210 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
211 historyTag, monitorType, unimportantForLogging);
212 } else {
213 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
214 monitorType, unimportantForLogging);
215 // XXX need to deal with disabled operations.
Svet Ganovf7b47252018-02-26 11:11:27 -0800216 mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700217 }
218 } catch (RemoteException ex) {
219 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700220 }
221 }
222 }
223
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700224 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
225 String historyTag) {
226 if (DEBUG) {
227 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid
228 + ", workSource=" + workSource);
229 }
230
231 try {
232 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000233 mBatteryStats.noteLongPartialWakelockStartFromSource(tag, historyTag, workSource);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700234 } else {
235 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid);
236 }
237 } catch (RemoteException ex) {
238 // Ignore
239 }
240 }
241
242 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource,
243 String historyTag) {
244 if (DEBUG) {
245 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid
246 + ", workSource=" + workSource);
247 }
248
249 try {
250 if (workSource != null) {
Narayan Kamath96a92562018-01-02 18:57:17 +0000251 mBatteryStats.noteLongPartialWakelockFinishFromSource(tag, historyTag, workSource);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700252 } else {
253 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid);
254 }
255 } catch (RemoteException ex) {
256 // Ignore
257 }
258 }
259
Jeff Brown96307042012-07-27 15:51:34 -0700260 /**
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800261 * Called when a wake lock is changing.
262 */
263 public void onWakeLockChanging(int flags, String tag, String packageName,
264 int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
265 int newFlags, String newTag, String newPackageName, int newOwnerUid,
266 int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
267
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700268 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
269 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
270 if (workSource != null && newWorkSource != null
271 && monitorType >= 0 && newMonitorType >= 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800272 if (DEBUG) {
273 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
274 + "\", packageName=" + newPackageName
275 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
276 + ", workSource=" + newWorkSource);
277 }
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700278
279 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
280 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800281 try {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700282 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
283 monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800284 newMonitorType, unimportantForLogging);
285 } catch (RemoteException ex) {
286 // Ignore
287 }
288 } else {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700289 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800290 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
291 newWorkSource, newHistoryTag);
292 }
293 }
294
295 /**
Jeff Brown96307042012-07-27 15:51:34 -0700296 * Called when a wake lock is released.
297 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700298 public void onWakeLockReleased(int flags, String tag, String packageName,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700299 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700300 if (DEBUG) {
301 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700302 + "\", packageName=" + packageName
303 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700304 + ", workSource=" + workSource);
305 }
306
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700307 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
308 if (monitorType >= 0) {
309 try {
310 if (workSource != null) {
311 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
312 historyTag, monitorType);
313 } else {
314 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
315 historyTag, monitorType);
Svet Ganovf7b47252018-02-26 11:11:27 -0800316 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700317 }
318 } catch (RemoteException ex) {
319 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700320 }
321 }
322 }
323
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700324 private int getBatteryStatsWakeLockMonitorType(int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700325 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
326 case PowerManager.PARTIAL_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700327 return BatteryStats.WAKE_TYPE_PARTIAL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700328
329 case PowerManager.SCREEN_DIM_WAKE_LOCK:
330 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700331 return BatteryStats.WAKE_TYPE_FULL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700332
333 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
334 if (mSuspendWhenScreenOffDueToProximityConfig) {
335 return -1;
336 }
337 return BatteryStats.WAKE_TYPE_PARTIAL;
338
339 case PowerManager.DRAW_WAKE_LOCK:
340 return BatteryStats.WAKE_TYPE_DRAW;
341
342 case PowerManager.DOZE_WAKE_LOCK:
343 // Doze wake locks are an internal implementation detail of the
344 // communication between dream manager service and power manager
345 // service. They have no additive battery impact.
346 return -1;
347
348 default:
349 return -1;
Jeff Brown96307042012-07-27 15:51:34 -0700350 }
351 }
352
353 /**
Jeff Brownfbe96702014-11-19 18:30:58 -0800354 * Notifies that the device is changing wakefulness.
Jeff Brown416c49c2015-05-26 19:50:18 -0700355 * This function may be called even if the previous change hasn't finished in
356 * which case it will assume that the state did not fully converge before the
357 * next transition began and will recover accordingly.
Jeff Brown96307042012-07-27 15:51:34 -0700358 */
Jeff Brown416c49c2015-05-26 19:50:18 -0700359 public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
360 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
Jeff Brown96307042012-07-27 15:51:34 -0700361 if (DEBUG) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800362 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
Jeff Brown416c49c2015-05-26 19:50:18 -0700363 + ", reason=" + reason + ", interactive=" + interactive);
Jeff Brown96307042012-07-27 15:51:34 -0700364 }
365
Jeff Brownfbe96702014-11-19 18:30:58 -0800366 // Tell the activity manager about changes in wakefulness, not just interactivity.
367 // It needs more granularity than other components.
368 mHandler.post(new Runnable() {
369 @Override
370 public void run() {
371 mActivityManagerInternal.onWakefulnessChanged(wakefulness);
372 }
373 });
374
Jeff Brown416c49c2015-05-26 19:50:18 -0700375 // Handle any early interactive state changes.
376 // Finish pending incomplete ones from a previous cycle.
377 if (mInteractive != interactive) {
378 // Finish up late behaviors if needed.
379 if (mInteractiveChanging) {
380 handleLateInteractiveChange();
Jeff Brown96307042012-07-27 15:51:34 -0700381 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700382
Jeff Brown416c49c2015-05-26 19:50:18 -0700383 // Start input as soon as we start waking up or going to sleep.
384 mInputManagerInternal.setInteractive(interactive);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700385 mInputMethodManagerInternal.setInteractive(interactive);
Jeff Brown416c49c2015-05-26 19:50:18 -0700386
387 // Notify battery stats.
Jeff Browne95c3cd2014-05-02 16:59:26 -0700388 try {
Jeff Brownfbe96702014-11-19 18:30:58 -0800389 mBatteryStats.noteInteractive(interactive);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700390 } catch (RemoteException ex) { }
Jeff Brown416c49c2015-05-26 19:50:18 -0700391
392 // Handle early behaviors.
393 mInteractive = interactive;
394 mInteractiveChangeReason = reason;
395 mInteractiveChanging = true;
396 handleEarlyInteractiveChange();
397 }
398 }
399
400 /**
401 * Notifies that the device has finished changing wakefulness.
402 */
403 public void onWakefulnessChangeFinished() {
404 if (DEBUG) {
405 Slog.d(TAG, "onWakefulnessChangeFinished");
406 }
407
408 if (mInteractiveChanging) {
409 mInteractiveChanging = false;
410 handleLateInteractiveChange();
411 }
412 }
413
414 /**
415 * Handle early interactive state changes such as getting applications or the lock
416 * screen running and ready for the user to see (such as when turning on the screen).
417 */
418 private void handleEarlyInteractiveChange() {
419 synchronized (mLock) {
420 if (mInteractive) {
421 // Waking up...
422 mHandler.post(new Runnable() {
423 @Override
424 public void run() {
Makoto Onuki5ab5e1d2017-04-14 17:04:26 -0700425 // Note a SCREEN tron event is logged in PowerManagerService.
Jeff Brown416c49c2015-05-26 19:50:18 -0700426 mPolicy.startedWakingUp();
427 }
428 });
429
430 // Send interactive broadcast.
431 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
432 mPendingWakeUpBroadcast = true;
433 updatePendingBroadcastLocked();
434 } else {
435 // Going to sleep...
436 // Tell the policy that we started going to sleep.
437 final int why = translateOffReason(mInteractiveChangeReason);
438 mHandler.post(new Runnable() {
439 @Override
440 public void run() {
441 mPolicy.startedGoingToSleep(why);
442 }
443 });
444 }
445 }
446 }
447
448 /**
449 * Handle late interactive state changes once they are finished so that the system can
450 * finish pending transitions (such as turning the screen off) before causing
451 * applications to change state visibly.
452 */
453 private void handleLateInteractiveChange() {
454 synchronized (mLock) {
455 if (mInteractive) {
456 // Finished waking up...
457 mHandler.post(new Runnable() {
458 @Override
459 public void run() {
460 mPolicy.finishedWakingUp();
461 }
462 });
463 } else {
464 // Finished going to sleep...
465 // This is a good time to make transitions that we don't want the user to see,
466 // such as bringing the key guard to focus. There's no guarantee for this
467 // however because the user could turn the device on again at any time.
468 // Some things may need to be protected by other mechanisms that defer screen on.
469
470 // Cancel pending user activity.
471 if (mUserActivityPending) {
472 mUserActivityPending = false;
473 mHandler.removeMessages(MSG_USER_ACTIVITY);
474 }
475
476 // Tell the policy we finished going to sleep.
477 final int why = translateOffReason(mInteractiveChangeReason);
478 mHandler.post(new Runnable() {
479 @Override
480 public void run() {
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500481 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
482 log.setType(MetricsEvent.TYPE_CLOSE);
483 log.setSubtype(why);
484 MetricsLogger.action(log);
Makoto Onuki5ab5e1d2017-04-14 17:04:26 -0700485 EventLogTags.writePowerScreenState(0, why, 0, 0, 0);
Jeff Brown416c49c2015-05-26 19:50:18 -0700486 mPolicy.finishedGoingToSleep(why);
487 }
488 });
489
490 // Send non-interactive broadcast.
491 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
492 mPendingGoToSleepBroadcast = true;
493 updatePendingBroadcastLocked();
494 }
495 }
496 }
497
498 private static int translateOffReason(int reason) {
499 switch (reason) {
500 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
501 return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
502 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
503 return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
504 default:
505 return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
Jeff Browne95c3cd2014-05-02 16:59:26 -0700506 }
Jeff Brown96307042012-07-27 15:51:34 -0700507 }
508
509 /**
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700510 * Called when screen brightness boost begins or ends.
511 */
512 public void onScreenBrightnessBoostChanged() {
513 if (DEBUG) {
514 Slog.d(TAG, "onScreenBrightnessBoostChanged");
515 }
516
517 mSuspendBlocker.acquire();
518 Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
519 msg.setAsynchronous(true);
520 mHandler.sendMessage(msg);
521 }
Jeff Brown416c49c2015-05-26 19:50:18 -0700522
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700523 /**
Jeff Brown96307042012-07-27 15:51:34 -0700524 * Called when there has been user activity.
525 */
526 public void onUserActivity(int event, int uid) {
527 if (DEBUG) {
528 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
529 }
530
531 try {
532 mBatteryStats.noteUserActivity(uid, event);
533 } catch (RemoteException ex) {
534 // Ignore
535 }
536
537 synchronized (mLock) {
538 if (!mUserActivityPending) {
539 mUserActivityPending = true;
540 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
541 msg.setAsynchronous(true);
542 mHandler.sendMessage(msg);
543 }
544 }
545 }
546
Jeff Brown84e27562012-12-07 13:56:34 -0800547 /**
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700548 * Called when the screen has turned on.
549 */
550 public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
551 if (DEBUG) {
552 Slog.d(TAG, "onWakeUp: event=" + reason + ", reasonUid=" + reasonUid
553 + " opPackageName=" + opPackageName + " opUid=" + opUid);
554 }
555
556 try {
557 mBatteryStats.noteWakeUp(reason, reasonUid);
558 if (opPackageName != null) {
Svet Ganovf7b47252018-02-26 11:11:27 -0800559 mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700560 }
561 } catch (RemoteException ex) {
562 // Ignore
563 }
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700564 }
565
566 /**
Beverlyae79ab92017-12-11 09:20:02 -0500567 * Called when profile screen lock timeout has expired.
Jeff Brown84e27562012-12-07 13:56:34 -0800568 */
Beverlyae79ab92017-12-11 09:20:02 -0500569 public void onProfileTimeout(@UserIdInt int userId) {
570 final Message msg = mHandler.obtainMessage(MSG_PROFILE_TIMED_OUT);
571 msg.setAsynchronous(true);
572 msg.arg1 = userId;
573 mHandler.sendMessage(msg);
574 }
575
576 /**
577 * Called when wireless charging has started so as to provide user feedback (sound and visual).
578 */
579 public void onWirelessChargingStarted(int batteryLevel) {
Jeff Brown84e27562012-12-07 13:56:34 -0800580 if (DEBUG) {
581 Slog.d(TAG, "onWirelessChargingStarted");
582 }
583
584 mSuspendBlocker.acquire();
585 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
586 msg.setAsynchronous(true);
Beverlyae79ab92017-12-11 09:20:02 -0500587 msg.arg1 = batteryLevel;
Pavel Grafov28939982017-10-03 15:11:52 +0100588 mHandler.sendMessage(msg);
589 }
590
Beverlyc1313eb2018-01-31 18:07:21 -0500591 /**
592 * Called when wired charging has started so as to provide user feedback
593 */
594 public void onWiredChargingStarted() {
595 if (DEBUG) {
596 Slog.d(TAG, "onWiredChargingStarted");
597 }
598
599 mSuspendBlocker.acquire();
600 Message msg = mHandler.obtainMessage(MSG_WIRED_CHARGING_STARTED);
601 msg.setAsynchronous(true);
602 mHandler.sendMessage(msg);
603 }
604
Jeff Brown96307042012-07-27 15:51:34 -0700605 private void updatePendingBroadcastLocked() {
606 if (!mBroadcastInProgress
Jeff Brown416c49c2015-05-26 19:50:18 -0700607 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
Jeff Brown54308352012-10-04 17:59:58 -0700608 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700609 || mPendingInteractiveState != mBroadcastedInteractiveState)) {
Jeff Brown96307042012-07-27 15:51:34 -0700610 mBroadcastInProgress = true;
611 mSuspendBlocker.acquire();
612 Message msg = mHandler.obtainMessage(MSG_BROADCAST);
613 msg.setAsynchronous(true);
614 mHandler.sendMessage(msg);
615 }
616 }
617
Jeff Brown54308352012-10-04 17:59:58 -0700618 private void finishPendingBroadcastLocked() {
619 mBroadcastInProgress = false;
620 mSuspendBlocker.release();
621 }
622
Jeff Brown96307042012-07-27 15:51:34 -0700623 private void sendUserActivity() {
624 synchronized (mLock) {
625 if (!mUserActivityPending) {
626 return;
627 }
628 mUserActivityPending = false;
629 }
Jeff Brown96307042012-07-27 15:51:34 -0700630 mPolicy.userActivity();
631 }
632
633 private void sendNextBroadcast() {
634 final int powerState;
Jeff Brown96307042012-07-27 15:51:34 -0700635 synchronized (mLock) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800636 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
Jeff Brown54308352012-10-04 17:59:58 -0700637 // Broadcasted power state is unknown. Send wake up.
638 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800639 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
640 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700641 // Broadcasted power state is awake. Send asleep if needed.
642 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700643 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
Jeff Brown54308352012-10-04 17:59:58 -0700644 mPendingGoToSleepBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800645 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
Jeff Brown54308352012-10-04 17:59:58 -0700646 } else {
647 finishPendingBroadcastLocked();
648 return;
649 }
650 } else {
651 // Broadcasted power state is asleep. Send awake if needed.
652 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700653 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700654 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800655 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
Jeff Brown54308352012-10-04 17:59:58 -0700656 } else {
657 finishPendingBroadcastLocked();
658 return;
659 }
Jeff Brown96307042012-07-27 15:51:34 -0700660 }
661
Jeff Brown96307042012-07-27 15:51:34 -0700662 mBroadcastStartTime = SystemClock.uptimeMillis();
Jeff Brownfbe96702014-11-19 18:30:58 -0800663 powerState = mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700664 }
665
666 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
667
Jeff Brownfbe96702014-11-19 18:30:58 -0800668 if (powerState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown96307042012-07-27 15:51:34 -0700669 sendWakeUpBroadcast();
670 } else {
Jim Millerc522d162014-07-01 17:10:21 -0700671 sendGoToSleepBroadcast();
Jeff Brown96307042012-07-27 15:51:34 -0700672 }
673 }
674
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700675 private void sendBrightnessBoostChangedBroadcast() {
676 if (DEBUG) {
677 Slog.d(TAG, "Sending brightness boost changed broadcast.");
678 }
679
680 mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
681 mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
682 }
683
684 private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
685 @Override
686 public void onReceive(Context context, Intent intent) {
687 mSuspendBlocker.release();
688 }
689 };
690
Jeff Brown96307042012-07-27 15:51:34 -0700691 private void sendWakeUpBroadcast() {
692 if (DEBUG) {
693 Slog.d(TAG, "Sending wake up broadcast.");
694 }
695
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700696 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700697 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700698 mWakeUpBroadcastDone, mHandler, 0, null, null);
699 } else {
700 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
701 sendNextBroadcast();
702 }
703 }
704
705 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
706 @Override
707 public void onReceive(Context context, Intent intent) {
708 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
709 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
710 sendNextBroadcast();
711 }
712 };
713
Jim Millerc522d162014-07-01 17:10:21 -0700714 private void sendGoToSleepBroadcast() {
Jeff Brown96307042012-07-27 15:51:34 -0700715 if (DEBUG) {
716 Slog.d(TAG, "Sending go to sleep broadcast.");
717 }
718
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700719 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700720 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700721 mGoToSleepBroadcastDone, mHandler, 0, null, null);
722 } else {
723 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
724 sendNextBroadcast();
725 }
726 }
727
728 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
729 @Override
730 public void onReceive(Context context, Intent intent) {
731 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
732 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
733 sendNextBroadcast();
734 }
735 };
736
Beverlyc1313eb2018-01-31 18:07:21 -0500737 /**
738 * Plays the wireless charging sound for both wireless and non-wireless charging
739 */
740 private void playChargingStartedSound() {
Jeff Brown84e27562012-12-07 13:56:34 -0800741 final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
Beverlyc1313eb2018-01-31 18:07:21 -0500742 Settings.Global.CHARGING_STARTED_SOUND);
Beverlydf9f36d2018-05-09 17:41:44 -0400743 if (isChargingFeedbackEnabled() && soundPath != null) {
Jeff Brown84e27562012-12-07 13:56:34 -0800744 final Uri soundUri = Uri.parse("file://" + soundPath);
745 if (soundUri != null) {
746 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
747 if (sfx != null) {
748 sfx.setStreamType(AudioManager.STREAM_SYSTEM);
749 sfx.play();
750 }
751 }
752 }
Beverlyae79ab92017-12-11 09:20:02 -0500753 }
Jeff Brown84e27562012-12-07 13:56:34 -0800754
Beverlyae79ab92017-12-11 09:20:02 -0500755 private void showWirelessChargingStarted(int batteryLevel) {
Beverlydf9f36d2018-05-09 17:41:44 -0400756 playWirelessChargingVibration();
Beverlyc1313eb2018-01-31 18:07:21 -0500757 playChargingStartedSound();
Andrew Zeng6d07baf2018-04-20 14:13:16 -0700758 if (mStatusBarManagerInternal != null) {
759 mStatusBarManagerInternal.showChargingAnimation(batteryLevel);
760 }
Jeff Brown84e27562012-12-07 13:56:34 -0800761 mSuspendBlocker.release();
762 }
763
Beverlyc1313eb2018-01-31 18:07:21 -0500764 private void showWiredChargingStarted() {
765 playChargingStartedSound();
766 mSuspendBlocker.release();
767 }
768
Pavel Grafov28939982017-10-03 15:11:52 +0100769 private void lockProfile(@UserIdInt int userId) {
770 mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
771 }
772
Beverlydf9f36d2018-05-09 17:41:44 -0400773 private void playWirelessChargingVibration() {
774 final boolean vibrateEnabled = Settings.Global.getInt(mContext.getContentResolver(),
775 Settings.Global.CHARGING_VIBRATION_ENABLED, 0) != 0;
776 if (vibrateEnabled && isChargingFeedbackEnabled()) {
777 mVibrator.vibrate(WIRELESS_CHARGING_VIBRATION_EFFECT, VIBRATION_ATTRIBUTES);
778 }
779 }
780
781 private boolean isChargingFeedbackEnabled() {
782 final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
783 Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
784 final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
785 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
786 == Settings.Global.ZEN_MODE_OFF;
787 return enabled && dndOff;
788 }
789
Jeff Brown96307042012-07-27 15:51:34 -0700790 private final class NotifierHandler extends Handler {
Pavel Grafov28939982017-10-03 15:11:52 +0100791
Jeff Brown96307042012-07-27 15:51:34 -0700792 public NotifierHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700793 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -0700794 }
Jeff Brown96307042012-07-27 15:51:34 -0700795 @Override
796 public void handleMessage(Message msg) {
797 switch (msg.what) {
798 case MSG_USER_ACTIVITY:
799 sendUserActivity();
800 break;
Jeff Brown96307042012-07-27 15:51:34 -0700801 case MSG_BROADCAST:
802 sendNextBroadcast();
803 break;
Jeff Brown84e27562012-12-07 13:56:34 -0800804 case MSG_WIRELESS_CHARGING_STARTED:
Beverlyae79ab92017-12-11 09:20:02 -0500805 showWirelessChargingStarted(msg.arg1);
Jeff Brown84e27562012-12-07 13:56:34 -0800806 break;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700807 case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
808 sendBrightnessBoostChangedBroadcast();
809 break;
Pavel Grafov28939982017-10-03 15:11:52 +0100810 case MSG_PROFILE_TIMED_OUT:
811 lockProfile(msg.arg1);
812 break;
Beverlyc1313eb2018-01-31 18:07:21 -0500813 case MSG_WIRED_CHARGING_STARTED:
814 showWiredChargingStarted();
Beverlydf9f36d2018-05-09 17:41:44 -0400815 break;
Jeff Brown96307042012-07-27 15:51:34 -0700816 }
817 }
818 }
819}