1 /* 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 17 package com.android.server.power; 18 19 import android.annotation.Nullable; 20 import android.annotation.UserIdInt; 21 import android.app.ActivityManagerInternal; 22 import android.app.AppOpsManager; 23 import android.app.trust.TrustManager; 24 import android.content.BroadcastReceiver; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.hardware.display.DisplayManagerInternal; 28 import android.hardware.input.InputManagerInternal; 29 import android.media.AudioManager; 30 import android.media.Ringtone; 31 import android.media.RingtoneManager; 32 import android.metrics.LogMaker; 33 import android.net.Uri; 34 import android.os.BatteryStats; 35 import android.os.Handler; 36 import android.os.IWakeLockCallback; 37 import android.os.Looper; 38 import android.os.Message; 39 import android.os.PowerManager; 40 import android.os.PowerManagerInternal; 41 import android.os.Process; 42 import android.os.RemoteException; 43 import android.os.SystemClock; 44 import android.os.UserHandle; 45 import android.os.VibrationAttributes; 46 import android.os.VibrationEffect; 47 import android.os.Vibrator; 48 import android.os.WorkSource; 49 import android.provider.Settings; 50 import android.telephony.TelephonyManager; 51 import android.util.EventLog; 52 import android.util.Slog; 53 import android.view.WindowManagerPolicyConstants; 54 55 import com.android.internal.annotations.VisibleForTesting; 56 import com.android.internal.app.IBatteryStats; 57 import com.android.internal.logging.MetricsLogger; 58 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 59 import com.android.internal.util.FrameworkStatsLog; 60 import com.android.server.EventLogTags; 61 import com.android.server.LocalServices; 62 import com.android.server.inputmethod.InputMethodManagerInternal; 63 import com.android.server.policy.WindowManagerPolicy; 64 import com.android.server.statusbar.StatusBarManagerInternal; 65 66 import java.io.PrintWriter; 67 import java.util.concurrent.Executor; 68 import java.util.concurrent.atomic.AtomicBoolean; 69 70 /** 71 * Sends broadcasts about important power state changes. 72 * <p> 73 * This methods of this class may be called by the power manager service while 74 * its lock is being held. Internally it takes care of sending broadcasts to 75 * notify other components of the system or applications asynchronously. 76 * </p><p> 77 * The notifier is designed to collapse unnecessary broadcasts when it is not 78 * possible for the system to have observed an intermediate state. 79 * </p><p> 80 * For example, if the device wakes up, goes to sleep, wakes up again and goes to 81 * sleep again before the wake up notification is sent, then the system will 82 * be told about only one wake up and sleep. However, we always notify the 83 * fact that at least one transition occurred. It is especially important to 84 * tell the system when we go to sleep so that it can lock the keyguard if needed. 85 * </p> 86 */ 87 @VisibleForTesting 88 public class Notifier { 89 private static final String TAG = "PowerManagerNotifier"; 90 91 private static final boolean DEBUG = false; 92 93 private static final int INTERACTIVE_STATE_UNKNOWN = 0; 94 private static final int INTERACTIVE_STATE_AWAKE = 1; 95 private static final int INTERACTIVE_STATE_ASLEEP = 2; 96 97 private static final int MSG_USER_ACTIVITY = 1; 98 private static final int MSG_BROADCAST = 2; 99 private static final int MSG_WIRELESS_CHARGING_STARTED = 3; 100 private static final int MSG_BROADCAST_ENHANCED_PREDICTION = 4; 101 private static final int MSG_PROFILE_TIMED_OUT = 5; 102 private static final int MSG_WIRED_CHARGING_STARTED = 6; 103 private static final int MSG_SCREEN_POLICY = 7; 104 105 private static final long[] CHARGING_VIBRATION_TIME = { 106 40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms 107 40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms 108 }; 109 private static final int[] CHARGING_VIBRATION_AMPLITUDE = { 110 1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%) 111 103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude 112 }; 113 private static final VibrationEffect CHARGING_VIBRATION_EFFECT = 114 VibrationEffect.createWaveform(CHARGING_VIBRATION_TIME, CHARGING_VIBRATION_AMPLITUDE, 115 -1); 116 private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = 117 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); 118 119 private final Object mLock = new Object(); 120 121 private final Context mContext; 122 private final IBatteryStats mBatteryStats; 123 private final AppOpsManager mAppOps; 124 private final SuspendBlocker mSuspendBlocker; 125 private final WindowManagerPolicy mPolicy; 126 private final FaceDownDetector mFaceDownDetector; 127 private final ScreenUndimDetector mScreenUndimDetector; 128 private final ActivityManagerInternal mActivityManagerInternal; 129 private final InputManagerInternal mInputManagerInternal; 130 private final InputMethodManagerInternal mInputMethodManagerInternal; 131 @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal; 132 private final TrustManager mTrustManager; 133 private final Vibrator mVibrator; 134 private final WakeLockLog mWakeLockLog; 135 private final DisplayManagerInternal mDisplayManagerInternal; 136 137 private final NotifierHandler mHandler; 138 private final Executor mBackgroundExecutor; 139 private final Intent mScreenOnIntent; 140 private final Intent mScreenOffIntent; 141 142 // True if the device should suspend when the screen is off due to proximity. 143 private final boolean mSuspendWhenScreenOffDueToProximityConfig; 144 145 // True if the device should show the wireless charging animation when the device 146 // begins charging wirelessly 147 private final boolean mShowWirelessChargingAnimationConfig; 148 149 // The current interactive state. This is set as soon as an interactive state 150 // transition begins so as to capture the reason that it happened. At some point 151 // this state will propagate to the pending state then eventually to the 152 // broadcasted state over the course of reporting the transition asynchronously. 153 private boolean mInteractive = true; 154 private int mInteractiveChangeReason; 155 private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis() 156 private boolean mInteractiveChanging; 157 158 // The pending interactive state that we will eventually want to broadcast. 159 // This is designed so that we can collapse redundant sequences of awake/sleep 160 // transition pairs while still guaranteeing that at least one transition is observed 161 // whenever this happens. 162 private int mPendingInteractiveState; 163 private boolean mPendingWakeUpBroadcast; 164 private boolean mPendingGoToSleepBroadcast; 165 166 // The currently broadcasted interactive state. This reflects what other parts of the 167 // system have observed. 168 private int mBroadcastedInteractiveState; 169 private boolean mBroadcastInProgress; 170 private long mBroadcastStartTime; 171 172 // True if a user activity message should be sent. 173 private boolean mUserActivityPending; 174 175 private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false); 176 Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor)177 public Notifier(Looper looper, Context context, IBatteryStats batteryStats, 178 SuspendBlocker suspendBlocker, WindowManagerPolicy policy, 179 FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, 180 Executor backgroundExecutor) { 181 mContext = context; 182 mBatteryStats = batteryStats; 183 mAppOps = mContext.getSystemService(AppOpsManager.class); 184 mSuspendBlocker = suspendBlocker; 185 mPolicy = policy; 186 mFaceDownDetector = faceDownDetector; 187 mScreenUndimDetector = screenUndimDetector; 188 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 189 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 190 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class); 191 mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class); 192 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 193 mTrustManager = mContext.getSystemService(TrustManager.class); 194 mVibrator = mContext.getSystemService(Vibrator.class); 195 196 mHandler = new NotifierHandler(looper); 197 mBackgroundExecutor = backgroundExecutor; 198 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); 199 mScreenOnIntent.addFlags( 200 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND 201 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 202 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); 203 mScreenOffIntent.addFlags( 204 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND 205 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 206 207 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean( 208 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity); 209 mShowWirelessChargingAnimationConfig = context.getResources().getBoolean( 210 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim); 211 212 mWakeLockLog = new WakeLockLog(); 213 214 // Initialize interactive state for battery stats. 215 try { 216 mBatteryStats.noteInteractive(true); 217 } catch (RemoteException ex) { } 218 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, 219 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON); 220 } 221 222 /** 223 * Called when a wake lock is acquired. 224 */ onWakeLockAcquired(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback)225 public void onWakeLockAcquired(int flags, String tag, String packageName, 226 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 227 IWakeLockCallback callback) { 228 if (DEBUG) { 229 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag 230 + "\", packageName=" + packageName 231 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 232 + ", workSource=" + workSource); 233 } 234 notifyWakeLockListener(callback, true); 235 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 236 if (monitorType >= 0) { 237 try { 238 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID 239 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; 240 if (workSource != null) { 241 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, 242 historyTag, monitorType, unimportantForLogging); 243 } else { 244 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag, 245 monitorType, unimportantForLogging); 246 // XXX need to deal with disabled operations. 247 mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName); 248 } 249 } catch (RemoteException ex) { 250 // Ignore 251 } 252 } 253 254 mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags); 255 } 256 onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource, String historyTag)257 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource, 258 String historyTag) { 259 if (DEBUG) { 260 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid 261 + ", workSource=" + workSource); 262 } 263 264 try { 265 if (workSource != null) { 266 mBatteryStats.noteLongPartialWakelockStartFromSource(tag, historyTag, workSource); 267 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 268 workSource, tag, historyTag, 269 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 270 } else { 271 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid); 272 FrameworkStatsLog.write_non_chained( 273 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag, 274 historyTag, 275 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 276 } 277 } catch (RemoteException ex) { 278 // Ignore 279 } 280 } 281 onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource, String historyTag)282 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource, 283 String historyTag) { 284 if (DEBUG) { 285 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid 286 + ", workSource=" + workSource); 287 } 288 289 try { 290 if (workSource != null) { 291 mBatteryStats.noteLongPartialWakelockFinishFromSource(tag, historyTag, workSource); 292 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 293 workSource, tag, historyTag, 294 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 295 } else { 296 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid); 297 FrameworkStatsLog.write_non_chained( 298 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag, 299 historyTag, 300 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 301 } 302 } catch (RemoteException ex) { 303 // Ignore 304 } 305 } 306 307 /** 308 * Called when a wake lock is changing. 309 */ onWakeLockChanging(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback, int newFlags, String newTag, String newPackageName, int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag, IWakeLockCallback newCallback)310 public void onWakeLockChanging(int flags, String tag, String packageName, 311 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 312 IWakeLockCallback callback, int newFlags, String newTag, String newPackageName, 313 int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag, 314 IWakeLockCallback newCallback) { 315 316 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 317 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags); 318 if (workSource != null && newWorkSource != null 319 && monitorType >= 0 && newMonitorType >= 0) { 320 if (DEBUG) { 321 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag 322 + "\", packageName=" + newPackageName 323 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid 324 + ", workSource=" + newWorkSource); 325 } 326 327 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID 328 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; 329 try { 330 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, historyTag, 331 monitorType, newWorkSource, newOwnerPid, newTag, newHistoryTag, 332 newMonitorType, unimportantForLogging); 333 } catch (RemoteException ex) { 334 // Ignore 335 } 336 } else if (!PowerManagerService.isSameCallback(callback, newCallback)) { 337 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, 338 null /* Do not notify the old callback */); 339 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid, 340 newWorkSource, newHistoryTag, newCallback /* notify the new callback */); 341 } else { 342 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, 343 callback); 344 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid, 345 newWorkSource, newHistoryTag, newCallback); 346 } 347 } 348 349 /** 350 * Called when a wake lock is released. 351 */ onWakeLockReleased(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback)352 public void onWakeLockReleased(int flags, String tag, String packageName, 353 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 354 IWakeLockCallback callback) { 355 if (DEBUG) { 356 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag 357 + "\", packageName=" + packageName 358 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 359 + ", workSource=" + workSource); 360 } 361 notifyWakeLockListener(callback, false); 362 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 363 if (monitorType >= 0) { 364 try { 365 if (workSource != null) { 366 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, 367 historyTag, monitorType); 368 } else { 369 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, 370 historyTag, monitorType); 371 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName); 372 } 373 } catch (RemoteException ex) { 374 // Ignore 375 } 376 } 377 mWakeLockLog.onWakeLockReleased(tag, ownerUid); 378 } 379 getBatteryStatsWakeLockMonitorType(int flags)380 private int getBatteryStatsWakeLockMonitorType(int flags) { 381 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) { 382 case PowerManager.PARTIAL_WAKE_LOCK: 383 return BatteryStats.WAKE_TYPE_PARTIAL; 384 385 case PowerManager.SCREEN_DIM_WAKE_LOCK: 386 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 387 return BatteryStats.WAKE_TYPE_FULL; 388 389 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 390 if (mSuspendWhenScreenOffDueToProximityConfig) { 391 return -1; 392 } 393 return BatteryStats.WAKE_TYPE_PARTIAL; 394 395 case PowerManager.DRAW_WAKE_LOCK: 396 return BatteryStats.WAKE_TYPE_DRAW; 397 398 case PowerManager.DOZE_WAKE_LOCK: 399 // Doze wake locks are an internal implementation detail of the 400 // communication between dream manager service and power manager 401 // service. They have no additive battery impact. 402 return -1; 403 404 default: 405 return -1; 406 } 407 } 408 409 /** 410 * Notifies that the device is changing wakefulness. 411 * This function may be called even if the previous change hasn't finished in 412 * which case it will assume that the state did not fully converge before the 413 * next transition began and will recover accordingly. 414 */ onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime)415 public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) { 416 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); 417 if (DEBUG) { 418 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness 419 + ", reason=" + reason + ", interactive=" + interactive); 420 } 421 422 // Tell the activity manager about changes in wakefulness, not just interactivity. 423 // It needs more granularity than other components. 424 mHandler.post(new Runnable() { 425 @Override 426 public void run() { 427 mActivityManagerInternal.onWakefulnessChanged(wakefulness); 428 } 429 }); 430 431 // Handle any early interactive state changes. 432 // Finish pending incomplete ones from a previous cycle. 433 if (mInteractive != interactive) { 434 // Finish up late behaviors if needed. 435 if (mInteractiveChanging) { 436 handleLateInteractiveChange(); 437 } 438 439 // Start input as soon as we start waking up or going to sleep. 440 mInputManagerInternal.setInteractive(interactive); 441 mInputMethodManagerInternal.setInteractive(interactive); 442 443 // Notify battery stats. 444 try { 445 mBatteryStats.noteInteractive(interactive); 446 } catch (RemoteException ex) { } 447 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, 448 interactive ? FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON : 449 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF); 450 451 // Handle early behaviors. 452 mInteractive = interactive; 453 mInteractiveChangeReason = reason; 454 mInteractiveChangeStartTime = eventTime; 455 mInteractiveChanging = true; 456 handleEarlyInteractiveChange(); 457 } 458 } 459 460 /** 461 * Notifies that the device has finished changing wakefulness. 462 */ onWakefulnessChangeFinished()463 public void onWakefulnessChangeFinished() { 464 if (DEBUG) { 465 Slog.d(TAG, "onWakefulnessChangeFinished"); 466 } 467 468 if (mInteractiveChanging) { 469 mInteractiveChanging = false; 470 handleLateInteractiveChange(); 471 } 472 } 473 474 /** 475 * Handle early interactive state changes such as getting applications or the lock 476 * screen running and ready for the user to see (such as when turning on the screen). 477 */ handleEarlyInteractiveChange()478 private void handleEarlyInteractiveChange() { 479 synchronized (mLock) { 480 if (mInteractive) { 481 // Waking up... 482 mHandler.post(() -> { 483 mPolicy.startedWakingUp(mInteractiveChangeReason); 484 mDisplayManagerInternal.onEarlyInteractivityChange(true /*isInteractive*/); 485 }); 486 487 // Send interactive broadcast. 488 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE; 489 mPendingWakeUpBroadcast = true; 490 updatePendingBroadcastLocked(); 491 } else { 492 // Going to sleep... 493 // Tell the policy that we started going to sleep. 494 mHandler.post(() -> { 495 mPolicy.startedGoingToSleep(mInteractiveChangeReason); 496 mDisplayManagerInternal.onEarlyInteractivityChange(false /*isInteractive*/); 497 }); 498 } 499 } 500 } 501 502 /** 503 * Handle late interactive state changes once they are finished so that the system can 504 * finish pending transitions (such as turning the screen off) before causing 505 * applications to change state visibly. 506 */ handleLateInteractiveChange()507 private void handleLateInteractiveChange() { 508 synchronized (mLock) { 509 final int interactiveChangeLatency = 510 (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime); 511 if (mInteractive) { 512 // Finished waking up... 513 mHandler.post(() -> { 514 LogMaker log = new LogMaker(MetricsEvent.SCREEN); 515 log.setType(MetricsEvent.TYPE_OPEN); 516 log.setSubtype(WindowManagerPolicyConstants.translateWakeReasonToOnReason( 517 mInteractiveChangeReason)); 518 log.setLatency(interactiveChangeLatency); 519 log.addTaggedData( 520 MetricsEvent.FIELD_SCREEN_WAKE_REASON, mInteractiveChangeReason); 521 MetricsLogger.action(log); 522 EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency); 523 mPolicy.finishedWakingUp(mInteractiveChangeReason); 524 }); 525 } else { 526 // Finished going to sleep... 527 // This is a good time to make transitions that we don't want the user to see, 528 // such as bringing the key guard to focus. There's no guarantee for this 529 // however because the user could turn the device on again at any time. 530 // Some things may need to be protected by other mechanisms that defer screen on. 531 532 // Cancel pending user activity. 533 if (mUserActivityPending) { 534 mUserActivityPending = false; 535 mHandler.removeMessages(MSG_USER_ACTIVITY); 536 } 537 538 // Tell the policy we finished going to sleep. 539 final int offReason = WindowManagerPolicyConstants.translateSleepReasonToOffReason( 540 mInteractiveChangeReason); 541 mHandler.post(() -> { 542 LogMaker log = new LogMaker(MetricsEvent.SCREEN); 543 log.setType(MetricsEvent.TYPE_CLOSE); 544 log.setSubtype(offReason); 545 log.setLatency(interactiveChangeLatency); 546 log.addTaggedData( 547 MetricsEvent.FIELD_SCREEN_SLEEP_REASON, mInteractiveChangeReason); 548 MetricsLogger.action(log); 549 EventLogTags.writePowerScreenState( 550 0, offReason, 0, 0, interactiveChangeLatency); 551 mPolicy.finishedGoingToSleep(mInteractiveChangeReason); 552 }); 553 554 // Send non-interactive broadcast. 555 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP; 556 mPendingGoToSleepBroadcast = true; 557 updatePendingBroadcastLocked(); 558 } 559 } 560 } 561 562 /** 563 * Called when an individual PowerGroup changes wakefulness. 564 */ onPowerGroupWakefulnessChanged(int groupId, int groupWakefulness, int changeReason, int globalWakefulness)565 public void onPowerGroupWakefulnessChanged(int groupId, int groupWakefulness, int changeReason, 566 int globalWakefulness) { 567 mHandler.post(() -> mPolicy.onPowerGroupWakefulnessChanged(groupId, groupWakefulness, 568 changeReason, globalWakefulness)); 569 } 570 571 /** 572 * Called when there has been user activity. 573 */ onUserActivity(int displayGroupId, @PowerManager.UserActivityEvent int event, int uid)574 public void onUserActivity(int displayGroupId, @PowerManager.UserActivityEvent int event, 575 int uid) { 576 if (DEBUG) { 577 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid); 578 } 579 580 try { 581 mBatteryStats.noteUserActivity(uid, event); 582 } catch (RemoteException ex) { 583 // Ignore 584 } 585 586 synchronized (mLock) { 587 if (!mUserActivityPending) { 588 mUserActivityPending = true; 589 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY); 590 msg.arg1 = displayGroupId; 591 msg.arg2 = event; 592 msg.setAsynchronous(true); 593 mHandler.sendMessage(msg); 594 } 595 } 596 } 597 598 /** 599 * Called when the screen has turned on. 600 */ onWakeUp(int reason, String details, int reasonUid, String opPackageName, int opUid)601 public void onWakeUp(int reason, String details, int reasonUid, String opPackageName, 602 int opUid) { 603 if (DEBUG) { 604 Slog.d(TAG, "onWakeUp: reason=" + PowerManager.wakeReasonToString(reason) 605 + ", details=" + details + ", reasonUid=" + reasonUid 606 + " opPackageName=" + opPackageName + " opUid=" + opUid); 607 } 608 609 try { 610 mBatteryStats.noteWakeUp(details, reasonUid); 611 if (opPackageName != null) { 612 mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName); 613 } 614 } catch (RemoteException ex) { 615 // Ignore 616 } 617 FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_WAKE_REPORTED, reason); 618 } 619 620 /** 621 * Called when profile screen lock timeout has expired. 622 */ onProfileTimeout(@serIdInt int userId)623 public void onProfileTimeout(@UserIdInt int userId) { 624 final Message msg = mHandler.obtainMessage(MSG_PROFILE_TIMED_OUT); 625 msg.setAsynchronous(true); 626 msg.arg1 = userId; 627 mHandler.sendMessage(msg); 628 } 629 630 /** 631 * Called when wireless charging has started - to provide user feedback (sound and visual). 632 */ onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId)633 public void onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) { 634 if (DEBUG) { 635 Slog.d(TAG, "onWirelessChargingStarted"); 636 } 637 638 mSuspendBlocker.acquire(); 639 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED); 640 msg.setAsynchronous(true); 641 msg.arg1 = batteryLevel; 642 msg.arg2 = userId; 643 mHandler.sendMessage(msg); 644 } 645 646 /** 647 * Called when wired charging has started - to provide user feedback 648 */ onWiredChargingStarted(@serIdInt int userId)649 public void onWiredChargingStarted(@UserIdInt int userId) { 650 if (DEBUG) { 651 Slog.d(TAG, "onWiredChargingStarted"); 652 } 653 654 mSuspendBlocker.acquire(); 655 Message msg = mHandler.obtainMessage(MSG_WIRED_CHARGING_STARTED); 656 msg.setAsynchronous(true); 657 msg.arg1 = userId; 658 mHandler.sendMessage(msg); 659 } 660 661 /** 662 * Called when the screen policy changes. 663 */ onScreenPolicyUpdate(int displayGroupId, int newPolicy)664 public void onScreenPolicyUpdate(int displayGroupId, int newPolicy) { 665 if (DEBUG) { 666 Slog.d(TAG, "onScreenPolicyUpdate: newPolicy=" + newPolicy); 667 } 668 669 synchronized (mLock) { 670 Message msg = mHandler.obtainMessage(MSG_SCREEN_POLICY); 671 msg.arg1 = displayGroupId; 672 msg.arg2 = newPolicy; 673 msg.setAsynchronous(true); 674 mHandler.sendMessage(msg); 675 } 676 } 677 678 /** 679 * Dumps data for bugreports. 680 * 681 * @param pw The stream to print to. 682 */ dump(PrintWriter pw)683 public void dump(PrintWriter pw) { 684 if (mWakeLockLog != null) { 685 mWakeLockLog.dump(pw); 686 } 687 } 688 updatePendingBroadcastLocked()689 private void updatePendingBroadcastLocked() { 690 if (!mBroadcastInProgress 691 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN 692 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 693 || mPendingInteractiveState != mBroadcastedInteractiveState)) { 694 mBroadcastInProgress = true; 695 mSuspendBlocker.acquire(); 696 Message msg = mHandler.obtainMessage(MSG_BROADCAST); 697 msg.setAsynchronous(true); 698 mHandler.sendMessage(msg); 699 } 700 } 701 finishPendingBroadcastLocked()702 private void finishPendingBroadcastLocked() { 703 mBroadcastInProgress = false; 704 mSuspendBlocker.release(); 705 } 706 sendUserActivity(int displayGroupId, int event)707 private void sendUserActivity(int displayGroupId, int event) { 708 synchronized (mLock) { 709 if (!mUserActivityPending) { 710 return; 711 } 712 mUserActivityPending = false; 713 } 714 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 715 tm.notifyUserActivity(); 716 mPolicy.userActivity(displayGroupId, event); 717 mFaceDownDetector.userActivity(event); 718 mScreenUndimDetector.userActivity(displayGroupId); 719 } 720 postEnhancedDischargePredictionBroadcast(long delayMs)721 void postEnhancedDischargePredictionBroadcast(long delayMs) { 722 mHandler.sendEmptyMessageDelayed(MSG_BROADCAST_ENHANCED_PREDICTION, delayMs); 723 } 724 sendEnhancedDischargePredictionBroadcast()725 private void sendEnhancedDischargePredictionBroadcast() { 726 Intent intent = new Intent(PowerManager.ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED) 727 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 728 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 729 } 730 sendNextBroadcast()731 private void sendNextBroadcast() { 732 final int powerState; 733 synchronized (mLock) { 734 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) { 735 // Broadcasted power state is unknown. 736 // Send wake up or go to sleep. 737 switch (mPendingInteractiveState) { 738 case INTERACTIVE_STATE_ASLEEP: 739 mPendingGoToSleepBroadcast = false; 740 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP; 741 break; 742 743 case INTERACTIVE_STATE_AWAKE: 744 default: 745 mPendingWakeUpBroadcast = false; 746 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; 747 break; 748 } 749 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) { 750 // Broadcasted power state is awake. Send asleep if needed. 751 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 752 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) { 753 mPendingGoToSleepBroadcast = false; 754 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP; 755 } else { 756 finishPendingBroadcastLocked(); 757 return; 758 } 759 } else { 760 // Broadcasted power state is asleep. Send awake if needed. 761 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 762 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) { 763 mPendingWakeUpBroadcast = false; 764 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; 765 } else { 766 finishPendingBroadcastLocked(); 767 return; 768 } 769 } 770 771 mBroadcastStartTime = SystemClock.uptimeMillis(); 772 powerState = mBroadcastedInteractiveState; 773 } 774 775 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1); 776 777 if (powerState == INTERACTIVE_STATE_AWAKE) { 778 sendWakeUpBroadcast(); 779 } else { 780 sendGoToSleepBroadcast(); 781 } 782 } 783 sendWakeUpBroadcast()784 private void sendWakeUpBroadcast() { 785 if (DEBUG) { 786 Slog.d(TAG, "Sending wake up broadcast."); 787 } 788 789 if (mActivityManagerInternal.isSystemReady()) { 790 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null, 791 mWakeUpBroadcastDone, mHandler, 0, null, null); 792 } else { 793 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1); 794 sendNextBroadcast(); 795 } 796 } 797 798 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() { 799 @Override 800 public void onReceive(Context context, Intent intent) { 801 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, 802 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 803 sendNextBroadcast(); 804 } 805 }; 806 sendGoToSleepBroadcast()807 private void sendGoToSleepBroadcast() { 808 if (DEBUG) { 809 Slog.d(TAG, "Sending go to sleep broadcast."); 810 } 811 812 if (mActivityManagerInternal.isSystemReady()) { 813 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null, 814 mGoToSleepBroadcastDone, mHandler, 0, null, null); 815 } else { 816 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1); 817 sendNextBroadcast(); 818 } 819 } 820 821 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() { 822 @Override 823 public void onReceive(Context context, Intent intent) { 824 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, 825 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 826 sendNextBroadcast(); 827 } 828 }; 829 playChargingStartedFeedback(@serIdInt int userId, boolean wireless)830 private void playChargingStartedFeedback(@UserIdInt int userId, boolean wireless) { 831 if (!isChargingFeedbackEnabled(userId)) { 832 return; 833 } 834 835 if (!mIsPlayingChargingStartedFeedback.compareAndSet(false, true)) { 836 // there's already a charging started feedback Runnable scheduled to run on the 837 // background thread, so let's not execute another 838 return; 839 } 840 841 // vibrate & play sound on a background thread 842 mBackgroundExecutor.execute(() -> { 843 // vibrate 844 final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(), 845 Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0; 846 if (vibrate) { 847 mVibrator.vibrate(CHARGING_VIBRATION_EFFECT, 848 HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 849 } 850 851 // play sound 852 final String soundPath = Settings.Global.getString(mContext.getContentResolver(), 853 wireless ? Settings.Global.WIRELESS_CHARGING_STARTED_SOUND 854 : Settings.Global.CHARGING_STARTED_SOUND); 855 final Uri soundUri = Uri.parse("file://" + soundPath); 856 if (soundUri != null) { 857 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); 858 if (sfx != null) { 859 sfx.setStreamType(AudioManager.STREAM_SYSTEM); 860 sfx.play(); 861 } 862 } 863 mIsPlayingChargingStartedFeedback.set(false); 864 }); 865 } 866 showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId)867 private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) { 868 // play sounds + haptics 869 playChargingStartedFeedback(userId, true /* wireless */); 870 871 // show animation 872 if (mShowWirelessChargingAnimationConfig && mStatusBarManagerInternal != null) { 873 mStatusBarManagerInternal.showChargingAnimation(batteryLevel); 874 } 875 mSuspendBlocker.release(); 876 } 877 showWiredChargingStarted(@serIdInt int userId)878 private void showWiredChargingStarted(@UserIdInt int userId) { 879 playChargingStartedFeedback(userId, false /* wireless */); 880 mSuspendBlocker.release(); 881 } 882 screenPolicyChanging(int displayGroupId, int screenPolicy)883 private void screenPolicyChanging(int displayGroupId, int screenPolicy) { 884 mScreenUndimDetector.recordScreenPolicy(displayGroupId, screenPolicy); 885 } 886 lockProfile(@serIdInt int userId)887 private void lockProfile(@UserIdInt int userId) { 888 mTrustManager.setDeviceLockedForUser(userId, true /*locked*/); 889 } 890 isChargingFeedbackEnabled(@serIdInt int userId)891 private boolean isChargingFeedbackEnabled(@UserIdInt int userId) { 892 final boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), 893 Settings.Secure.CHARGING_SOUNDS_ENABLED, 1, userId) != 0; 894 final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(), 895 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) 896 == Settings.Global.ZEN_MODE_OFF; 897 return enabled && dndOff; 898 } 899 notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled)900 private void notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled) { 901 if (callback != null) { 902 mHandler.post(() -> { 903 try { 904 callback.onStateChanged(isEnabled); 905 } catch (RemoteException e) { 906 throw new IllegalArgumentException("Wakelock.mCallback is already dead.", e); 907 } 908 }); 909 } 910 } 911 912 private final class NotifierHandler extends Handler { 913 NotifierHandler(Looper looper)914 public NotifierHandler(Looper looper) { 915 super(looper, null, true /*async*/); 916 } 917 @Override handleMessage(Message msg)918 public void handleMessage(Message msg) { 919 switch (msg.what) { 920 case MSG_USER_ACTIVITY: 921 sendUserActivity(msg.arg1, msg.arg2); 922 break; 923 case MSG_BROADCAST: 924 sendNextBroadcast(); 925 break; 926 case MSG_WIRELESS_CHARGING_STARTED: 927 showWirelessChargingStarted(msg.arg1, msg.arg2); 928 break; 929 case MSG_BROADCAST_ENHANCED_PREDICTION: 930 removeMessages(MSG_BROADCAST_ENHANCED_PREDICTION); 931 sendEnhancedDischargePredictionBroadcast(); 932 break; 933 case MSG_PROFILE_TIMED_OUT: 934 lockProfile(msg.arg1); 935 break; 936 case MSG_WIRED_CHARGING_STARTED: 937 showWiredChargingStarted(msg.arg1); 938 break; 939 case MSG_SCREEN_POLICY: 940 screenPolicyChanging(msg.arg1, msg.arg2); 941 break; 942 } 943 } 944 } 945 } 946