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