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.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SuppressLint; 22 import android.annotation.UserIdInt; 23 import android.app.ActivityManagerInternal; 24 import android.app.AppOpsManager; 25 import android.app.BroadcastOptions; 26 import android.app.trust.TrustManager; 27 import android.content.Context; 28 import android.content.IIntentReceiver; 29 import android.content.Intent; 30 import android.hardware.display.DisplayManagerInternal; 31 import android.media.AudioManager; 32 import android.media.Ringtone; 33 import android.media.RingtoneManager; 34 import android.metrics.LogMaker; 35 import android.net.Uri; 36 import android.os.BatteryStats; 37 import android.os.BatteryStatsInternal; 38 import android.os.Bundle; 39 import android.os.Handler; 40 import android.os.IScreenTimeoutPolicyListener; 41 import android.os.IWakeLockCallback; 42 import android.os.Looper; 43 import android.os.Message; 44 import android.os.PowerManager; 45 import android.os.PowerManager.ScreenTimeoutPolicy; 46 import android.os.PowerManagerInternal; 47 import android.os.Process; 48 import android.os.RemoteCallbackList; 49 import android.os.RemoteException; 50 import android.os.SystemClock; 51 import android.os.UserHandle; 52 import android.os.VibrationAttributes; 53 import android.os.VibrationEffect; 54 import android.os.Vibrator; 55 import android.os.WorkSource; 56 import android.os.WorkSource.WorkChain; 57 import android.provider.Settings; 58 import android.telephony.TelephonyManager; 59 import android.util.ArrayMap; 60 import android.util.EventLog; 61 import android.util.Slog; 62 import android.util.SparseArray; 63 import android.util.SparseBooleanArray; 64 import android.view.WindowManagerPolicyConstants; 65 66 import com.android.internal.annotations.VisibleForTesting; 67 import com.android.internal.app.IBatteryStats; 68 import com.android.internal.logging.MetricsLogger; 69 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 70 import com.android.internal.util.FrameworkStatsLog; 71 import com.android.internal.util.IndentingPrintWriter; 72 import com.android.server.EventLogTags; 73 import com.android.server.LocalServices; 74 import com.android.server.input.InputManagerInternal; 75 import com.android.server.inputmethod.InputMethodManagerInternal; 76 import com.android.server.policy.WindowManagerPolicy; 77 import com.android.server.power.FrameworkStatsLogger.WakelockEventType; 78 import com.android.server.power.feature.PowerManagerFlags; 79 import com.android.server.statusbar.StatusBarManagerInternal; 80 81 import java.io.PrintWriter; 82 import java.util.List; 83 import java.util.UUID; 84 import java.util.concurrent.Executor; 85 import java.util.concurrent.atomic.AtomicBoolean; 86 87 /** 88 * Sends broadcasts about important power state changes. 89 * <p> 90 * This methods of this class may be called by the power manager service while 91 * its lock is being held. Internally it takes care of sending broadcasts to 92 * notify other components of the system or applications asynchronously. 93 * </p><p> 94 * The notifier is designed to collapse unnecessary broadcasts when it is not 95 * possible for the system to have observed an intermediate state. 96 * </p><p> 97 * For example, if the device wakes up, goes to sleep, wakes up again and goes to 98 * sleep again before the wake up notification is sent, then the system will 99 * be told about only one wake up and sleep. However, we always notify the 100 * fact that at least one transition occurred. It is especially important to 101 * tell the system when we go to sleep so that it can lock the keyguard if needed. 102 * </p> 103 */ 104 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) 105 public class Notifier { 106 private static final String TAG = "PowerManagerNotifier"; 107 108 private static final boolean DEBUG = false; 109 110 private static final int INTERACTIVE_STATE_UNKNOWN = 0; 111 private static final int INTERACTIVE_STATE_AWAKE = 1; 112 private static final int INTERACTIVE_STATE_ASLEEP = 2; 113 114 private static final int MSG_USER_ACTIVITY = 1; 115 private static final int MSG_BROADCAST = 2; 116 private static final int MSG_WIRELESS_CHARGING_STARTED = 3; 117 private static final int MSG_BROADCAST_ENHANCED_PREDICTION = 4; 118 private static final int MSG_PROFILE_TIMED_OUT = 5; 119 private static final int MSG_WIRED_CHARGING_STARTED = 6; 120 private static final int MSG_SCREEN_POLICY = 7; 121 122 private static final long[] CHARGING_VIBRATION_TIME = { 123 40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms 124 40, 40, 40, 40, 40, 40, 40 // ramp-down sampling rate = 40ms 125 }; 126 private static final int[] CHARGING_VIBRATION_AMPLITUDE = { 127 1, 4, 11, 25, 44, 67, 91, 114, 123, // ramp-up amplitude (from 0 to 50%) 128 103, 79, 55, 34, 17, 7, 2 // ramp-up amplitude 129 }; 130 private static final VibrationEffect CHARGING_VIBRATION_EFFECT = 131 VibrationEffect.createWaveform(CHARGING_VIBRATION_TIME, CHARGING_VIBRATION_AMPLITUDE, 132 -1); 133 private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES = 134 VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK); 135 136 private final Object mLock = new Object(); 137 138 private final Context mContext; 139 private final IBatteryStats mBatteryStats; 140 private final AppOpsManager mAppOps; 141 private final SuspendBlocker mSuspendBlocker; 142 private final WindowManagerPolicy mPolicy; 143 private final FaceDownDetector mFaceDownDetector; 144 private final ScreenUndimDetector mScreenUndimDetector; 145 private final WakefulnessSessionObserver mWakefulnessSessionObserver; 146 private final ActivityManagerInternal mActivityManagerInternal; 147 private final InputManagerInternal mInputManagerInternal; 148 private final InputMethodManagerInternal mInputMethodManagerInternal; 149 @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal; 150 private final TrustManager mTrustManager; 151 private final Vibrator mVibrator; 152 @NonNull private final WakeLockLog mPartialWakeLockLog; 153 @NonNull private final WakeLockLog mFullWakeLockLog; 154 private final DisplayManagerInternal mDisplayManagerInternal; 155 156 private final NotifierHandler mHandler; 157 private final Executor mBackgroundExecutor; 158 private final Intent mScreenOnIntent; 159 private final Intent mScreenOffIntent; 160 private final Bundle mScreenOnOffOptions; 161 162 // Display id -> ScreenTimeoutPolicyListenersContainer that contains list of screen 163 // wake lock listeners 164 private final SparseArray<ScreenTimeoutPolicyListenersContainer> mScreenTimeoutPolicyListeners 165 = new SparseArray<>(); 166 167 // True if the device should suspend when the screen is off due to proximity. 168 private final boolean mSuspendWhenScreenOffDueToProximityConfig; 169 170 // True if the device should show the wireless charging animation when the device 171 // begins charging wirelessly 172 private final boolean mShowWirelessChargingAnimationConfig; 173 174 // Encapsulates interactivity information about a particular display group. 175 private static class Interactivity { 176 public boolean isInteractive = true; 177 public int changeReason; 178 public long changeStartTime; // In SystemClock.uptimeMillis() 179 public boolean isChanging; 180 } 181 182 private final SparseArray<Interactivity> mInteractivityByGroupId = new SparseArray<>(); 183 private SparseBooleanArray mDisplayInteractivities = new SparseBooleanArray(); 184 185 // The current global interactive state. This is set as soon as an interactive state 186 // transition begins so as to capture the reason that it happened. At some point 187 // this state will propagate to the pending state then eventually to the 188 // broadcasted state over the course of reporting the transition asynchronously. 189 private Interactivity mGlobalInteractivity = new Interactivity(); 190 191 // The pending interactive state that we will eventually want to broadcast. 192 // This is designed so that we can collapse redundant sequences of awake/sleep 193 // transition pairs while still guaranteeing that at least one transition is observed 194 // whenever this happens. 195 private int mPendingInteractiveState; 196 private boolean mPendingWakeUpBroadcast; 197 private boolean mPendingGoToSleepBroadcast; 198 199 // The currently broadcasted interactive state. This reflects what other parts of the 200 // system have observed. 201 private int mBroadcastedInteractiveState; 202 private boolean mBroadcastInProgress; 203 private long mBroadcastStartTime; 204 205 // True if a user activity message should be sent. 206 private boolean mUserActivityPending; 207 208 private final AtomicBoolean mIsPlayingChargingStartedFeedback = new AtomicBoolean(false); 209 210 private final Injector mInjector; 211 212 private final PowerManagerFlags mFlags; 213 214 private final BatteryStatsInternal mBatteryStatsInternal; 215 private final FrameworkStatsLogger mFrameworkStatsLogger; 216 Notifier(Looper looper, Context context, IBatteryStats batteryStats, SuspendBlocker suspendBlocker, WindowManagerPolicy policy, FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector)217 public Notifier(Looper looper, Context context, IBatteryStats batteryStats, 218 SuspendBlocker suspendBlocker, WindowManagerPolicy policy, 219 FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector, 220 Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector) { 221 mContext = context; 222 mInjector = (injector == null) ? new RealInjector() : injector; 223 mFlags = powerManagerFlags; 224 mBatteryStats = batteryStats; 225 mAppOps = mInjector.getAppOpsManager(context); 226 mSuspendBlocker = suspendBlocker; 227 mPolicy = policy; 228 mFaceDownDetector = faceDownDetector; 229 mScreenUndimDetector = screenUndimDetector; 230 mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); 231 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 232 mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class); 233 mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class); 234 mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 235 mTrustManager = mContext.getSystemService(TrustManager.class); 236 mVibrator = mContext.getSystemService(Vibrator.class); 237 mWakefulnessSessionObserver = new WakefulnessSessionObserver(mContext, null); 238 239 mHandler = new NotifierHandler(looper); 240 mBackgroundExecutor = backgroundExecutor; 241 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); 242 mScreenOnIntent.addFlags( 243 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND 244 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 245 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); 246 mScreenOffIntent.addFlags( 247 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND 248 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 249 mScreenOnOffOptions = createScreenOnOffBroadcastOptions(); 250 251 mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean( 252 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity); 253 mShowWirelessChargingAnimationConfig = context.getResources().getBoolean( 254 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim); 255 256 mFullWakeLockLog = mInjector.getWakeLockLog(context); 257 mPartialWakeLockLog = mInjector.getWakeLockLog(context); 258 259 // Initialize interactive state for battery stats. 260 try { 261 mBatteryStats.noteInteractive(true); 262 } catch (RemoteException ex) { } 263 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, 264 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON); 265 266 if (mFlags.isMoveWscLoggingToNotifierEnabled()) { 267 mBatteryStatsInternal = mInjector.getBatteryStatsInternal(); 268 mFrameworkStatsLogger = mInjector.getFrameworkStatsLogger(); 269 } else { 270 mBatteryStatsInternal = null; 271 mFrameworkStatsLogger = null; 272 } 273 } 274 275 /** 276 * Create the {@link BroadcastOptions} bundle that will be used with sending the 277 * {@link Intent#ACTION_SCREEN_ON} and {@link Intent#ACTION_SCREEN_OFF} broadcasts. 278 */ createScreenOnOffBroadcastOptions()279 private Bundle createScreenOnOffBroadcastOptions() { 280 final BroadcastOptions options = BroadcastOptions.makeBasic(); 281 // This allows the broadcasting system to discard any older broadcasts 282 // waiting to be delivered to a process. 283 options.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT); 284 // Set namespace and key to identify which older broadcasts can be discarded. 285 // We could use any strings here but namespace needs to be unlikely to be reused with in 286 // the system_server process, as that could result in potentially discarding some 287 // non-screen on/off related broadcast. 288 options.setDeliveryGroupMatchingKey( 289 UUID.randomUUID().toString(), 290 Intent.ACTION_SCREEN_ON); 291 // This allows the broadcast delivery to be delayed to apps in the Cached state. 292 options.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); 293 return options.toBundle(); 294 } 295 296 /** 297 * Called when a wake lock is acquired. 298 */ 299 @SuppressLint("AndroidFrameworkRequiresPermission") onWakeLockAcquired(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback)300 public void onWakeLockAcquired(int flags, String tag, String packageName, 301 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 302 IWakeLockCallback callback) { 303 if (DEBUG) { 304 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag 305 + "\", packageName=" + packageName 306 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 307 + ", workSource=" + workSource); 308 } 309 logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.ACQUIRE); 310 notifyWakeLockListener(callback, tag, true, ownerUid, ownerPid, flags, workSource, 311 packageName, historyTag); 312 if (!mFlags.improveWakelockLatency()) { 313 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 314 if (monitorType >= 0) { 315 try { 316 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID 317 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; 318 if (workSource != null) { 319 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, 320 historyTag, monitorType, unimportantForLogging); 321 } else { 322 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag, 323 monitorType, unimportantForLogging); 324 // XXX need to deal with disabled operations. 325 mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, 326 false, null, null); 327 } 328 } catch (RemoteException ex) { 329 // Ignore 330 } 331 } 332 getWakeLockLog(flags).onWakeLockAcquired(tag, 333 getUidForWakeLockLog(ownerUid, workSource), flags, /*eventTime=*/ -1); 334 } 335 mWakefulnessSessionObserver.onWakeLockAcquired(flags); 336 } 337 onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource, String historyTag)338 public void onLongPartialWakeLockStart(String tag, int ownerUid, WorkSource workSource, 339 String historyTag) { 340 if (DEBUG) { 341 Slog.d(TAG, "onLongPartialWakeLockStart: ownerUid=" + ownerUid 342 + ", workSource=" + workSource); 343 } 344 345 try { 346 if (workSource != null) { 347 mBatteryStats.noteLongPartialWakelockStartFromSource(tag, historyTag, workSource); 348 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 349 workSource, tag, historyTag, 350 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 351 } else { 352 mBatteryStats.noteLongPartialWakelockStart(tag, historyTag, ownerUid); 353 FrameworkStatsLog.write_non_chained( 354 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag, 355 historyTag, 356 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON); 357 } 358 } catch (RemoteException ex) { 359 // Ignore 360 } 361 } 362 onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource, String historyTag)363 public void onLongPartialWakeLockFinish(String tag, int ownerUid, WorkSource workSource, 364 String historyTag) { 365 if (DEBUG) { 366 Slog.d(TAG, "onLongPartialWakeLockFinish: ownerUid=" + ownerUid 367 + ", workSource=" + workSource); 368 } 369 370 try { 371 if (workSource != null) { 372 mBatteryStats.noteLongPartialWakelockFinishFromSource(tag, historyTag, workSource); 373 FrameworkStatsLog.write(FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, 374 workSource, tag, historyTag, 375 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 376 } else { 377 mBatteryStats.noteLongPartialWakelockFinish(tag, historyTag, ownerUid); 378 FrameworkStatsLog.write_non_chained( 379 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, ownerUid, null, tag, 380 historyTag, 381 FrameworkStatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF); 382 } 383 } catch (RemoteException ex) { 384 // Ignore 385 } 386 } 387 388 /** 389 * Called when a wake lock is changing. 390 */ 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)391 public void onWakeLockChanging(int flags, String tag, String packageName, 392 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 393 IWakeLockCallback callback, int newFlags, String newTag, String newPackageName, 394 int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag, 395 IWakeLockCallback newCallback) { 396 // Todo(b/359154665): We do this because the newWorkSource can potentially be updated 397 // before the request is processed on the notifier thread. This would generally happen is 398 // the Worksource's set method is called, which as of this comment happens only in 399 // PowerManager#setWorksource and WifiManager#WifiLock#setWorksource. Both these places 400 // need to be updated and the WorkSource#set should be deprecated to avoid falling into 401 // such traps 402 newWorkSource = (newWorkSource == null) ? null : new WorkSource(newWorkSource); 403 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 404 final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags); 405 if (workSource != null && newWorkSource != null 406 && monitorType >= 0 && newMonitorType >= 0) { 407 if (DEBUG) { 408 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag 409 + "\", packageName=" + newPackageName 410 + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid 411 + ", workSource=" + newWorkSource); 412 } 413 414 logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); 415 logWakelockStateChanged( 416 newFlags, newTag, newOwnerUid, newWorkSource, WakelockEventType.ACQUIRE); 417 418 final boolean unimportantForLogging = newOwnerUid == Process.SYSTEM_UID 419 && (newFlags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; 420 try { 421 notifyWakelockChanging(workSource, ownerPid, tag, 422 historyTag, monitorType, newWorkSource, newOwnerPid, newTag, 423 newHistoryTag, newMonitorType, unimportantForLogging); 424 } catch (RemoteException ex) { 425 // Ignore 426 } 427 } else if (!PowerManagerService.isSameCallback(callback, newCallback)) { 428 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, 429 null /* Do not notify the old callback */); 430 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid, 431 newWorkSource, newHistoryTag, newCallback /* notify the new callback */); 432 } else { 433 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, 434 callback); 435 onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid, 436 newWorkSource, newHistoryTag, newCallback); 437 } 438 } 439 440 /** 441 * Called when a wake lock is released. 442 */ onWakeLockReleased(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback)443 public void onWakeLockReleased(int flags, String tag, String packageName, 444 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 445 IWakeLockCallback callback) { 446 onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag, 447 callback, ScreenTimeoutOverridePolicy.RELEASE_REASON_UNKNOWN); 448 } 449 450 /** 451 * Called when a wake lock is released. 452 */ 453 @SuppressLint("AndroidFrameworkRequiresPermission") onWakeLockReleased(int flags, String tag, String packageName, int ownerUid, int ownerPid, WorkSource workSource, String historyTag, IWakeLockCallback callback, int releaseReason)454 public void onWakeLockReleased(int flags, String tag, String packageName, 455 int ownerUid, int ownerPid, WorkSource workSource, String historyTag, 456 IWakeLockCallback callback, int releaseReason) { 457 if (DEBUG) { 458 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag 459 + "\", packageName=" + packageName 460 + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 461 + ", workSource=" + workSource); 462 } 463 logWakelockStateChanged(flags, tag, ownerUid, workSource, WakelockEventType.RELEASE); 464 notifyWakeLockListener(callback, tag, false, ownerUid, ownerPid, flags, workSource, 465 packageName, historyTag); 466 if (!mFlags.improveWakelockLatency()) { 467 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 468 if (monitorType >= 0) { 469 try { 470 if (workSource != null) { 471 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, 472 historyTag, monitorType); 473 } else { 474 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, 475 historyTag, monitorType); 476 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, null); 477 } 478 } catch (RemoteException ex) { 479 // Ignore 480 } 481 } 482 getWakeLockLog(flags).onWakeLockReleased(tag, 483 getUidForWakeLockLog(ownerUid, workSource), /*eventTime=*/ -1); 484 } 485 mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason); 486 } 487 488 /** Shows the keyguard without requesting the device to immediately lock. */ showDismissibleKeyguard()489 public void showDismissibleKeyguard() { 490 mPolicy.showDismissibleKeyguard(); 491 } 492 getBatteryStatsWakeLockMonitorType(int flags)493 private int getBatteryStatsWakeLockMonitorType(int flags) { 494 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) { 495 case PowerManager.PARTIAL_WAKE_LOCK: 496 return BatteryStats.WAKE_TYPE_PARTIAL; 497 498 case PowerManager.FULL_WAKE_LOCK: 499 case PowerManager.SCREEN_DIM_WAKE_LOCK: 500 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 501 return BatteryStats.WAKE_TYPE_FULL; 502 503 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 504 if (mSuspendWhenScreenOffDueToProximityConfig) { 505 return -1; 506 } 507 return BatteryStats.WAKE_TYPE_PARTIAL; 508 509 case PowerManager.DRAW_WAKE_LOCK: 510 return BatteryStats.WAKE_TYPE_DRAW; 511 512 case PowerManager.DOZE_WAKE_LOCK: 513 // Doze wake locks are an internal implementation detail of the 514 // communication between dream manager service and power manager 515 // service. They have no additive battery impact. 516 return -1; 517 518 default: 519 return -1; 520 } 521 } 522 523 @VisibleForTesting getWakelockMonitorTypeForLogging(int flags)524 int getWakelockMonitorTypeForLogging(int flags) { 525 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) { 526 case PowerManager.FULL_WAKE_LOCK, PowerManager.SCREEN_DIM_WAKE_LOCK, 527 PowerManager.SCREEN_BRIGHT_WAKE_LOCK: 528 return PowerManager.FULL_WAKE_LOCK; 529 case PowerManager.DRAW_WAKE_LOCK: 530 return PowerManager.DRAW_WAKE_LOCK; 531 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 532 if (mSuspendWhenScreenOffDueToProximityConfig) { 533 return -1; 534 } 535 return PowerManager.PARTIAL_WAKE_LOCK; 536 case PowerManager.PARTIAL_WAKE_LOCK: 537 return PowerManager.PARTIAL_WAKE_LOCK; 538 case PowerManager.DOZE_WAKE_LOCK: 539 // Doze wake locks are an internal implementation detail of the 540 // communication between dream manager service and power manager 541 // service. They have no additive battery impact. 542 return -1; 543 default: 544 return -1; 545 } 546 } 547 548 /** 549 * Notifies that the device is changing wakefulness. 550 * This function may be called even if the previous change hasn't finished in 551 * which case it will assume that the state did not fully converge before the 552 * next transition began and will recover accordingly. 553 */ onGlobalWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime)554 public void onGlobalWakefulnessChangeStarted(final int wakefulness, int reason, 555 long eventTime) { 556 final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); 557 if (DEBUG) { 558 Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness 559 + ", reason=" + reason + ", interactive=" + interactive); 560 } 561 562 // Tell the activity manager about changes in wakefulness, not just interactivity. 563 // It needs more granularity than other components. 564 mHandler.post(new Runnable() { 565 @Override 566 public void run() { 567 mActivityManagerInternal.onWakefulnessChanged(wakefulness); 568 } 569 }); 570 571 // Handle any early interactive state changes. 572 // Finish pending incomplete ones from a previous cycle. 573 if (mGlobalInteractivity.isInteractive != interactive) { 574 // Finish up late behaviors if needed. 575 if (mGlobalInteractivity.isChanging) { 576 handleLateGlobalInteractiveChange(); 577 } 578 579 // Start input as soon as we start waking up or going to sleep. 580 mInputMethodManagerInternal.setInteractive(interactive); 581 if (!mFlags.isPerDisplayWakeByTouchEnabled()) { 582 // Since wakefulness is a global property in original logic, all displays should 583 // be set to the same interactive state, matching system's global wakefulness 584 SparseBooleanArray displayInteractivities = new SparseBooleanArray(); 585 int[] displayIds = mDisplayManagerInternal.getDisplayIds().toArray(); 586 for (int displayId : displayIds) { 587 displayInteractivities.put(displayId, interactive); 588 } 589 mInputManagerInternal.setDisplayInteractivities(displayInteractivities); 590 } 591 592 // Notify battery stats. 593 try { 594 mBatteryStats.noteInteractive(interactive); 595 } catch (RemoteException ex) { } 596 FrameworkStatsLog.write(FrameworkStatsLog.INTERACTIVE_STATE_CHANGED, 597 interactive ? FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__ON : 598 FrameworkStatsLog.INTERACTIVE_STATE_CHANGED__STATE__OFF); 599 600 // Handle early behaviors. 601 mGlobalInteractivity.isInteractive = interactive; 602 mGlobalInteractivity.isChanging = true; 603 mGlobalInteractivity.changeReason = reason; 604 mGlobalInteractivity.changeStartTime = eventTime; 605 handleEarlyGlobalInteractiveChange(); 606 } 607 } 608 609 /** 610 * Notifies that the device has finished changing wakefulness. 611 */ onWakefulnessChangeFinished()612 public void onWakefulnessChangeFinished() { 613 if (DEBUG) { 614 Slog.d(TAG, "onWakefulnessChangeFinished"); 615 } 616 for (int i = 0; i < mInteractivityByGroupId.size(); i++) { 617 int groupId = mInteractivityByGroupId.keyAt(i); 618 Interactivity interactivity = mInteractivityByGroupId.valueAt(i); 619 if (interactivity.isChanging) { 620 interactivity.isChanging = false; 621 handleLateInteractiveChange(groupId); 622 } 623 } 624 if (mGlobalInteractivity.isChanging) { 625 mGlobalInteractivity.isChanging = false; 626 handleLateGlobalInteractiveChange(); 627 } 628 } 629 630 handleEarlyInteractiveChange(int groupId)631 private void handleEarlyInteractiveChange(int groupId) { 632 synchronized (mLock) { 633 Interactivity interactivity = mInteractivityByGroupId.get(groupId); 634 if (interactivity == null) { 635 Slog.e(TAG, "no Interactivity entry for groupId:" + groupId); 636 return; 637 } 638 final int changeReason = interactivity.changeReason; 639 if (interactivity.isInteractive) { 640 mHandler.post(() -> mPolicy.startedWakingUp(groupId, changeReason)); 641 } else { 642 mHandler.post(() -> mPolicy.startedGoingToSleep(groupId, changeReason)); 643 } 644 } 645 } 646 647 /** 648 * Handle early interactive state changes such as getting applications or the lock 649 * screen running and ready for the user to see (such as when turning on the screen). 650 */ handleEarlyGlobalInteractiveChange()651 private void handleEarlyGlobalInteractiveChange() { 652 synchronized (mLock) { 653 if (mGlobalInteractivity.isInteractive) { 654 // Waking up... 655 mHandler.post(() -> { 656 mDisplayManagerInternal.onEarlyInteractivityChange(true /*isInteractive*/); 657 mPolicy.startedWakingUpGlobal(mGlobalInteractivity.changeReason); 658 }); 659 660 // Send interactive broadcast. 661 mPendingInteractiveState = INTERACTIVE_STATE_AWAKE; 662 mPendingWakeUpBroadcast = true; 663 updatePendingBroadcastLocked(); 664 } else { 665 // Going to sleep... 666 mHandler.post(() -> { 667 mDisplayManagerInternal.onEarlyInteractivityChange(false /*isInteractive*/); 668 mPolicy.startedGoingToSleepGlobal(mGlobalInteractivity.changeReason); 669 }); 670 } 671 } 672 } 673 674 /** 675 * Handle late global interactive state changes. Also see 676 * {@link #handleLateInteractiveChange(int)}. 677 */ handleLateGlobalInteractiveChange()678 private void handleLateGlobalInteractiveChange() { 679 synchronized (mLock) { 680 final int interactiveChangeLatency = 681 (int) (SystemClock.uptimeMillis() - mGlobalInteractivity.changeStartTime); 682 if (mGlobalInteractivity.isInteractive) { 683 // Finished waking up... 684 mHandler.post(() -> { 685 LogMaker log = new LogMaker(MetricsEvent.SCREEN); 686 log.setType(MetricsEvent.TYPE_OPEN); 687 log.setSubtype(WindowManagerPolicyConstants.translateWakeReasonToOnReason( 688 mGlobalInteractivity.changeReason)); 689 log.setLatency(interactiveChangeLatency); 690 log.addTaggedData(MetricsEvent.FIELD_SCREEN_WAKE_REASON, 691 mGlobalInteractivity.changeReason); 692 MetricsLogger.action(log); 693 EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency); 694 695 mPolicy.finishedWakingUpGlobal(mGlobalInteractivity.changeReason); 696 }); 697 } else { 698 // Finished going to sleep... 699 // This is a good time to make transitions that we don't want the user to see, 700 // such as bringing the key guard to focus. There's no guarantee for this 701 // however because the user could turn the device on again at any time. 702 // Some things may need to be protected by other mechanisms that defer screen on. 703 704 // Cancel pending user activity. 705 if (mUserActivityPending) { 706 mUserActivityPending = false; 707 mHandler.removeMessages(MSG_USER_ACTIVITY); 708 } 709 710 // Tell the policy we finished going to sleep. 711 final int offReason = WindowManagerPolicyConstants.translateSleepReasonToOffReason( 712 mGlobalInteractivity.changeReason); 713 mHandler.post(() -> { 714 LogMaker log = new LogMaker(MetricsEvent.SCREEN); 715 log.setType(MetricsEvent.TYPE_CLOSE); 716 log.setSubtype(offReason); 717 log.setLatency(interactiveChangeLatency); 718 log.addTaggedData(MetricsEvent.FIELD_SCREEN_SLEEP_REASON, 719 mGlobalInteractivity.changeReason); 720 MetricsLogger.action(log); 721 EventLogTags.writePowerScreenState( 722 0, offReason, 0, 0, interactiveChangeLatency); 723 724 mPolicy.finishedGoingToSleepGlobal(mGlobalInteractivity.changeReason); 725 }); 726 727 // Send non-interactive broadcast. 728 mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP; 729 mPendingGoToSleepBroadcast = true; 730 updatePendingBroadcastLocked(); 731 } 732 } 733 } 734 735 /** 736 * Handle late interactive state changes once they are finished so that the system can 737 * finish pending transitions (such as turning the screen off) before causing 738 * applications to change state visibly. 739 */ handleLateInteractiveChange(int groupId)740 private void handleLateInteractiveChange(int groupId) { 741 synchronized (mLock) { 742 Interactivity interactivity = mInteractivityByGroupId.get(groupId); 743 if (interactivity == null) { 744 Slog.e(TAG, "no Interactivity entry for groupId:" + groupId); 745 return; 746 } 747 final int changeReason = interactivity.changeReason; 748 if (interactivity.isInteractive) { 749 mHandler.post(() -> mPolicy.finishedWakingUp(groupId, changeReason)); 750 } else { 751 mHandler.post(() -> mPolicy.finishedGoingToSleep(groupId, changeReason)); 752 } 753 } 754 } 755 756 /** 757 * Update the interactivities of the displays in given DisplayGroup. 758 * 759 * @param groupId The group id of the DisplayGroup to update display interactivities for. 760 */ updateDisplayInteractivities(int groupId, boolean interactive)761 private void updateDisplayInteractivities(int groupId, boolean interactive) { 762 final int[] displayIds = mDisplayManagerInternal.getDisplayIdsForGroup(groupId); 763 for (int displayId : displayIds) { 764 mDisplayInteractivities.put(displayId, interactive); 765 } 766 767 } 768 resetDisplayInteractivities()769 private void resetDisplayInteractivities() { 770 final SparseArray<int[]> displaysByGroupId = 771 mDisplayManagerInternal.getDisplayIdsByGroupsIds(); 772 SparseBooleanArray newDisplayInteractivities = new SparseBooleanArray(); 773 for (int i = 0; i < displaysByGroupId.size(); i++) { 774 final int groupId = displaysByGroupId.keyAt(i); 775 for (int displayId : displaysByGroupId.get(groupId)) { 776 // If we already know display interactivity, use that 777 if (mDisplayInteractivities.indexOfKey(displayId) > 0) { 778 newDisplayInteractivities.put( 779 displayId, mDisplayInteractivities.get(displayId)); 780 } else { // If display is new to Notifier, use the power group's interactive value 781 final Interactivity groupInteractivity = mInteractivityByGroupId.get(groupId); 782 // If group Interactivity hasn't been initialized, assume group is interactive 783 final boolean groupInteractive = 784 groupInteractivity == null || groupInteractivity.isInteractive; 785 newDisplayInteractivities.put(displayId, groupInteractive); 786 } 787 } 788 } 789 mDisplayInteractivities = newDisplayInteractivities; 790 } 791 792 /** 793 * Called when an individual PowerGroup changes wakefulness. 794 */ onGroupWakefulnessChangeStarted(int groupId, int wakefulness, int changeReason, long eventTime)795 public void onGroupWakefulnessChangeStarted(int groupId, int wakefulness, int changeReason, 796 long eventTime) { 797 final boolean isInteractive = PowerManagerInternal.isInteractive(wakefulness); 798 799 boolean isNewGroup = false; 800 Interactivity interactivity = mInteractivityByGroupId.get(groupId); 801 if (interactivity == null) { 802 isNewGroup = true; 803 interactivity = new Interactivity(); 804 mInteractivityByGroupId.put(groupId, interactivity); 805 } 806 if (isNewGroup || interactivity.isInteractive != isInteractive) { 807 // Finish up late behaviors if needed. 808 if (interactivity.isChanging) { 809 handleLateInteractiveChange(groupId); 810 } 811 812 // Handle early behaviors. 813 interactivity.isInteractive = isInteractive; 814 interactivity.changeReason = changeReason; 815 interactivity.changeStartTime = eventTime; 816 interactivity.isChanging = true; 817 handleEarlyInteractiveChange(groupId); 818 mWakefulnessSessionObserver.onWakefulnessChangeStarted(groupId, wakefulness, 819 changeReason, eventTime); 820 821 // Update input on which displays are interactive 822 if (mFlags.isPerDisplayWakeByTouchEnabled()) { 823 updateDisplayInteractivities(groupId, isInteractive); 824 mInputManagerInternal.setDisplayInteractivities(mDisplayInteractivities); 825 } 826 } 827 } 828 829 /** 830 * Called when a PowerGroup has been removed. 831 * 832 * @param groupId which group was removed 833 */ onGroupRemoved(int groupId)834 public void onGroupRemoved(int groupId) { 835 mInteractivityByGroupId.remove(groupId); 836 mWakefulnessSessionObserver.removePowerGroup(groupId); 837 if (mFlags.isPerDisplayWakeByTouchEnabled()) { 838 resetDisplayInteractivities(); 839 mInputManagerInternal.setDisplayInteractivities(mDisplayInteractivities); 840 } 841 } 842 843 /** 844 * Called when a PowerGroup has been changed. 845 */ onGroupChanged()846 public void onGroupChanged() { 847 if (mFlags.isPerDisplayWakeByTouchEnabled()) { 848 resetDisplayInteractivities(); 849 mInputManagerInternal.setDisplayInteractivities(mDisplayInteractivities); 850 } 851 } 852 853 /** 854 * Called when there has been user activity. 855 */ onUserActivity(int displayGroupId, @PowerManager.UserActivityEvent int event, int uid)856 public void onUserActivity(int displayGroupId, @PowerManager.UserActivityEvent int event, 857 int uid) { 858 if (DEBUG) { 859 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid); 860 } 861 862 try { 863 mBatteryStats.noteUserActivity(uid, event); 864 mWakefulnessSessionObserver.notifyUserActivity( 865 SystemClock.uptimeMillis(), displayGroupId, event); 866 } catch (RemoteException ex) { 867 // Ignore 868 } 869 870 synchronized (mLock) { 871 if (!mUserActivityPending) { 872 mUserActivityPending = true; 873 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY); 874 msg.arg1 = displayGroupId; 875 msg.arg2 = event; 876 msg.setAsynchronous(true); 877 mHandler.sendMessage(msg); 878 } 879 } 880 } 881 882 /** 883 * Called when the screen has turned on. 884 */ onWakeUp(int reason, String details, int reasonUid, String opPackageName, int opUid)885 public void onWakeUp(int reason, String details, int reasonUid, String opPackageName, 886 int opUid) { 887 if (DEBUG) { 888 Slog.d(TAG, "onWakeUp: reason=" + PowerManager.wakeReasonToString(reason) 889 + ", details=" + details + ", reasonUid=" + reasonUid 890 + " opPackageName=" + opPackageName + " opUid=" + opUid); 891 } 892 893 try { 894 mBatteryStats.noteWakeUp(details, reasonUid); 895 if (opPackageName != null) { 896 mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName); 897 } 898 } catch (RemoteException ex) { 899 // Ignore 900 } 901 FrameworkStatsLog.write(FrameworkStatsLog.DISPLAY_WAKE_REPORTED, reason, reasonUid); 902 } 903 904 /** 905 * Called when profile screen lock timeout has expired. 906 */ onProfileTimeout(@serIdInt int userId)907 public void onProfileTimeout(@UserIdInt int userId) { 908 final Message msg = mHandler.obtainMessage(MSG_PROFILE_TIMED_OUT); 909 msg.setAsynchronous(true); 910 msg.arg1 = userId; 911 mHandler.sendMessage(msg); 912 } 913 914 /** 915 * Called when wireless charging has started - to provide user feedback (sound and visual). 916 */ onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId)917 public void onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) { 918 if (DEBUG) { 919 Slog.d(TAG, "onWirelessChargingStarted"); 920 } 921 922 mSuspendBlocker.acquire(); 923 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED); 924 msg.setAsynchronous(true); 925 msg.arg1 = batteryLevel; 926 msg.arg2 = userId; 927 mHandler.sendMessage(msg); 928 } 929 930 /** 931 * Called when wired charging has started - to provide user feedback 932 */ onWiredChargingStarted(@serIdInt int userId)933 public void onWiredChargingStarted(@UserIdInt int userId) { 934 if (DEBUG) { 935 Slog.d(TAG, "onWiredChargingStarted"); 936 } 937 938 mSuspendBlocker.acquire(); 939 Message msg = mHandler.obtainMessage(MSG_WIRED_CHARGING_STARTED); 940 msg.setAsynchronous(true); 941 msg.arg1 = userId; 942 mHandler.sendMessage(msg); 943 } 944 945 /** 946 * Called when the screen policy changes. 947 */ onScreenPolicyUpdate(int displayGroupId, int newPolicy)948 public void onScreenPolicyUpdate(int displayGroupId, int newPolicy) { 949 if (DEBUG) { 950 Slog.d(TAG, "onScreenPolicyUpdate: newPolicy=" + newPolicy); 951 } 952 mWakefulnessSessionObserver.onScreenPolicyUpdate( 953 SystemClock.uptimeMillis(), displayGroupId, newPolicy); 954 955 synchronized (mLock) { 956 Message msg = mHandler.obtainMessage(MSG_SCREEN_POLICY); 957 msg.arg1 = displayGroupId; 958 msg.arg2 = newPolicy; 959 msg.setAsynchronous(true); 960 mHandler.sendMessage(msg); 961 } 962 } 963 964 /** 965 * Dumps data for bugreports. 966 * 967 * @param pw The stream to print to. 968 */ dump(PrintWriter pw)969 public void dump(PrintWriter pw) { 970 pw.println("Notifier:"); 971 972 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 973 ipw.println("Partial Wakelock Log:"); 974 mPartialWakeLockLog.dump(ipw); 975 976 ipw.println(""); 977 ipw.println("Full Wakelock Log:"); 978 mFullWakeLockLog.dump(ipw); 979 980 ipw.println(""); 981 mWakefulnessSessionObserver.dump(ipw); 982 } 983 updatePendingBroadcastLocked()984 private void updatePendingBroadcastLocked() { 985 if (!mBroadcastInProgress 986 && mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN 987 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 988 || mPendingInteractiveState != mBroadcastedInteractiveState)) { 989 mBroadcastInProgress = true; 990 mSuspendBlocker.acquire(); 991 Message msg = mHandler.obtainMessage(MSG_BROADCAST); 992 msg.setAsynchronous(true); 993 mHandler.sendMessage(msg); 994 } 995 } 996 finishPendingBroadcastLocked()997 private void finishPendingBroadcastLocked() { 998 mBroadcastInProgress = false; 999 mSuspendBlocker.release(); 1000 } 1001 sendUserActivity(int displayGroupId, int event)1002 private void sendUserActivity(int displayGroupId, int event) { 1003 synchronized (mLock) { 1004 if (!mUserActivityPending) { 1005 return; 1006 } 1007 mUserActivityPending = false; 1008 } 1009 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 1010 tm.notifyUserActivity(); 1011 mInputManagerInternal.notifyUserActivity(); 1012 mPolicy.userActivity(displayGroupId, event); 1013 mFaceDownDetector.userActivity(event); 1014 mScreenUndimDetector.userActivity(displayGroupId); 1015 } 1016 postEnhancedDischargePredictionBroadcast(long delayMs)1017 void postEnhancedDischargePredictionBroadcast(long delayMs) { 1018 mHandler.sendEmptyMessageDelayed(MSG_BROADCAST_ENHANCED_PREDICTION, delayMs); 1019 } 1020 sendEnhancedDischargePredictionBroadcast()1021 private void sendEnhancedDischargePredictionBroadcast() { 1022 Intent intent = new Intent(PowerManager.ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED) 1023 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 1024 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 1025 } 1026 sendNextBroadcast()1027 private void sendNextBroadcast() { 1028 final int powerState; 1029 synchronized (mLock) { 1030 if (mBroadcastedInteractiveState == INTERACTIVE_STATE_UNKNOWN) { 1031 // Broadcasted power state is unknown. 1032 // Send wake up or go to sleep. 1033 switch (mPendingInteractiveState) { 1034 case INTERACTIVE_STATE_ASLEEP: 1035 mPendingGoToSleepBroadcast = false; 1036 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP; 1037 break; 1038 1039 case INTERACTIVE_STATE_AWAKE: 1040 default: 1041 mPendingWakeUpBroadcast = false; 1042 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; 1043 break; 1044 } 1045 } else if (mBroadcastedInteractiveState == INTERACTIVE_STATE_AWAKE) { 1046 // Broadcasted power state is awake. Send asleep if needed. 1047 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 1048 || mPendingInteractiveState == INTERACTIVE_STATE_ASLEEP) { 1049 mPendingGoToSleepBroadcast = false; 1050 mBroadcastedInteractiveState = INTERACTIVE_STATE_ASLEEP; 1051 } else { 1052 finishPendingBroadcastLocked(); 1053 return; 1054 } 1055 } else { 1056 // Broadcasted power state is asleep. Send awake if needed. 1057 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 1058 || mPendingInteractiveState == INTERACTIVE_STATE_AWAKE) { 1059 mPendingWakeUpBroadcast = false; 1060 mBroadcastedInteractiveState = INTERACTIVE_STATE_AWAKE; 1061 } else { 1062 finishPendingBroadcastLocked(); 1063 return; 1064 } 1065 } 1066 1067 mBroadcastStartTime = SystemClock.uptimeMillis(); 1068 powerState = mBroadcastedInteractiveState; 1069 } 1070 1071 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1); 1072 1073 if (powerState == INTERACTIVE_STATE_AWAKE) { 1074 sendWakeUpBroadcast(); 1075 } else { 1076 sendGoToSleepBroadcast(); 1077 } 1078 } 1079 sendWakeUpBroadcast()1080 private void sendWakeUpBroadcast() { 1081 if (DEBUG) { 1082 Slog.d(TAG, "Sending wake up broadcast."); 1083 } 1084 1085 if (mActivityManagerInternal.isSystemReady()) { 1086 mActivityManagerInternal.broadcastIntentWithCallback(mScreenOnIntent, 1087 mWakeUpBroadcastDone, null, UserHandle.USER_ALL, 1088 null, null, mScreenOnOffOptions); 1089 } else { 1090 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1); 1091 sendNextBroadcast(); 1092 } 1093 } 1094 1095 private final IIntentReceiver mWakeUpBroadcastDone = new IIntentReceiver.Stub() { 1096 @Override 1097 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 1098 boolean ordered, boolean sticky, int sendingUser) { 1099 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, 1100 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 1101 sendNextBroadcast(); 1102 } 1103 }; 1104 sendGoToSleepBroadcast()1105 private void sendGoToSleepBroadcast() { 1106 if (DEBUG) { 1107 Slog.d(TAG, "Sending go to sleep broadcast."); 1108 } 1109 1110 if (mActivityManagerInternal.isSystemReady()) { 1111 mActivityManagerInternal.broadcastIntentWithCallback(mScreenOffIntent, 1112 mGoToSleepBroadcastDone, null, UserHandle.USER_ALL, 1113 null, null, mScreenOnOffOptions); 1114 } else { 1115 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1); 1116 sendNextBroadcast(); 1117 } 1118 } 1119 1120 private final IIntentReceiver mGoToSleepBroadcastDone = new IIntentReceiver.Stub() { 1121 @Override 1122 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 1123 boolean ordered, boolean sticky, int sendingUser) { 1124 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, 1125 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 1126 sendNextBroadcast(); 1127 } 1128 }; 1129 playChargingStartedFeedback(@serIdInt int userId, boolean wireless)1130 private void playChargingStartedFeedback(@UserIdInt int userId, boolean wireless) { 1131 if (!isChargingFeedbackEnabled(userId)) { 1132 return; 1133 } 1134 1135 if (!mIsPlayingChargingStartedFeedback.compareAndSet(false, true)) { 1136 // there's already a charging started feedback Runnable scheduled to run on the 1137 // background thread, so let's not execute another 1138 return; 1139 } 1140 1141 // vibrate & play sound on a background thread 1142 mBackgroundExecutor.execute(() -> { 1143 // vibrate 1144 final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1145 Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0; 1146 if (vibrate) { 1147 mVibrator.vibrate(Process.SYSTEM_UID, mContext.getOpPackageName(), 1148 CHARGING_VIBRATION_EFFECT, /* reason= */ "Charging started", 1149 HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES); 1150 } 1151 1152 // play sound 1153 final String soundPath = Settings.Global.getString(mContext.getContentResolver(), 1154 wireless ? Settings.Global.WIRELESS_CHARGING_STARTED_SOUND 1155 : Settings.Global.CHARGING_STARTED_SOUND); 1156 final Uri soundUri = Uri.parse("file://" + soundPath); 1157 if (soundUri != null) { 1158 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); 1159 if (sfx != null) { 1160 sfx.setStreamType(AudioManager.STREAM_SYSTEM); 1161 sfx.play(); 1162 } 1163 } 1164 mIsPlayingChargingStartedFeedback.set(false); 1165 }); 1166 } 1167 showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId)1168 private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) { 1169 // play sounds + haptics 1170 playChargingStartedFeedback(userId, true /* wireless */); 1171 1172 // show animation 1173 if (mShowWirelessChargingAnimationConfig && mStatusBarManagerInternal != null) { 1174 mStatusBarManagerInternal.showChargingAnimation(batteryLevel); 1175 } 1176 mSuspendBlocker.release(); 1177 } 1178 showWiredChargingStarted(@serIdInt int userId)1179 private void showWiredChargingStarted(@UserIdInt int userId) { 1180 playChargingStartedFeedback(userId, false /* wireless */); 1181 mSuspendBlocker.release(); 1182 } 1183 screenPolicyChanging(int displayGroupId, int screenPolicy)1184 private void screenPolicyChanging(int displayGroupId, int screenPolicy) { 1185 mScreenUndimDetector.recordScreenPolicy(displayGroupId, screenPolicy); 1186 } 1187 lockProfile(@serIdInt int userId)1188 private void lockProfile(@UserIdInt int userId) { 1189 mTrustManager.setDeviceLockedForUser(userId, true /*locked*/); 1190 } 1191 isChargingFeedbackEnabled(@serIdInt int userId)1192 private boolean isChargingFeedbackEnabled(@UserIdInt int userId) { 1193 final boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), 1194 Settings.Secure.CHARGING_SOUNDS_ENABLED, 1, userId) != 0; 1195 final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(), 1196 Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) 1197 == Settings.Global.ZEN_MODE_OFF; 1198 return enabled && dndOff; 1199 } 1200 notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled, int ownerUid, int ownerPid, int flags, WorkSource workSource, String packageName, String historyTag)1201 private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled, 1202 int ownerUid, int ownerPid, int flags, WorkSource workSource, String packageName, 1203 String historyTag) { 1204 long currentTime = mInjector.currentTimeMillis(); 1205 mHandler.post(() -> { 1206 if (mFlags.improveWakelockLatency()) { 1207 if (isEnabled) { 1208 notifyWakelockAcquisition(tag, ownerUid, ownerPid, flags, 1209 workSource, packageName, historyTag, currentTime); 1210 } else { 1211 notifyWakelockRelease(tag, ownerUid, ownerPid, flags, 1212 workSource, packageName, historyTag, currentTime); 1213 } 1214 } 1215 1216 if (callback != null) { 1217 try { 1218 callback.onStateChanged(isEnabled); 1219 } catch (RemoteException e) { 1220 Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e); 1221 } 1222 } 1223 }); 1224 } 1225 1226 @SuppressLint("AndroidFrameworkRequiresPermission") notifyWakelockAcquisition(String tag, int ownerUid, int ownerPid, int flags, WorkSource workSource, String packageName, String historyTag, long currentTime)1227 private void notifyWakelockAcquisition(String tag, int ownerUid, int ownerPid, int flags, 1228 WorkSource workSource, String packageName, String historyTag, long currentTime) { 1229 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 1230 if (monitorType >= 0) { 1231 try { 1232 final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID 1233 && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0; 1234 if (workSource != null) { 1235 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, 1236 historyTag, monitorType, unimportantForLogging); 1237 } else { 1238 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag, 1239 monitorType, unimportantForLogging); 1240 // XXX need to deal with disabled operations. 1241 mAppOps.startOpNoThrow( 1242 AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, 1243 false, null, null); 1244 } 1245 } catch (RemoteException ex) { 1246 // Do Nothing 1247 } 1248 } 1249 1250 getWakeLockLog(flags).onWakeLockAcquired(tag, getUidForWakeLockLog(ownerUid, workSource), 1251 flags, currentTime); 1252 } 1253 1254 @SuppressLint("AndroidFrameworkRequiresPermission") notifyWakelockRelease(String tag, int ownerUid, int ownerPid, int flags, WorkSource workSource, String packageName, String historyTag, long currentTime)1255 private void notifyWakelockRelease(String tag, int ownerUid, int ownerPid, int flags, 1256 WorkSource workSource, String packageName, String historyTag, long currentTime) { 1257 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 1258 if (monitorType >= 0) { 1259 try { 1260 if (workSource != null) { 1261 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, 1262 historyTag, monitorType); 1263 } else { 1264 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, 1265 historyTag, monitorType); 1266 mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, null); 1267 } 1268 } catch (RemoteException ex) { 1269 // Ignore 1270 } 1271 } 1272 getWakeLockLog(flags).onWakeLockReleased(tag, getUidForWakeLockLog(ownerUid, workSource), 1273 currentTime); 1274 } 1275 1276 @SuppressLint("AndroidFrameworkRequiresPermission") notifyWakelockChanging(WorkSource workSource, int ownerPid, String tag, String historyTag, int monitorType, WorkSource newWorkSource, int newOwnerPid, String newTag, String newHistoryTag, int newMonitorType, boolean unimportantForLogging)1277 private void notifyWakelockChanging(WorkSource workSource, int ownerPid, String tag, 1278 String historyTag, int monitorType, WorkSource newWorkSource, int newOwnerPid, 1279 String newTag, String newHistoryTag, int newMonitorType, boolean unimportantForLogging) 1280 throws RemoteException { 1281 if (!mFlags.improveWakelockLatency()) { 1282 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, 1283 historyTag, monitorType, newWorkSource, newOwnerPid, newTag, 1284 newHistoryTag, newMonitorType, unimportantForLogging); 1285 } else { 1286 mHandler.post(() -> { 1287 try { 1288 mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, 1289 historyTag, monitorType, newWorkSource, newOwnerPid, newTag, 1290 newHistoryTag, newMonitorType, unimportantForLogging); 1291 } catch (RemoteException e) { 1292 Slog.e(TAG, "Failed to notify the wakelock changing from source via " 1293 + "Notifier." + e.getLocalizedMessage()); 1294 } 1295 }); 1296 } 1297 } 1298 1299 /** 1300 * Adds a listener for the screen timeout policy 1301 * @param displayId display ID 1302 * @param screenTimeoutPolicy initial state of the timeout policy 1303 * @param listener callback to receive screen timeout policy updates 1304 */ addScreenTimeoutPolicyListener(int displayId, @ScreenTimeoutPolicy int screenTimeoutPolicy, IScreenTimeoutPolicyListener listener)1305 void addScreenTimeoutPolicyListener(int displayId, @ScreenTimeoutPolicy int screenTimeoutPolicy, 1306 IScreenTimeoutPolicyListener listener) { 1307 synchronized (mLock) { 1308 ScreenTimeoutPolicyListenersContainer listenersContainer = 1309 mScreenTimeoutPolicyListeners.get(displayId); 1310 if (listenersContainer == null) { 1311 listenersContainer = new ScreenTimeoutPolicyListenersContainer( 1312 screenTimeoutPolicy); 1313 mScreenTimeoutPolicyListeners.set(displayId, listenersContainer); 1314 } 1315 1316 listenersContainer.addListener(listener); 1317 } 1318 } 1319 1320 /** 1321 * Removes a listener for the screen timeout policy 1322 * @param displayId display id from which the listener should be removed 1323 * @param listener the instance of the listener 1324 */ removeScreenTimeoutPolicyListener(int displayId, IScreenTimeoutPolicyListener listener)1325 void removeScreenTimeoutPolicyListener(int displayId, 1326 IScreenTimeoutPolicyListener listener) { 1327 synchronized (mLock) { 1328 ScreenTimeoutPolicyListenersContainer listenersContainer = 1329 mScreenTimeoutPolicyListeners.get(displayId); 1330 if (listenersContainer == null) { 1331 return; 1332 } 1333 1334 listenersContainer.removeListener(listener); 1335 1336 if (listenersContainer.isEmpty()) { 1337 mScreenTimeoutPolicyListeners.remove(displayId); 1338 } 1339 } 1340 } 1341 1342 /** 1343 * Clears all screen timeout policy listeners for the specified display id 1344 * @param displayId display id from which the listeners should be cleared 1345 */ clearScreenTimeoutPolicyListeners(int displayId)1346 void clearScreenTimeoutPolicyListeners(int displayId) { 1347 synchronized (mLock) { 1348 mScreenTimeoutPolicyListeners.remove(displayId); 1349 } 1350 } 1351 1352 /** 1353 * Notifies about screen timeout policy changes of the corresponding display group if 1354 * it has changed 1355 * @param displayGroupId the id of the display group to report 1356 * @param screenTimeoutPolicy screen timeout policy 1357 */ notifyScreenTimeoutPolicyChanges(int displayGroupId, @ScreenTimeoutPolicy int screenTimeoutPolicy)1358 void notifyScreenTimeoutPolicyChanges(int displayGroupId, 1359 @ScreenTimeoutPolicy int screenTimeoutPolicy) { 1360 synchronized (mLock) { 1361 for (int idx = 0; idx < mScreenTimeoutPolicyListeners.size(); idx++) { 1362 final int displayId = mScreenTimeoutPolicyListeners.keyAt(idx); 1363 if (mDisplayManagerInternal.getGroupIdForDisplay(displayId) == displayGroupId) { 1364 final ScreenTimeoutPolicyListenersContainer container = 1365 mScreenTimeoutPolicyListeners.valueAt(idx); 1366 container.updateScreenTimeoutPolicyAndNotifyIfNeeded(screenTimeoutPolicy); 1367 } 1368 } 1369 } 1370 } 1371 1372 private final class ScreenTimeoutPolicyListenersContainer { 1373 private final RemoteCallbackList<IScreenTimeoutPolicyListener> mListeners; 1374 private final ArrayMap<IScreenTimeoutPolicyListener, Integer> mLastReportedState = 1375 new ArrayMap<>(); 1376 1377 @ScreenTimeoutPolicy 1378 private volatile int mScreenTimeoutPolicy; 1379 ScreenTimeoutPolicyListenersContainer(int screenTimeoutPolicy)1380 ScreenTimeoutPolicyListenersContainer(int screenTimeoutPolicy) { 1381 mScreenTimeoutPolicy = screenTimeoutPolicy; 1382 mListeners = new RemoteCallbackList<IScreenTimeoutPolicyListener>() { 1383 @Override 1384 public void onCallbackDied(IScreenTimeoutPolicyListener callbackInterface) { 1385 mLastReportedState.remove(callbackInterface); 1386 } 1387 }; 1388 } 1389 updateScreenTimeoutPolicyAndNotifyIfNeeded( @creenTimeoutPolicy int screenTimeoutPolicy)1390 void updateScreenTimeoutPolicyAndNotifyIfNeeded( 1391 @ScreenTimeoutPolicy int screenTimeoutPolicy) { 1392 mScreenTimeoutPolicy = screenTimeoutPolicy; 1393 1394 mHandler.post(() -> { 1395 for (int i = mListeners.beginBroadcast() - 1; i >= 0; i--) { 1396 final IScreenTimeoutPolicyListener listener = mListeners.getBroadcastItem(i); 1397 notifyListenerIfNeeded(listener); 1398 } 1399 mListeners.finishBroadcast(); 1400 }); 1401 } 1402 addListener(IScreenTimeoutPolicyListener listener)1403 void addListener(IScreenTimeoutPolicyListener listener) { 1404 mListeners.register(listener); 1405 mHandler.post(() -> notifyListenerIfNeeded(listener)); 1406 } 1407 removeListener(IScreenTimeoutPolicyListener listener)1408 void removeListener(IScreenTimeoutPolicyListener listener) { 1409 mListeners.unregister(listener); 1410 mLastReportedState.remove(listener); 1411 } 1412 isEmpty()1413 boolean isEmpty() { 1414 return mListeners.getRegisteredCallbackCount() == 0; 1415 } 1416 notifyListenerIfNeeded(IScreenTimeoutPolicyListener listener)1417 private void notifyListenerIfNeeded(IScreenTimeoutPolicyListener listener) { 1418 final int currentScreenTimeoutPolicy = mScreenTimeoutPolicy; 1419 final Integer reportedScreenTimeoutPolicy = mLastReportedState.get(listener); 1420 final boolean needsReporting = reportedScreenTimeoutPolicy == null 1421 || !reportedScreenTimeoutPolicy.equals(currentScreenTimeoutPolicy); 1422 1423 if (!needsReporting) return; 1424 1425 try { 1426 listener.onScreenTimeoutPolicyChanged(currentScreenTimeoutPolicy); 1427 mLastReportedState.put(listener, currentScreenTimeoutPolicy); 1428 } catch (RemoteException e) { 1429 // The RemoteCallbackList will take care of removing 1430 // the dead object for us. 1431 Slog.e(TAG, "Remote exception when notifying screen timeout policy change", e); 1432 } catch (Throwable e) { 1433 Slog.e(TAG, "Exception when notifying screen timeout policy change", e); 1434 removeListener(listener); 1435 } 1436 } 1437 } 1438 getWakeLockLog(int flags)1439 private @NonNull WakeLockLog getWakeLockLog(int flags) { 1440 return PowerManagerService.isScreenLock(flags) ? mFullWakeLockLog : mPartialWakeLockLog; 1441 } 1442 getUidForWakeLockLog(int ownerUid, WorkSource workSource)1443 private int getUidForWakeLockLog(int ownerUid, WorkSource workSource) { 1444 int attributionUid = workSource != null ? workSource.getAttributionUid() : -1; 1445 return attributionUid != -1 ? attributionUid : ownerUid; 1446 } 1447 1448 private final class NotifierHandler extends Handler { 1449 NotifierHandler(Looper looper)1450 public NotifierHandler(Looper looper) { 1451 super(looper, null, true /*async*/); 1452 } 1453 1454 @Override handleMessage(Message msg)1455 public void handleMessage(Message msg) { 1456 switch (msg.what) { 1457 case MSG_USER_ACTIVITY: 1458 sendUserActivity(msg.arg1, msg.arg2); 1459 break; 1460 case MSG_BROADCAST: 1461 sendNextBroadcast(); 1462 break; 1463 case MSG_WIRELESS_CHARGING_STARTED: 1464 showWirelessChargingStarted(msg.arg1, msg.arg2); 1465 break; 1466 case MSG_BROADCAST_ENHANCED_PREDICTION: 1467 removeMessages(MSG_BROADCAST_ENHANCED_PREDICTION); 1468 sendEnhancedDischargePredictionBroadcast(); 1469 break; 1470 case MSG_PROFILE_TIMED_OUT: 1471 lockProfile(msg.arg1); 1472 break; 1473 case MSG_WIRED_CHARGING_STARTED: 1474 showWiredChargingStarted(msg.arg1); 1475 break; 1476 case MSG_SCREEN_POLICY: 1477 screenPolicyChanging(msg.arg1, msg.arg2); 1478 break; 1479 } 1480 } 1481 } 1482 logWakelockStateChanged( int flags, String tag, int ownerUid, WorkSource workSource, WakelockEventType eventType)1483 private void logWakelockStateChanged( 1484 int flags, 1485 String tag, 1486 int ownerUid, 1487 WorkSource workSource, 1488 WakelockEventType eventType) { 1489 if (mBatteryStatsInternal == null) { 1490 return; 1491 } 1492 final int type = getWakelockMonitorTypeForLogging(flags); 1493 if (workSource == null || workSource.isEmpty()) { 1494 final int mappedUid = mBatteryStatsInternal.getOwnerUid(ownerUid); 1495 mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); 1496 } else { 1497 for (int i = 0; i < workSource.size(); ++i) { 1498 final int mappedUid = mBatteryStatsInternal.getOwnerUid(workSource.getUid(i)); 1499 mFrameworkStatsLogger.wakelockStateChanged(mappedUid, tag, type, eventType); 1500 } 1501 1502 List<WorkChain> workChains = workSource.getWorkChains(); 1503 if (workChains != null) { 1504 for (WorkChain workChain : workChains) { 1505 WorkChain mappedWorkChain = new WorkChain(); 1506 // Cache getUids() and getTags() because they make an arraycopy. 1507 int[] uids = workChain.getUids(); 1508 String[] tags = workChain.getTags(); 1509 1510 for (int i = 0; i < workChain.getSize(); ++i) { 1511 final int mappedUid = mBatteryStatsInternal.getOwnerUid(uids[i]); 1512 mappedWorkChain.addNode(mappedUid, tags[i]); 1513 } 1514 mFrameworkStatsLogger.wakelockStateChanged( 1515 tag, mappedWorkChain, type, eventType); 1516 } 1517 } 1518 } 1519 } 1520 1521 public interface Injector { 1522 /** 1523 * Gets the current time in millis 1524 */ currentTimeMillis()1525 long currentTimeMillis(); 1526 1527 /** 1528 * Gets the WakeLockLog object 1529 */ getWakeLockLog(Context context)1530 @NonNull WakeLockLog getWakeLockLog(Context context); 1531 1532 /** 1533 * Gets the AppOpsManager system service 1534 */ getAppOpsManager(Context context)1535 AppOpsManager getAppOpsManager(Context context); 1536 1537 /** Gets the BatteryStatsInternal object */ getBatteryStatsInternal()1538 BatteryStatsInternal getBatteryStatsInternal(); 1539 1540 /** Get the FrameworkStatsLogger object */ getFrameworkStatsLogger()1541 FrameworkStatsLogger getFrameworkStatsLogger(); 1542 } 1543 1544 class RealInjector implements Injector { 1545 @Override currentTimeMillis()1546 public long currentTimeMillis() { 1547 return System.currentTimeMillis(); 1548 } 1549 1550 @Override getWakeLockLog(Context context)1551 public @NonNull WakeLockLog getWakeLockLog(Context context) { 1552 return new WakeLockLog(context); 1553 } 1554 1555 @Override getAppOpsManager(Context context)1556 public AppOpsManager getAppOpsManager(Context context) { 1557 return context.getSystemService(AppOpsManager.class); 1558 } 1559 1560 @Override getBatteryStatsInternal()1561 public BatteryStatsInternal getBatteryStatsInternal() { 1562 return LocalServices.getService(BatteryStatsInternal.class); 1563 } 1564 1565 @Override getFrameworkStatsLogger()1566 public FrameworkStatsLogger getFrameworkStatsLogger() { 1567 return new FrameworkStatsLogger(); 1568 } 1569 } 1570 } 1571