From 0abc001275d6cf0af4990f521ccff7346a7cd2bf Mon Sep 17 00:00:00 2001 From: Ruchi Kandoi Date: Tue, 12 Jan 2016 14:39:24 -0800 Subject: [PATCH] PowerManager: Adds the Sustained performance API. Adds a new type of wakelock - SUSTAINED_PERFORMANCE_WAKELOCK. This wakelock can only be acquired when the application is in the foreground. And it is not effective when the application is no longer in the foreground. Acquiring this wakelock enables the Sustained performance mode which guarantees a certain level of performance. Bug: 22864186 Change-Id: Id0ececc756fe014779db6efde7aede23ea181dc5 Signed-off-by: Ruchi Kandoi --- api/current.txt | 1 + api/system-current.txt | 1 + api/test-current.txt | 1 + core/java/android/os/PowerManager.java | 10 +++ .../server/power/PowerManagerService.java | 73 +++++++++++++++++-- 5 files changed, 79 insertions(+), 7 deletions(-) diff --git a/api/current.txt b/api/current.txt index a10c510bd463d..10562d555f2e5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28553,6 +28553,7 @@ package android.os { field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1 field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 + field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100 } public final class PowerManager.WakeLock { diff --git a/api/system-current.txt b/api/system-current.txt index 8e247ade27d8f..77ae1c99f1b99 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -30631,6 +30631,7 @@ package android.os { field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1 field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 + field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100 field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1 field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0 field public static final int USER_ACTIVITY_EVENT_TOUCH = 2; // 0x2 diff --git a/api/test-current.txt b/api/test-current.txt index 25b72c012f16f..1bf294bfb1032 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -28561,6 +28561,7 @@ package android.os { field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1 field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6 + field public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 256; // 0x100 } public final class PowerManager.WakeLock { diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 4159d89d1be1b..314b7d5491ff0 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -218,6 +218,15 @@ public final class PowerManager { */ public static final int DRAW_WAKE_LOCK = 0x00000080; + /** + * Wake lock level: Enables Sustained Performance Mode. + *

+ * This is used by Gaming and VR applications to ensure the device provides + * will provide consistent performance over a large amount of time. + *

+ */ + public static final int SUSTAINED_PERFORMANCE_WAKE_LOCK = 0x00000100; + /** * Mask for the wake lock level component of a combined wake lock level and flags integer. * @@ -525,6 +534,7 @@ public final class PowerManager { case PROXIMITY_SCREEN_OFF_WAKE_LOCK: case DOZE_WAKE_LOCK: case DRAW_WAKE_LOCK: + case SUSTAINED_PERFORMANCE_WAKE_LOCK: break; default: throw new IllegalArgumentException("Must specify a valid wake lock level."); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 290019c73ba46..a1f24f772c3ce 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -131,6 +131,7 @@ public final class PowerManagerService extends SystemService private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake private static final int WAKE_LOCK_DOZE = 1 << 6; private static final int WAKE_LOCK_DRAW = 1 << 7; + private static final int WAKE_LOCK_SUSTAINED_PERFORMANCE = 1 << 8; // Summarizes the user activity state. private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0; @@ -149,6 +150,7 @@ public final class PowerManagerService extends SystemService // Power hints defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_HINT_LOW_POWER = 5; + private static final int POWER_HINT_SUSTAINED_PERFORMANCE = 6; // Power features defined in hardware/libhardware/include/hardware/power.h. private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1; @@ -444,6 +446,9 @@ public final class PowerManagerService extends SystemService // True if we are currently in light device idle mode. private boolean mLightDeviceIdleMode; + // True if we are currently in sustained performance mode. + private boolean mSustainedPerformanceMode; + // Set of app ids that we will always respect the wake locks for. int[] mDeviceIdleWhitelist = new int[0]; @@ -452,6 +457,8 @@ public final class PowerManagerService extends SystemService private final SparseIntArray mUidState = new SparseIntArray(); + private final SparseIntArray mSustainedPerformanceUid = new SparseIntArray(); + // True if theater mode is enabled private boolean mTheaterModeEnabled; @@ -811,6 +818,12 @@ public final class PowerManagerService extends SystemService throw new IllegalArgumentException("Wake lock is already dead."); } mWakeLocks.add(wakeLock); + + if ((flags & PowerManager.WAKE_LOCK_LEVEL_MASK) + == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) { + int numberWakelock = mSustainedPerformanceUid.get(uid); + mSustainedPerformanceUid.put(uid, numberWakelock + 1); + } setWakeLockDisabledStateLocked(wakeLock); notifyAcquire = true; } @@ -879,6 +892,17 @@ public final class PowerManagerService extends SystemService mRequestWaitForNegativeProximity = true; } + + if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) + == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) { + int numberWakelock = mSustainedPerformanceUid.get(wakeLock.mOwnerUid); + if (numberWakelock == 1) { + mSustainedPerformanceUid.delete(wakeLock.mOwnerUid); + } else { + mSustainedPerformanceUid.put(wakeLock.mOwnerUid, numberWakelock - 1); + } + } + wakeLock.mLock.unlinkToDeath(wakeLock, 0); removeWakeLockLocked(wakeLock, index); } @@ -1501,6 +1525,10 @@ public final class PowerManagerService extends SystemService break; case PowerManager.DRAW_WAKE_LOCK: mWakeLockSummary |= WAKE_LOCK_DRAW; + case PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK: + if (!wakeLock.mDisabled) { + mWakeLockSummary |= WAKE_LOCK_SUSTAINED_PERFORMANCE; + } break; } } @@ -2198,6 +2226,14 @@ public final class PowerManagerService extends SystemService if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) { setHalAutoSuspendModeLocked(true); } + + if (mSustainedPerformanceMode + && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) == 0) { + setSustainedPerformanceModeLocked(false); + } else if (!mSustainedPerformanceMode + && (mWakeLockSummary & WAKE_LOCK_SUSTAINED_PERFORMANCE) != 0) { + setSustainedPerformanceModeLocked(true); + } } /** @@ -2296,6 +2332,12 @@ public final class PowerManagerService extends SystemService } } + private void setSustainedPerformanceModeLocked(boolean mode) { + mSustainedPerformanceMode = mode; + powerHintInternal(POWER_HINT_SUSTAINED_PERFORMANCE, + mSustainedPerformanceMode ? 1 : 0); + } + boolean isDeviceIdleModeInternal() { synchronized (mLock) { return mDeviceIdleMode; @@ -2425,7 +2467,7 @@ public final class PowerManagerService extends SystemService void updateUidProcStateInternal(int uid, int procState) { synchronized (mLock) { mUidState.put(uid, procState); - if (mDeviceIdleMode) { + if (mDeviceIdleMode || mSustainedPerformanceUid.get(uid) != 0) { updateWakeLockDisabledStatesLocked(); } } @@ -2446,7 +2488,9 @@ public final class PowerManagerService extends SystemService for (int i = 0; i < numWakeLocks; i++) { final WakeLock wakeLock = mWakeLocks.get(i); if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) - == PowerManager.PARTIAL_WAKE_LOCK) { + == PowerManager.PARTIAL_WAKE_LOCK + || (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) + == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK) { if (setWakeLockDisabledStateLocked(wakeLock)) { changed = true; if (wakeLock.mDisabled) { @@ -2465,9 +2509,9 @@ public final class PowerManagerService extends SystemService } private boolean setWakeLockDisabledStateLocked(WakeLock wakeLock) { + boolean disabled = false; if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) == PowerManager.PARTIAL_WAKE_LOCK) { - boolean disabled = false; if (mDeviceIdleMode) { final int appid = UserHandle.getAppId(wakeLock.mOwnerUid); // If we are in idle mode, we will ignore all partial wake locks that are @@ -2481,10 +2525,16 @@ public final class PowerManagerService extends SystemService disabled = true; } } - if (wakeLock.mDisabled != disabled) { - wakeLock.mDisabled = disabled; - return true; - } + } else if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) + == PowerManager.SUSTAINED_PERFORMANCE_WAKE_LOCK + && mUidState.get(wakeLock.mOwnerUid, + ActivityManager.PROCESS_STATE_CACHED_EMPTY) + > ActivityManager.PROCESS_STATE_TOP) { + disabled = true; + } + if (wakeLock.mDisabled != disabled) { + wakeLock.mDisabled = disabled; + return true; } return false; } @@ -2695,6 +2745,7 @@ public final class PowerManagerService extends SystemService pw.println(" mBatteryLevelLow=" + mBatteryLevelLow); pw.println(" mLightDeviceIdleMode=" + mLightDeviceIdleMode); pw.println(" mDeviceIdleMode=" + mDeviceIdleMode); + pw.println(" mSustainedPerformanceMode=" + mSustainedPerformanceMode); pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime)); @@ -2809,6 +2860,14 @@ public final class PowerManagerService extends SystemService pw.println(); pw.println("Display Power: " + mDisplayPowerCallbacks); + pw.println(); + pw.println("Sustained Performance UIDs:"); + for (int i=0; i