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 com.android.internal.app.IBatteryStats; 20 import com.android.server.EventLogTags; 21 22 import android.app.ActivityManagerNative; 23 import android.content.BroadcastReceiver; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.media.AudioManager; 27 import android.media.Ringtone; 28 import android.media.RingtoneManager; 29 import android.net.Uri; 30 import android.os.BatteryStats; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.os.Message; 34 import android.os.PowerManager; 35 import android.os.RemoteException; 36 import android.os.SystemClock; 37 import android.os.UserHandle; 38 import android.os.WorkSource; 39 import android.provider.Settings; 40 import android.util.EventLog; 41 import android.util.Slog; 42 import android.view.WindowManagerPolicy; 43 44 /** 45 * Sends broadcasts about important power state changes. 46 * <p> 47 * This methods of this class may be called by the power manager service while 48 * its lock is being held. Internally it takes care of sending broadcasts to 49 * notify other components of the system or applications asynchronously. 50 * </p><p> 51 * The notifier is designed to collapse unnecessary broadcasts when it is not 52 * possible for the system to have observed an intermediate state. 53 * </p><p> 54 * For example, if the device wakes up, goes to sleep, wakes up again and goes to 55 * sleep again before the wake up notification is sent, then the system will 56 * be told about only one wake up and sleep. However, we always notify the 57 * fact that at least one transition occurred. It is especially important to 58 * tell the system when we go to sleep so that it can lock the keyguard if needed. 59 * </p> 60 */ 61 final class Notifier { 62 private static final String TAG = "PowerManagerNotifier"; 63 64 private static final boolean DEBUG = false; 65 66 private static final int POWER_STATE_UNKNOWN = 0; 67 private static final int POWER_STATE_AWAKE = 1; 68 private static final int POWER_STATE_ASLEEP = 2; 69 70 private static final int MSG_USER_ACTIVITY = 1; 71 private static final int MSG_BROADCAST = 2; 72 private static final int MSG_WIRELESS_CHARGING_STARTED = 3; 73 74 private final Object mLock = new Object(); 75 76 private final Context mContext; 77 private final IBatteryStats mBatteryStats; 78 private final SuspendBlocker mSuspendBlocker; 79 private final ScreenOnBlocker mScreenOnBlocker; 80 private final WindowManagerPolicy mPolicy; 81 82 private final NotifierHandler mHandler; 83 private final Intent mScreenOnIntent; 84 private final Intent mScreenOffIntent; 85 86 // The current power state. 87 private int mActualPowerState; 88 private int mLastGoToSleepReason; 89 90 // True if there is a pending transition that needs to be reported. 91 private boolean mPendingWakeUpBroadcast; 92 private boolean mPendingGoToSleepBroadcast; 93 94 // The currently broadcasted power state. This reflects what other parts of the 95 // system have observed. 96 private int mBroadcastedPowerState; 97 private boolean mBroadcastInProgress; 98 private long mBroadcastStartTime; 99 100 // True if a user activity message should be sent. 101 private boolean mUserActivityPending; 102 103 // True if the screen on blocker has been acquired. 104 private boolean mScreenOnBlockerAcquired; 105 106 public Notifier(Looper looper, Context context, IBatteryStats batteryStats, 107 SuspendBlocker suspendBlocker, ScreenOnBlocker screenOnBlocker, 108 WindowManagerPolicy policy) { 109 mContext = context; 110 mBatteryStats = batteryStats; 111 mSuspendBlocker = suspendBlocker; 112 mScreenOnBlocker = screenOnBlocker; 113 mPolicy = policy; 114 115 mHandler = new NotifierHandler(looper); 116 mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON); 117 mScreenOnIntent.addFlags( 118 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); 119 mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF); 120 mScreenOffIntent.addFlags( 121 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); 122 } 123 124 /** 125 * Called when a wake lock is acquired. 126 */ 127 public void onWakeLockAcquired(int flags, String tag, int ownerUid, int ownerPid, 128 WorkSource workSource) { 129 if (DEBUG) { 130 Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag 131 + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 132 + ", workSource=" + workSource); 133 } 134 135 try { 136 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 137 if (workSource != null) { 138 mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType); 139 } else { 140 mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType); 141 } 142 } catch (RemoteException ex) { 143 // Ignore 144 } 145 } 146 147 /** 148 * Called when a wake lock is released. 149 */ 150 public void onWakeLockReleased(int flags, String tag, int ownerUid, int ownerPid, 151 WorkSource workSource) { 152 if (DEBUG) { 153 Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag 154 + "\", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid 155 + ", workSource=" + workSource); 156 } 157 158 try { 159 final int monitorType = getBatteryStatsWakeLockMonitorType(flags); 160 if (workSource != null) { 161 mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, monitorType); 162 } else { 163 mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, monitorType); 164 } 165 } catch (RemoteException ex) { 166 // Ignore 167 } 168 } 169 170 private static int getBatteryStatsWakeLockMonitorType(int flags) { 171 switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) { 172 case PowerManager.PARTIAL_WAKE_LOCK: 173 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: 174 return BatteryStats.WAKE_TYPE_PARTIAL; 175 default: 176 return BatteryStats.WAKE_TYPE_FULL; 177 } 178 } 179 180 /** 181 * Called when the screen is turned on. 182 */ 183 public void onScreenOn() { 184 if (DEBUG) { 185 Slog.d(TAG, "onScreenOn"); 186 } 187 188 try { 189 mBatteryStats.noteScreenOn(); 190 } catch (RemoteException ex) { 191 // Ignore 192 } 193 } 194 195 /** 196 * Called when the screen is turned off. 197 */ 198 public void onScreenOff() { 199 if (DEBUG) { 200 Slog.d(TAG, "onScreenOff"); 201 } 202 203 try { 204 mBatteryStats.noteScreenOff(); 205 } catch (RemoteException ex) { 206 // Ignore 207 } 208 } 209 210 /** 211 * Called when the screen changes brightness. 212 */ 213 public void onScreenBrightness(int brightness) { 214 if (DEBUG) { 215 Slog.d(TAG, "onScreenBrightness: brightness=" + brightness); 216 } 217 218 try { 219 mBatteryStats.noteScreenBrightness(brightness); 220 } catch (RemoteException ex) { 221 // Ignore 222 } 223 } 224 225 /** 226 * Called when the device is waking up from sleep and the 227 * display is about to be turned on. 228 */ 229 public void onWakeUpStarted() { 230 if (DEBUG) { 231 Slog.d(TAG, "onWakeUpStarted"); 232 } 233 234 synchronized (mLock) { 235 if (mActualPowerState != POWER_STATE_AWAKE) { 236 mActualPowerState = POWER_STATE_AWAKE; 237 mPendingWakeUpBroadcast = true; 238 if (!mScreenOnBlockerAcquired) { 239 mScreenOnBlockerAcquired = true; 240 mScreenOnBlocker.acquire(); 241 } 242 updatePendingBroadcastLocked(); 243 } 244 } 245 } 246 247 /** 248 * Called when the device has finished waking up from sleep 249 * and the display has been turned on. 250 */ 251 public void onWakeUpFinished() { 252 if (DEBUG) { 253 Slog.d(TAG, "onWakeUpFinished"); 254 } 255 } 256 257 /** 258 * Called when the device is going to sleep. 259 */ 260 public void onGoToSleepStarted(int reason) { 261 if (DEBUG) { 262 Slog.d(TAG, "onGoToSleepStarted"); 263 } 264 265 synchronized (mLock) { 266 mLastGoToSleepReason = reason; 267 } 268 } 269 270 /** 271 * Called when the device has finished going to sleep and the 272 * display has been turned off. 273 * 274 * This is a good time to make transitions that we don't want the user to see, 275 * such as bringing the key guard to focus. There's no guarantee for this, 276 * however because the user could turn the device on again at any time. 277 * Some things may need to be protected by other mechanisms that defer screen on. 278 */ 279 public void onGoToSleepFinished() { 280 if (DEBUG) { 281 Slog.d(TAG, "onGoToSleepFinished"); 282 } 283 284 synchronized (mLock) { 285 if (mActualPowerState != POWER_STATE_ASLEEP) { 286 mActualPowerState = POWER_STATE_ASLEEP; 287 mPendingGoToSleepBroadcast = true; 288 if (mUserActivityPending) { 289 mUserActivityPending = false; 290 mHandler.removeMessages(MSG_USER_ACTIVITY); 291 } 292 updatePendingBroadcastLocked(); 293 } 294 } 295 } 296 297 /** 298 * Called when there has been user activity. 299 */ 300 public void onUserActivity(int event, int uid) { 301 if (DEBUG) { 302 Slog.d(TAG, "onUserActivity: event=" + event + ", uid=" + uid); 303 } 304 305 try { 306 mBatteryStats.noteUserActivity(uid, event); 307 } catch (RemoteException ex) { 308 // Ignore 309 } 310 311 synchronized (mLock) { 312 if (!mUserActivityPending) { 313 mUserActivityPending = true; 314 Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY); 315 msg.setAsynchronous(true); 316 mHandler.sendMessage(msg); 317 } 318 } 319 } 320 321 /** 322 * Called when wireless charging has started so as to provide user feedback. 323 */ 324 public void onWirelessChargingStarted() { 325 if (DEBUG) { 326 Slog.d(TAG, "onWirelessChargingStarted"); 327 } 328 329 mSuspendBlocker.acquire(); 330 Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED); 331 msg.setAsynchronous(true); 332 mHandler.sendMessage(msg); 333 } 334 335 private void updatePendingBroadcastLocked() { 336 if (!mBroadcastInProgress 337 && mActualPowerState != POWER_STATE_UNKNOWN 338 && (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 339 || mActualPowerState != mBroadcastedPowerState)) { 340 mBroadcastInProgress = true; 341 mSuspendBlocker.acquire(); 342 Message msg = mHandler.obtainMessage(MSG_BROADCAST); 343 msg.setAsynchronous(true); 344 mHandler.sendMessage(msg); 345 } 346 } 347 348 private void finishPendingBroadcastLocked() { 349 mBroadcastInProgress = false; 350 mSuspendBlocker.release(); 351 } 352 353 private void sendUserActivity() { 354 synchronized (mLock) { 355 if (!mUserActivityPending) { 356 return; 357 } 358 mUserActivityPending = false; 359 } 360 361 mPolicy.userActivity(); 362 } 363 364 private void sendNextBroadcast() { 365 final int powerState; 366 final int goToSleepReason; 367 synchronized (mLock) { 368 if (mBroadcastedPowerState == POWER_STATE_UNKNOWN) { 369 // Broadcasted power state is unknown. Send wake up. 370 mPendingWakeUpBroadcast = false; 371 mBroadcastedPowerState = POWER_STATE_AWAKE; 372 } else if (mBroadcastedPowerState == POWER_STATE_AWAKE) { 373 // Broadcasted power state is awake. Send asleep if needed. 374 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 375 || mActualPowerState == POWER_STATE_ASLEEP) { 376 mPendingGoToSleepBroadcast = false; 377 mBroadcastedPowerState = POWER_STATE_ASLEEP; 378 } else { 379 finishPendingBroadcastLocked(); 380 return; 381 } 382 } else { 383 // Broadcasted power state is asleep. Send awake if needed. 384 if (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast 385 || mActualPowerState == POWER_STATE_AWAKE) { 386 mPendingWakeUpBroadcast = false; 387 mBroadcastedPowerState = POWER_STATE_AWAKE; 388 } else { 389 finishPendingBroadcastLocked(); 390 return; 391 } 392 } 393 394 mBroadcastStartTime = SystemClock.uptimeMillis(); 395 powerState = mBroadcastedPowerState; 396 goToSleepReason = mLastGoToSleepReason; 397 } 398 399 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND, 1); 400 401 if (powerState == POWER_STATE_AWAKE) { 402 sendWakeUpBroadcast(); 403 } else { 404 sendGoToSleepBroadcast(goToSleepReason); 405 } 406 } 407 408 private void sendWakeUpBroadcast() { 409 if (DEBUG) { 410 Slog.d(TAG, "Sending wake up broadcast."); 411 } 412 413 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0); 414 415 mPolicy.screenTurningOn(mScreenOnListener); 416 417 try { 418 ActivityManagerNative.getDefault().wakingUp(); 419 } catch (RemoteException e) { 420 // ignore it 421 } 422 423 if (ActivityManagerNative.isSystemReady()) { 424 mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null, 425 mWakeUpBroadcastDone, mHandler, 0, null, null); 426 } else { 427 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1); 428 sendNextBroadcast(); 429 } 430 } 431 432 private final WindowManagerPolicy.ScreenOnListener mScreenOnListener = 433 new WindowManagerPolicy.ScreenOnListener() { 434 @Override 435 public void onScreenOn() { 436 synchronized (mLock) { 437 if (mScreenOnBlockerAcquired && !mPendingWakeUpBroadcast) { 438 mScreenOnBlockerAcquired = false; 439 mScreenOnBlocker.release(); 440 } 441 } 442 } 443 }; 444 445 private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() { 446 @Override 447 public void onReceive(Context context, Intent intent) { 448 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, 449 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 450 sendNextBroadcast(); 451 } 452 }; 453 454 private void sendGoToSleepBroadcast(int reason) { 455 if (DEBUG) { 456 Slog.d(TAG, "Sending go to sleep broadcast."); 457 } 458 459 int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER; 460 switch (reason) { 461 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: 462 why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN; 463 break; 464 case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: 465 why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT; 466 break; 467 } 468 469 EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0); 470 471 mPolicy.screenTurnedOff(why); 472 try { 473 ActivityManagerNative.getDefault().goingToSleep(); 474 } catch (RemoteException e) { 475 // ignore it. 476 } 477 478 if (ActivityManagerNative.isSystemReady()) { 479 mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null, 480 mGoToSleepBroadcastDone, mHandler, 0, null, null); 481 } else { 482 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1); 483 sendNextBroadcast(); 484 } 485 } 486 487 private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() { 488 @Override 489 public void onReceive(Context context, Intent intent) { 490 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, 491 SystemClock.uptimeMillis() - mBroadcastStartTime, 1); 492 sendNextBroadcast(); 493 } 494 }; 495 496 private void playWirelessChargingStartedSound() { 497 final String soundPath = Settings.Global.getString(mContext.getContentResolver(), 498 Settings.Global.WIRELESS_CHARGING_STARTED_SOUND); 499 if (soundPath != null) { 500 final Uri soundUri = Uri.parse("file://" + soundPath); 501 if (soundUri != null) { 502 final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); 503 if (sfx != null) { 504 sfx.setStreamType(AudioManager.STREAM_SYSTEM); 505 sfx.play(); 506 } 507 } 508 } 509 510 mSuspendBlocker.release(); 511 } 512 513 private final class NotifierHandler extends Handler { 514 public NotifierHandler(Looper looper) { 515 super(looper, null, true /*async*/); 516 } 517 518 @Override 519 public void handleMessage(Message msg) { 520 switch (msg.what) { 521 case MSG_USER_ACTIVITY: 522 sendUserActivity(); 523 break; 524 525 case MSG_BROADCAST: 526 sendNextBroadcast(); 527 break; 528 529 case MSG_WIRELESS_CHARGING_STARTED: 530 playWirelessChargingStartedSound(); 531 break; 532 } 533 } 534 } 535 } 536