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