blob: 8ee26f29957a68b9f94f4fb03ebf78b841601e1c [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
Jeff Brown13014b52014-04-07 19:45:27 -070019import android.app.ActivityManagerInternal;
Dianne Hackborn713df152013-05-17 11:27:57 -070020import android.app.AppOpsManager;
Jeff Brown13014b52014-04-07 19:45:27 -070021
Dianne Hackborn713df152013-05-17 11:27:57 -070022import com.android.internal.app.IAppOpsService;
Jeff Brown96307042012-07-27 15:51:34 -070023import com.android.internal.app.IBatteryStats;
Alison Cichowlas5c38fc22017-01-25 17:11:06 -050024import com.android.internal.logging.MetricsLogger;
25import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Jeff Brown96307042012-07-27 15:51:34 -070026import com.android.server.EventLogTags;
Jeff Brown13014b52014-04-07 19:45:27 -070027import com.android.server.LocalServices;
Adrian Roose99bc052017-11-20 17:55:31 +010028import com.android.server.policy.WindowManagerPolicy;
Jeff Brown96307042012-07-27 15:51:34 -070029
Jeff Brown96307042012-07-27 15:51:34 -070030import android.content.BroadcastReceiver;
31import android.content.Context;
32import android.content.Intent;
Jeff Brown037c33e2014-04-09 00:31:55 -070033import android.hardware.input.InputManagerInternal;
Jeff Brown84e27562012-12-07 13:56:34 -080034import android.media.AudioManager;
35import android.media.Ringtone;
36import android.media.RingtoneManager;
Alison Cichowlas5c38fc22017-01-25 17:11:06 -050037import android.metrics.LogMaker;
Jeff Brown84e27562012-12-07 13:56:34 -080038import android.net.Uri;
Jeff Brown96307042012-07-27 15:51:34 -070039import android.os.BatteryStats;
40import android.os.Handler;
41import android.os.Looper;
42import android.os.Message;
43import android.os.PowerManager;
Jeff Brownfbe96702014-11-19 18:30:58 -080044import android.os.PowerManagerInternal;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -080045import android.os.Process;
Jeff Brown96307042012-07-27 15:51:34 -070046import android.os.RemoteException;
47import android.os.SystemClock;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070048import android.os.UserHandle;
Jeff Brown96307042012-07-27 15:51:34 -070049import android.os.WorkSource;
Jeff Brown84e27562012-12-07 13:56:34 -080050import android.provider.Settings;
Jeff Brown96307042012-07-27 15:51:34 -070051import android.util.EventLog;
52import android.util.Slog;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -070053import android.view.inputmethod.InputMethodManagerInternal;
Jeff Brown96307042012-07-27 15:51:34 -070054
55/**
56 * Sends broadcasts about important power state changes.
Jeff Brown54308352012-10-04 17:59:58 -070057 * <p>
Jeff Brown96307042012-07-27 15:51:34 -070058 * This methods of this class may be called by the power manager service while
59 * its lock is being held. Internally it takes care of sending broadcasts to
60 * notify other components of the system or applications asynchronously.
Jeff Brown54308352012-10-04 17:59:58 -070061 * </p><p>
Jeff Brown96307042012-07-27 15:51:34 -070062 * The notifier is designed to collapse unnecessary broadcasts when it is not
63 * possible for the system to have observed an intermediate state.
Jeff Brown54308352012-10-04 17:59:58 -070064 * </p><p>
65 * For example, if the device wakes up, goes to sleep, wakes up again and goes to
66 * sleep again before the wake up notification is sent, then the system will
67 * be told about only one wake up and sleep. However, we always notify the
68 * fact that at least one transition occurred. It is especially important to
69 * tell the system when we go to sleep so that it can lock the keyguard if needed.
70 * </p>
Jeff Brown96307042012-07-27 15:51:34 -070071 */
72final class Notifier {
73 private static final String TAG = "PowerManagerNotifier";
74
75 private static final boolean DEBUG = false;
76
Jeff Brownfbe96702014-11-19 18:30:58 -080077 private static final int INTERACTIVE_STATE_UNKNOWN = 0;
78 private static final int INTERACTIVE_STATE_AWAKE = 1;
79 private static final int INTERACTIVE_STATE_ASLEEP = 2;
Jeff Brown96307042012-07-27 15:51:34 -070080
81 private static final int MSG_USER_ACTIVITY = 1;
82 private static final int MSG_BROADCAST = 2;
Jeff Brown84e27562012-12-07 13:56:34 -080083 private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
Bryce Lee84d6c0f2015-03-17 10:43:08 -070084 private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;
Jeff Brown96307042012-07-27 15:51:34 -070085
86 private final Object mLock = new Object();
87
88 private final Context mContext;
89 private final IBatteryStats mBatteryStats;
Dianne Hackborn713df152013-05-17 11:27:57 -070090 private final IAppOpsService mAppOps;
Jeff Brown96307042012-07-27 15:51:34 -070091 private final SuspendBlocker mSuspendBlocker;
92 private final WindowManagerPolicy mPolicy;
Jeff Brown13014b52014-04-07 19:45:27 -070093 private final ActivityManagerInternal mActivityManagerInternal;
Jeff Brown037c33e2014-04-09 00:31:55 -070094 private final InputManagerInternal mInputManagerInternal;
Yohei Yukawafa6e0a82015-07-23 15:08:59 -070095 private final InputMethodManagerInternal mInputMethodManagerInternal;
Jeff Brown96307042012-07-27 15:51:34 -070096
97 private final NotifierHandler mHandler;
98 private final Intent mScreenOnIntent;
99 private final Intent mScreenOffIntent;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700100 private final Intent mScreenBrightnessBoostIntent;
Jeff Brown96307042012-07-27 15:51:34 -0700101
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700102 // True if the device should suspend when the screen is off due to proximity.
103 private final boolean mSuspendWhenScreenOffDueToProximityConfig;
104
Jeff Brown416c49c2015-05-26 19:50:18 -0700105 // The current interactive state. This is set as soon as an interactive state
106 // transition begins so as to capture the reason that it happened. At some point
107 // this state will propagate to the pending state then eventually to the
108 // broadcasted state over the course of reporting the transition asynchronously.
109 private boolean mInteractive = true;
110 private int mInteractiveChangeReason;
111 private boolean mInteractiveChanging;
Jeff Brown96307042012-07-27 15:51:34 -0700112
Jeff Brown416c49c2015-05-26 19:50:18 -0700113 // The pending interactive state that we will eventually want to broadcast.
114 // This is designed so that we can collapse redundant sequences of awake/sleep
115 // transition pairs while still guaranteeing that at least one transition is observed
116 // whenever this happens.
117 private int mPendingInteractiveState;
Jeff Brown54308352012-10-04 17:59:58 -0700118 private boolean mPendingWakeUpBroadcast;
119 private boolean mPendingGoToSleepBroadcast;
120
Jeff Brownfbe96702014-11-19 18:30:58 -0800121 // The currently broadcasted interactive state. This reflects what other parts of the
Jeff Brown96307042012-07-27 15:51:34 -0700122 // system have observed.
Jeff Brownfbe96702014-11-19 18:30:58 -0800123 private int mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700124 private boolean mBroadcastInProgress;
125 private long mBroadcastStartTime;
126
127 // True if a user activity message should be sent.
128 private boolean mUserActivityPending;
129
130 public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
Jeff Brown3ee549c2014-09-22 20:14:39 -0700131 IAppOpsService appOps, SuspendBlocker suspendBlocker,
Jeff Brownc38c9be2012-10-04 13:16:19 -0700132 WindowManagerPolicy policy) {
Jeff Brown96307042012-07-27 15:51:34 -0700133 mContext = context;
134 mBatteryStats = batteryStats;
Dianne Hackborn713df152013-05-17 11:27:57 -0700135 mAppOps = appOps;
Jeff Brown96307042012-07-27 15:51:34 -0700136 mSuspendBlocker = suspendBlocker;
137 mPolicy = policy;
Jeff Brown13014b52014-04-07 19:45:27 -0700138 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
Jeff Brown037c33e2014-04-09 00:31:55 -0700139 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700140 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
Jeff Brown96307042012-07-27 15:51:34 -0700141
142 mHandler = new NotifierHandler(looper);
143 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
144 mScreenOnIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700145 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
146 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Jeff Brown96307042012-07-27 15:51:34 -0700147 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
148 mScreenOffIntent.addFlags(
Chad Brubaker291df4f2017-03-14 10:23:02 -0700149 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
150 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700151 mScreenBrightnessBoostIntent =
152 new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
153 mScreenBrightnessBoostIntent.addFlags(
154 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700155
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700156 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
157 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
158
Jeff Browne95c3cd2014-05-02 16:59:26 -0700159 // Initialize interactive state for battery stats.
160 try {
161 mBatteryStats.noteInteractive(true);
162 } catch (RemoteException ex) { }
Jeff Brown96307042012-07-27 15:51:34 -0700163 }
164
165 /**
166 * Called when a wake lock is acquired.
167 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700168 public void onWakeLockAcquired(int flags, String tag, String packageName,
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800169 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700170 if (DEBUG) {
171 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700172 + "\", packageName=" + packageName
173 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700174 + ", workSource=" + workSource);
175 }
176
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700177 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
178 if (monitorType >= 0) {
179 try {
180 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
181 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
182 if (workSource != null) {
183 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
184 historyTag, monitorType, unimportantForLogging);
185 } else {
186 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
187 monitorType, unimportantForLogging);
188 // XXX need to deal with disabled operations.
189 mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
190 AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
191 }
192 } catch (RemoteException ex) {
193 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700194 }
195 }
196 }
197
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700198 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource,
199 String historyTag) {
200 if (DEBUG) {
201 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid
202 + ", workSource=" + workSource);
203 }
204
205 try {
206 if (workSource != null) {
207 final int N = workSource.size();
208 for (int i=0; i<N; i++) {
209 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, workSource.get(i));
210 }
211 } else {
212 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid);
213 }
214 } catch (RemoteException ex) {
215 // Ignore
216 }
217 }
218
219 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource,
220 String historyTag) {
221 if (DEBUG) {
222 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid
223 + ", workSource=" + workSource);
224 }
225
226 try {
227 if (workSource != null) {
228 final int N = workSource.size();
229 for (int i=0; i<N; i++) {
230 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, workSource.get(i));
231 }
232 } else {
233 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid);
234 }
235 } catch (RemoteException ex) {
236 // Ignore
237 }
238 }
239
Jeff Brown96307042012-07-27 15:51:34 -0700240 /**
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800241 * Called when a wake lock is changing.
242 */
243 public void onWakeLockChanging(int flags, String tag, String packageName,
244 int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
245 int newFlags, String newTag, String newPackageName, int newOwnerUid,
246 int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
247
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700248 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
249 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
250 if (workSource != null && newWorkSource != null
251 && monitorType >= 0 && newMonitorType >= 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800252 if (DEBUG) {
253 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
254 + "\", packageName=" + newPackageName
255 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
256 + ", workSource=" + newWorkSource);
257 }
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700258
259 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID
260 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800261 try {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700262 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag,
263 monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800264 newMonitorType, unimportantForLogging);
265 } catch (RemoteException ex) {
266 // Ignore
267 }
268 } else {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700269 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800270 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
271 newWorkSource, newHistoryTag);
272 }
273 }
274
275 /**
Jeff Brown96307042012-07-27 15:51:34 -0700276 * Called when a wake lock is released.
277 */
Dianne Hackborn713df152013-05-17 11:27:57 -0700278 public void onWakeLockReleased(int flags, String tag, String packageName,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700279 int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
Jeff Brown96307042012-07-27 15:51:34 -0700280 if (DEBUG) {
281 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
Dianne Hackborn713df152013-05-17 11:27:57 -0700282 + "\", packageName=" + packageName
283 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
Jeff Brown96307042012-07-27 15:51:34 -0700284 + ", workSource=" + workSource);
285 }
286
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700287 final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
288 if (monitorType >= 0) {
289 try {
290 if (workSource != null) {
291 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
292 historyTag, monitorType);
293 } else {
294 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
295 historyTag, monitorType);
296 mAppOps.finishOperation(AppOpsManager.getToken(mAppOps),
297 AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
298 }
299 } catch (RemoteException ex) {
300 // Ignore
Jeff Brown96307042012-07-27 15:51:34 -0700301 }
302 }
303 }
304
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700305 private int getBatteryStatsWakeLockMonitorType(int flags) {
Jeff Brown96307042012-07-27 15:51:34 -0700306 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
307 case PowerManager.PARTIAL_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700308 return BatteryStats.WAKE_TYPE_PARTIAL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700309
310 case PowerManager.SCREEN_DIM_WAKE_LOCK:
311 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
Jeff Brown96307042012-07-27 15:51:34 -0700312 return BatteryStats.WAKE_TYPE_FULL;
Jeff Brownc4bd42c2015-06-12 18:00:11 -0700313
314 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
315 if (mSuspendWhenScreenOffDueToProximityConfig) {
316 return -1;
317 }
318 return BatteryStats.WAKE_TYPE_PARTIAL;
319
320 case PowerManager.DRAW_WAKE_LOCK:
321 return BatteryStats.WAKE_TYPE_DRAW;
322
323 case PowerManager.DOZE_WAKE_LOCK:
324 // Doze wake locks are an internal implementation detail of the
325 // communication between dream manager service and power manager
326 // service. They have no additive battery impact.
327 return -1;
328
329 default:
330 return -1;
Jeff Brown96307042012-07-27 15:51:34 -0700331 }
332 }
333
334 /**
Jeff Brownfbe96702014-11-19 18:30:58 -0800335 * Notifies that the device is changing wakefulness.
Jeff Brown416c49c2015-05-26 19:50:18 -0700336 * This function may be called even if the previous change hasn't finished in
337 * which case it will assume that the state did not fully converge before the
338 * next transition began and will recover accordingly.
Jeff Brown96307042012-07-27 15:51:34 -0700339 */
Jeff Brown416c49c2015-05-26 19:50:18 -0700340 public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
341 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
Jeff Brown96307042012-07-27 15:51:34 -0700342 if (DEBUG) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800343 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
Jeff Brown416c49c2015-05-26 19:50:18 -0700344 + ", reason=" + reason + ", interactive=" + interactive);
Jeff Brown96307042012-07-27 15:51:34 -0700345 }
346
Jeff Brownfbe96702014-11-19 18:30:58 -0800347 // Tell the activity manager about changes in wakefulness, not just interactivity.
348 // It needs more granularity than other components.
349 mHandler.post(new Runnable() {
350 @Override
351 public void run() {
352 mActivityManagerInternal.onWakefulnessChanged(wakefulness);
353 }
354 });
355
Jeff Brown416c49c2015-05-26 19:50:18 -0700356 // Handle any early interactive state changes.
357 // Finish pending incomplete ones from a previous cycle.
358 if (mInteractive != interactive) {
359 // Finish up late behaviors if needed.
360 if (mInteractiveChanging) {
361 handleLateInteractiveChange();
Jeff Brown96307042012-07-27 15:51:34 -0700362 }
Jeff Browne95c3cd2014-05-02 16:59:26 -0700363
Jeff Brown416c49c2015-05-26 19:50:18 -0700364 // Start input as soon as we start waking up or going to sleep.
365 mInputManagerInternal.setInteractive(interactive);
Yohei Yukawafa6e0a82015-07-23 15:08:59 -0700366 mInputMethodManagerInternal.setInteractive(interactive);
Jeff Brown416c49c2015-05-26 19:50:18 -0700367
368 // Notify battery stats.
Jeff Browne95c3cd2014-05-02 16:59:26 -0700369 try {
Jeff Brownfbe96702014-11-19 18:30:58 -0800370 mBatteryStats.noteInteractive(interactive);
Jeff Browne95c3cd2014-05-02 16:59:26 -0700371 } catch (RemoteException ex) { }
Jeff Brown416c49c2015-05-26 19:50:18 -0700372
373 // Handle early behaviors.
374 mInteractive = interactive;
375 mInteractiveChangeReason = reason;
376 mInteractiveChanging = true;
377 handleEarlyInteractiveChange();
378 }
379 }
380
381 /**
382 * Notifies that the device has finished changing wakefulness.
383 */
384 public void onWakefulnessChangeFinished() {
385 if (DEBUG) {
386 Slog.d(TAG, "onWakefulnessChangeFinished");
387 }
388
389 if (mInteractiveChanging) {
390 mInteractiveChanging = false;
391 handleLateInteractiveChange();
392 }
393 }
394
395 /**
396 * Handle early interactive state changes such as getting applications or the lock
397 * screen running and ready for the user to see (such as when turning on the screen).
398 */
399 private void handleEarlyInteractiveChange() {
400 synchronized (mLock) {
401 if (mInteractive) {
402 // Waking up...
403 mHandler.post(new Runnable() {
404 @Override
405 public void run() {
Makoto Onuki5ab5e1d2017-04-14 17:04:26 -0700406 // Note a SCREEN tron event is logged in PowerManagerService.
Jeff Brown416c49c2015-05-26 19:50:18 -0700407 mPolicy.startedWakingUp();
408 }
409 });
410
411 // Send interactive broadcast.
412 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
413 mPendingWakeUpBroadcast = true;
414 updatePendingBroadcastLocked();
415 } else {
416 // Going to sleep...
417 // Tell the policy that we started going to sleep.
418 final int why = translateOffReason(mInteractiveChangeReason);
419 mHandler.post(new Runnable() {
420 @Override
421 public void run() {
422 mPolicy.startedGoingToSleep(why);
423 }
424 });
425 }
426 }
427 }
428
429 /**
430 * Handle late interactive state changes once they are finished so that the system can
431 * finish pending transitions (such as turning the screen off) before causing
432 * applications to change state visibly.
433 */
434 private void handleLateInteractiveChange() {
435 synchronized (mLock) {
436 if (mInteractive) {
437 // Finished waking up...
438 mHandler.post(new Runnable() {
439 @Override
440 public void run() {
441 mPolicy.finishedWakingUp();
442 }
443 });
444 } else {
445 // Finished going to sleep...
446 // This is a good time to make transitions that we don't want the user to see,
447 // such as bringing the key guard to focus. There's no guarantee for this
448 // however because the user could turn the device on again at any time.
449 // Some things may need to be protected by other mechanisms that defer screen on.
450
451 // Cancel pending user activity.
452 if (mUserActivityPending) {
453 mUserActivityPending = false;
454 mHandler.removeMessages(MSG_USER_ACTIVITY);
455 }
456
457 // Tell the policy we finished going to sleep.
458 final int why = translateOffReason(mInteractiveChangeReason);
459 mHandler.post(new Runnable() {
460 @Override
461 public void run() {
Alison Cichowlas5c38fc22017-01-25 17:11:06 -0500462 LogMaker log = new LogMaker(MetricsEvent.SCREEN);
463 log.setType(MetricsEvent.TYPE_CLOSE);
464 log.setSubtype(why);
465 MetricsLogger.action(log);
Makoto Onuki5ab5e1d2017-04-14 17:04:26 -0700466 EventLogTags.writePowerScreenState(0, why, 0, 0, 0);
Jeff Brown416c49c2015-05-26 19:50:18 -0700467 mPolicy.finishedGoingToSleep(why);
468 }
469 });
470
471 // Send non-interactive broadcast.
472 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
473 mPendingGoToSleepBroadcast = true;
474 updatePendingBroadcastLocked();
475 }
476 }
477 }
478
479 private static int translateOffReason(int reason) {
480 switch (reason) {
481 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:
482 return WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;
483 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:
484 return WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
485 default:
486 return WindowManagerPolicy.OFF_BECAUSE_OF_USER;
Jeff Browne95c3cd2014-05-02 16:59:26 -0700487 }
Jeff Brown96307042012-07-27 15:51:34 -0700488 }
489
490 /**
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700491 * Called when screen brightness boost begins or ends.
492 */
493 public void onScreenBrightnessBoostChanged() {
494 if (DEBUG) {
495 Slog.d(TAG, "onScreenBrightnessBoostChanged");
496 }
497
498 mSuspendBlocker.acquire();
499 Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
500 msg.setAsynchronous(true);
501 mHandler.sendMessage(msg);
502 }
Jeff Brown416c49c2015-05-26 19:50:18 -0700503
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700504 /**
Jeff Brown96307042012-07-27 15:51:34 -0700505 * Called when there has been user activity.
506 */
507 public void onUserActivity(int event, int uid) {
508 if (DEBUG) {
509 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid);
510 }
511
512 try {
513 mBatteryStats.noteUserActivity(uid, event);
514 } catch (RemoteException ex) {
515 // Ignore
516 }
517
518 synchronized (mLock) {
519 if (!mUserActivityPending) {
520 mUserActivityPending = true;
521 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
522 msg.setAsynchronous(true);
523 mHandler.sendMessage(msg);
524 }
525 }
526 }
527
Jeff Brown84e27562012-12-07 13:56:34 -0800528 /**
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700529 * Called when the screen has turned on.
530 */
531 public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
532 if (DEBUG) {
533 Slog.d(TAG, "onWakeUp: event=" + reason + ", reasonUid=" + reasonUid
534 + " opPackageName=" + opPackageName + " opUid=" + opUid);
535 }
536
537 try {
538 mBatteryStats.noteWakeUp(reason, reasonUid);
539 if (opPackageName != null) {
540 mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
541 }
542 } catch (RemoteException ex) {
543 // Ignore
544 }
545
546 }
547
548 /**
Jeff Brown84e27562012-12-07 13:56:34 -0800549 * Called when wireless charging has started so as to provide user feedback.
550 */
551 public void onWirelessChargingStarted() {
552 if (DEBUG) {
553 Slog.d(TAG, "onWirelessChargingStarted");
554 }
555
556 mSuspendBlocker.acquire();
557 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
558 msg.setAsynchronous(true);
559 mHandler.sendMessage(msg);
560 }
561
Jeff Brown96307042012-07-27 15:51:34 -0700562 private void updatePendingBroadcastLocked() {
563 if (!mBroadcastInProgress
Jeff Brown416c49c2015-05-26 19:50:18 -0700564 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
Jeff Brown54308352012-10-04 17:59:58 -0700565 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700566 || mPendingInteractiveState != mBroadcastedInteractiveState)) {
Jeff Brown96307042012-07-27 15:51:34 -0700567 mBroadcastInProgress = true;
568 mSuspendBlocker.acquire();
569 Message msg = mHandler.obtainMessage(MSG_BROADCAST);
570 msg.setAsynchronous(true);
571 mHandler.sendMessage(msg);
572 }
573 }
574
Jeff Brown54308352012-10-04 17:59:58 -0700575 private void finishPendingBroadcastLocked() {
576 mBroadcastInProgress = false;
577 mSuspendBlocker.release();
578 }
579
Jeff Brown96307042012-07-27 15:51:34 -0700580 private void sendUserActivity() {
581 synchronized (mLock) {
582 if (!mUserActivityPending) {
583 return;
584 }
585 mUserActivityPending = false;
586 }
Jeff Brown96307042012-07-27 15:51:34 -0700587 mPolicy.userActivity();
588 }
589
590 private void sendNextBroadcast() {
591 final int powerState;
Jeff Brown96307042012-07-27 15:51:34 -0700592 synchronized (mLock) {
Jeff Brownfbe96702014-11-19 18:30:58 -0800593 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) {
Jeff Brown54308352012-10-04 17:59:58 -0700594 // Broadcasted power state is unknown. Send wake up.
595 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800596 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
597 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700598 // Broadcasted power state is awake. Send asleep if needed.
599 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700600 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) {
Jeff Brown54308352012-10-04 17:59:58 -0700601 mPendingGoToSleepBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800602 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP;
Jeff Brown54308352012-10-04 17:59:58 -0700603 } else {
604 finishPendingBroadcastLocked();
605 return;
606 }
607 } else {
608 // Broadcasted power state is asleep. Send awake if needed.
609 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
Jeff Brown416c49c2015-05-26 19:50:18 -0700610 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown54308352012-10-04 17:59:58 -0700611 mPendingWakeUpBroadcast = false;
Jeff Brownfbe96702014-11-19 18:30:58 -0800612 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE;
Jeff Brown54308352012-10-04 17:59:58 -0700613 } else {
614 finishPendingBroadcastLocked();
615 return;
616 }
Jeff Brown96307042012-07-27 15:51:34 -0700617 }
618
Jeff Brown96307042012-07-27 15:51:34 -0700619 mBroadcastStartTime = SystemClock.uptimeMillis();
Jeff Brownfbe96702014-11-19 18:30:58 -0800620 powerState = mBroadcastedInteractiveState;
Jeff Brown96307042012-07-27 15:51:34 -0700621 }
622
623 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1);
624
Jeff Brownfbe96702014-11-19 18:30:58 -0800625 if (powerState == INTERACTIVE_STATE_AWAKE) {
Jeff Brown96307042012-07-27 15:51:34 -0700626 sendWakeUpBroadcast();
627 } else {
Jim Millerc522d162014-07-01 17:10:21 -0700628 sendGoToSleepBroadcast();
Jeff Brown96307042012-07-27 15:51:34 -0700629 }
630 }
631
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700632 private void sendBrightnessBoostChangedBroadcast() {
633 if (DEBUG) {
634 Slog.d(TAG, "Sending brightness boost changed broadcast.");
635 }
636
637 mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
638 mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
639 }
640
641 private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
642 @Override
643 public void onReceive(Context context, Intent intent) {
644 mSuspendBlocker.release();
645 }
646 };
647
Jeff Brown96307042012-07-27 15:51:34 -0700648 private void sendWakeUpBroadcast() {
649 if (DEBUG) {
650 Slog.d(TAG, "Sending wake up broadcast.");
651 }
652
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700653 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700654 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700655 mWakeUpBroadcastDone, mHandler, 0, null, null);
656 } else {
657 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
658 sendNextBroadcast();
659 }
660 }
661
662 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
663 @Override
664 public void onReceive(Context context, Intent intent) {
665 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
666 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
667 sendNextBroadcast();
668 }
669 };
670
Jim Millerc522d162014-07-01 17:10:21 -0700671 private void sendGoToSleepBroadcast() {
Jeff Brown96307042012-07-27 15:51:34 -0700672 if (DEBUG) {
673 Slog.d(TAG, "Sending go to sleep broadcast.");
674 }
675
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700676 if (mActivityManagerInternal.isSystemReady()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700677 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null,
Jeff Brown96307042012-07-27 15:51:34 -0700678 mGoToSleepBroadcastDone, mHandler, 0, null, null);
679 } else {
680 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1);
681 sendNextBroadcast();
682 }
683 }
684
685 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() {
686 @Override
687 public void onReceive(Context context, Intent intent) {
688 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
689 SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
690 sendNextBroadcast();
691 }
692 };
693
Jeff Brown84e27562012-12-07 13:56:34 -0800694 private void playWirelessChargingStartedSound() {
John Spurlock51a871d2015-05-06 17:41:30 -0400695 final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
696 Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
Jeff Brown84e27562012-12-07 13:56:34 -0800697 final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
698 Settings.Global.WIRELESS_CHARGING_STARTED_SOUND);
John Spurlock51a871d2015-05-06 17:41:30 -0400699 if (enabled && soundPath != null) {
Jeff Brown84e27562012-12-07 13:56:34 -0800700 final Uri soundUri = Uri.parse("file://" + soundPath);
701 if (soundUri != null) {
702 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
703 if (sfx != null) {
704 sfx.setStreamType(AudioManager.STREAM_SYSTEM);
705 sfx.play();
706 }
707 }
708 }
709
710 mSuspendBlocker.release();
711 }
712
Jeff Brown96307042012-07-27 15:51:34 -0700713 private final class NotifierHandler extends Handler {
714 public NotifierHandler(Looper looper) {
Jeff Browna2910d02012-08-25 12:29:46 -0700715 super(looper, null, true /*async*/);
Jeff Brown96307042012-07-27 15:51:34 -0700716 }
717
718 @Override
719 public void handleMessage(Message msg) {
720 switch (msg.what) {
721 case MSG_USER_ACTIVITY:
722 sendUserActivity();
723 break;
724
725 case MSG_BROADCAST:
726 sendNextBroadcast();
727 break;
Jeff Brown84e27562012-12-07 13:56:34 -0800728
729 case MSG_WIRELESS_CHARGING_STARTED:
730 playWirelessChargingStartedSound();
731 break;
Bryce Lee84d6c0f2015-03-17 10:43:08 -0700732 case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
733 sendBrightnessBoostChangedBroadcast();
734 break;
Jeff Brown96307042012-07-27 15:51:34 -0700735 }
736 }
737 }
738}