diff options
Diffstat (limited to 'services')
6 files changed, 147 insertions, 72 deletions
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index bda0183..9de3efe 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -426,8 +426,10 @@ class AlarmManagerService extends SystemService { final Pair<String, ComponentName> mTarget; final BroadcastStats mBroadcastStats; final FilterStats mFilterStats; + final int mAlarmType; - InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) { + InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource, + int alarmType) { mPendingIntent = pendingIntent; mWorkSource = workSource; Intent intent = pendingIntent.getIntent(); @@ -441,6 +443,7 @@ class AlarmManagerService extends SystemService { mBroadcastStats.filterStats.put(mTarget, fs); } mFilterStats = fs; + mAlarmType = alarmType; } } @@ -1280,17 +1283,12 @@ class AlarmManagerService extends SystemService { // we have an active broadcast so stay awake. if (mBroadcastRefCount == 0) { - setWakelockWorkSource(alarm.operation, alarm.workSource); - mWakeLock.setUnimportantForLogging( - alarm.operation == mTimeTickSender); - mWakeLock.setHistoryTag(alarm.operation.getTag( - alarm.type == ELAPSED_REALTIME_WAKEUP - || alarm.type == RTC_WAKEUP - ? "*walarm*:" : "*alarm*:")); + setWakelockWorkSource(alarm.operation, alarm.workSource, + alarm.type, true); mWakeLock.acquire(); } final InFlight inflight = new InFlight(AlarmManagerService.this, - alarm.operation, alarm.workSource); + alarm.operation, alarm.workSource, alarm.type); mInFlight.add(inflight); mBroadcastRefCount++; @@ -1345,9 +1343,17 @@ class AlarmManagerService extends SystemService { * @param pi PendingIntent to attribute blame to if ws is null. * @param ws WorkSource to attribute blame. */ - void setWakelockWorkSource(PendingIntent pi, WorkSource ws) { + void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) { try { + mWakeLock.setUnimportantForLogging(pi == mTimeTickSender); if (ws != null) { + if (first) { + mWakeLock.setHistoryTag(pi.getTag( + type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP + ? "*walarm*:" : "*alarm*:")); + } else { + mWakeLock.setHistoryTag(null); + } mWakeLock.setWorkSource(ws); return; } @@ -1355,6 +1361,7 @@ class AlarmManagerService extends SystemService { final int uid = ActivityManagerNative.getDefault() .getUidForIntentSender(pi.getTarget()); if (uid >= 0) { + mWakeLock.setHistoryTag(null); mWakeLock.setWorkSource(new WorkSource(uid)); return; } @@ -1579,7 +1586,8 @@ class AlarmManagerService extends SystemService { // the next of our alarms is now in flight. reattribute the wakelock. if (mInFlight.size() > 0) { InFlight inFlight = mInFlight.get(0); - setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource); + setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource, + inFlight.mAlarmType, false); } else { // should never happen mLog.w("Alarm wakelock still held but sent queue empty"); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 39bfc23..3414daf 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -29,6 +29,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Process; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.UserHandle; import android.os.WorkSource; import android.telephony.SignalStrength; @@ -133,14 +134,15 @@ public final class BatteryStatsService extends IBatteryStats.Stub { boolean unimportantForLogging) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging); + mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging, + SystemClock.elapsedRealtime()); } } public void noteStopWakelock(int uid, int pid, String name, int type) { enforceCallingPermission(); synchronized (mStats) { - mStats.noteStopWakeLocked(uid, pid, name, type); + mStats.noteStopWakeLocked(uid, pid, name, type, SystemClock.elapsedRealtime()); } } @@ -153,6 +155,16 @@ public final class BatteryStatsService extends IBatteryStats.Stub { } } + public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, int type, + WorkSource newWs, int newPid, String newName, + String newHistoryName, int newType, boolean newUnimportantForLogging) { + enforceCallingPermission(); + synchronized (mStats) { + mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, type, + newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging); + } + } + public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, int type) { enforceCallingPermission(); synchronized (mStats) { diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java index 12d51aa..6d3702a 100644 --- a/services/core/java/com/android/server/power/DisplayPowerController.java +++ b/services/core/java/com/android/server/power/DisplayPowerController.java @@ -479,7 +479,6 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call && mProximity == PROXIMITY_POSITIVE) { mScreenOffBecauseOfProximity = true; sendOnProximityPositiveWithWakelock(); - setScreenOn(false); } } else if (mWaitingForNegativeProximity && mScreenOffBecauseOfProximity @@ -544,59 +543,62 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mUsingScreenAutoBrightness = false; } - // Animate the screen on or off. - if (!mScreenOffBecauseOfProximity) { - if (mPowerRequest.wantScreenOnAny()) { - // Want screen on. - // Wait for previous off animation to complete beforehand. - // It is relatively short but if we cancel it and switch to the - // on animation immediately then the results are pretty ugly. - if (!mElectronBeamOffAnimator.isStarted()) { - // Turn the screen on. The contents of the screen may not yet - // be visible if the electron beam has not been dismissed because - // its last frame of animation is solid black. - setScreenOn(true); - - if (mPowerRequest.blockScreenOn - && mPowerState.getElectronBeamLevel() == 0.0f) { - blockScreenOn(); - } else { - unblockScreenOn(); - if (USE_ELECTRON_BEAM_ON_ANIMATION) { - if (!mElectronBeamOnAnimator.isStarted()) { - if (mPowerState.getElectronBeamLevel() == 1.0f) { - mPowerState.dismissElectronBeam(); - } else if (mPowerState.prepareElectronBeam( - mElectronBeamFadesConfig ? - ElectronBeam.MODE_FADE : - ElectronBeam.MODE_WARM_UP)) { - mElectronBeamOnAnimator.start(); - } else { - mElectronBeamOnAnimator.end(); - } + // Animate the screen on or off unless blocked. + if (mScreenOffBecauseOfProximity) { + // Screen off due to proximity. + setScreenOn(false); + unblockScreenOn(); + } else if (mPowerRequest.wantScreenOnAny()) { + // Want screen on. + // Wait for previous off animation to complete beforehand. + // It is relatively short but if we cancel it and switch to the + // on animation immediately then the results are pretty ugly. + if (!mElectronBeamOffAnimator.isStarted()) { + // Turn the screen on. The contents of the screen may not yet + // be visible if the electron beam has not been dismissed because + // its last frame of animation is solid black. + setScreenOn(true); + + if (mPowerRequest.blockScreenOn + && mPowerState.getElectronBeamLevel() == 0.0f) { + blockScreenOn(); + } else { + unblockScreenOn(); + if (USE_ELECTRON_BEAM_ON_ANIMATION) { + if (!mElectronBeamOnAnimator.isStarted()) { + if (mPowerState.getElectronBeamLevel() == 1.0f) { + mPowerState.dismissElectronBeam(); + } else if (mPowerState.prepareElectronBeam( + mElectronBeamFadesConfig ? + ElectronBeam.MODE_FADE : + ElectronBeam.MODE_WARM_UP)) { + mElectronBeamOnAnimator.start(); + } else { + mElectronBeamOnAnimator.end(); } - } else { - mPowerState.setElectronBeamLevel(1.0f); - mPowerState.dismissElectronBeam(); } + } else { + mPowerState.setElectronBeamLevel(1.0f); + mPowerState.dismissElectronBeam(); } } - } else { - // Want screen off. - // Wait for previous on animation to complete beforehand. - if (!mElectronBeamOnAnimator.isStarted()) { - if (!mElectronBeamOffAnimator.isStarted()) { - if (mPowerState.getElectronBeamLevel() == 0.0f) { - setScreenOn(false); - } else if (mPowerState.prepareElectronBeam( - mElectronBeamFadesConfig ? - ElectronBeam.MODE_FADE : - ElectronBeam.MODE_COOL_DOWN) - && mPowerState.isScreenOn()) { - mElectronBeamOffAnimator.start(); - } else { - mElectronBeamOffAnimator.end(); - } + } + } else { + // Want screen off. + // Wait for previous on animation to complete beforehand. + unblockScreenOn(); + if (!mElectronBeamOnAnimator.isStarted()) { + if (!mElectronBeamOffAnimator.isStarted()) { + if (mPowerState.getElectronBeamLevel() == 0.0f) { + setScreenOn(false); + } else if (mPowerState.prepareElectronBeam( + mElectronBeamFadesConfig ? + ElectronBeam.MODE_FADE : + ElectronBeam.MODE_COOL_DOWN) + && mPowerState.isScreenOn()) { + mElectronBeamOffAnimator.start(); + } else { + mElectronBeamOffAnimator.end(); } } } @@ -641,15 +643,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void unblockScreenOn() { if (mScreenOnWasBlocked) { mScreenOnWasBlocked = false; - if (DEBUG) { - Slog.d(TAG, "Unblocked screen on after " + - (SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms"); + long delay = SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime; + if (delay > 1000 || DEBUG) { + Slog.d(TAG, "Unblocked screen on after " + delay + " ms"); } } } private void setScreenOn(boolean on) { - if (!mPowerState.isScreenOn() == on) { + if (mPowerState.isScreenOn() != on) { mPowerState.setScreenOn(on); if (on) { mNotifier.onScreenOn(); diff --git a/services/core/java/com/android/server/power/DisplayPowerState.java b/services/core/java/com/android/server/power/DisplayPowerState.java index 42af4b4..8e331ad 100644 --- a/services/core/java/com/android/server/power/DisplayPowerState.java +++ b/services/core/java/com/android/server/power/DisplayPowerState.java @@ -304,8 +304,15 @@ final class DisplayPowerState { int brightness = mScreenOn && mElectronBeamLevel > 0f ? mScreenBrightness : 0; if (mPhotonicModulator.setState(mScreenOn, brightness)) { + if (DEBUG) { + Slog.d(TAG, "Screen ready"); + } mScreenReady = true; invokeCleanListenerIfNeeded(); + } else { + if (DEBUG) { + Slog.d(TAG, "Screen not ready"); + } } } }; @@ -355,7 +362,7 @@ final class DisplayPowerState { AsyncTask.THREAD_POOL_EXECUTOR.execute(mTask); } } - return mChangeInProgress; + return !mChangeInProgress; } } diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index e1ccf46..df06bae 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -158,6 +158,39 @@ final class Notifier { } /** + * Called when a wake lock is changing. + */ + public void onWakeLockChanging(int flags, String tag, String packageName, + int ownerUid, int ownerPid, WorkSource workSource, String historyTag, + int newFlags, String newTag, String newPackageName, int newOwnerUid, + int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) { + + final int monitorType = getBatteryStatsWakeLockMonitorType(flags); + final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags); + boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0 + && ownerUid == Process.SYSTEM_UID; + if (workSource != null && newWorkSource != null) { + if (DEBUG) { + Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag + + "\", packageName=" + newPackageName + + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid + + ", workSource=" + newWorkSource); + } + try { + mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, monitorType, + newWorkSource, newOwnerPid, newTag, newHistoryTag, + newMonitorType, unimportantForLogging); + } catch (RemoteException ex) { + // Ignore + } + } else { + onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource); + onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid, + newWorkSource, newHistoryTag); + } + } + + /** * Called when a wake lock is released. */ public void onWakeLockReleased(int flags, String tag, String packageName, diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index e7bbf1c..e0a46b9 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -646,9 +646,9 @@ public final class PowerManagerService extends com.android.server.SystemService wakeLock = mWakeLocks.get(index); if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) { // Update existing wake lock. This shouldn't happen but is harmless. - notifyWakeLockReleasedLocked(wakeLock); + notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName, + uid, pid, ws, historyTag); wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid); - notifyWakeLockAcquiredLocked(wakeLock); } } else { wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid); @@ -765,9 +765,10 @@ public final class PowerManagerService extends com.android.server.SystemService } if (!wakeLock.hasSameWorkSource(ws)) { - notifyWakeLockReleasedLocked(wakeLock); + notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag, + wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid, + ws, wakeLock.mHistoryTag); wakeLock.updateWorkSource(ws); - notifyWakeLockAcquiredLocked(wakeLock); } } } @@ -791,6 +792,15 @@ public final class PowerManagerService extends com.android.server.SystemService } } + private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag, + String packageName, int uid, int pid, WorkSource ws, String historyTag) { + if (mSystemReady && wakeLock.mNotifiedAcquired) { + mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName, + wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource, + wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag); + } + } + private void notifyWakeLockReleasedLocked(WakeLock wakeLock) { if (mSystemReady && wakeLock.mNotifiedAcquired) { wakeLock.mNotifiedAcquired = false; @@ -1037,6 +1047,9 @@ public final class PowerManagerService extends com.android.server.SystemService if (!mSystemReady || mDirty == 0) { return; } + if (!Thread.holdsLock(mLock)) { + Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked"); + } // Phase 0: Basic state updates. updateIsPoweredLocked(mDirty); |