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