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