Merge "PowerManager: Adds the Sustained performance API."
diff --git a/api/current.txt b/api/current.txt
index a10c510..10562d5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28553,6 +28553,7 @@
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 de5d8c9..dc081bf 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -30633,6 +30633,7 @@
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 25b72c0..1bf294b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -28561,6 +28561,7 @@
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 4159d89..314b7d5 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -219,6 +219,15 @@
public static final int DRAW_WAKE_LOCK = 0x00000080;
/**
+ * Wake lock level: Enables Sustained Performance Mode.
+ * <p>
+ * This is used by Gaming and VR applications to ensure the device provides
+ * will provide consistent performance over a large amount of time.
+ * </p>
+ */
+ 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.
*
* @hide
@@ -525,6 +534,7 @@
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 290019c..a1f24f7 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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+ 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
pw.println();
pw.println("Display Power: " + mDisplayPowerCallbacks);
+ pw.println();
+ pw.println("Sustained Performance UIDs:");
+ for (int i=0; i<mSustainedPerformanceUid.size(); i++) {
+ pw.print(" UID "); UserHandle.formatUid(pw, mSustainedPerformanceUid.keyAt(i));
+ pw.print(": "); pw.println(mSustainedPerformanceUid.valueAt(i));
+ }
+
+
wcd = mWirelessChargerDetector;
}