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