More app ops fg/bg tuning
- Only report that something has changed when a uid changes between
the restricted and unrestricted states. (Adds new constant that
defines this important division point.)
- Have different settle times for different key transitions: (a)
out of the top state, (b) out of any other unrestricted state,
(c) down to a lower background state.
- But, don't apply any settle time when transitioning from top to
another unrestricted state... there is no need to.
Bug: 78480444
Test: manual
Change-Id: Ife772858009a6da5c286e285a4059aea3ad3f6c7
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 4c914c2..61b1dcc 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -95,11 +95,12 @@
import java.util.List;
import java.util.Map;
+import static android.app.AppOpsManager._NUM_UID_STATE;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager._NUM_UID_STATE;
+import static android.app.AppOpsManager.UID_STATE_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
@@ -213,15 +214,31 @@
*/
private final class Constants extends ContentObserver {
// Key names stored in the settings value.
- private static final String KEY_STATE_SETTLE_TIME = "state_settle_time";
+ private static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
+ private static final String KEY_FG_SERVICE_STATE_SETTLE_TIME
+ = "fg_service_state_settle_time";
+ private static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time";
/**
- * How long we want for a drop in uid state to settle before applying it.
+ * How long we want for a drop in uid state from top to settle before applying it.
* @see Settings.Global#APP_OPS_CONSTANTS
- * @see #KEY_STATE_SETTLE_TIME
+ * @see #KEY_TOP_STATE_SETTLE_TIME
*/
- public long STATE_SETTLE_TIME;
+ public long TOP_STATE_SETTLE_TIME;
+ /**
+ * How long we want for a drop in uid state from foreground to settle before applying it.
+ * @see Settings.Global#APP_OPS_CONSTANTS
+ * @see #KEY_FG_SERVICE_STATE_SETTLE_TIME
+ */
+ public long FG_SERVICE_STATE_SETTLE_TIME;
+
+ /**
+ * How long we want for a drop in uid state from background to settle before applying it.
+ * @see Settings.Global#APP_OPS_CONSTANTS
+ * @see #KEY_BG_STATE_SETTLE_TIME
+ */
+ public long BG_STATE_SETTLE_TIME;
private final KeyValueListParser mParser = new KeyValueListParser(',');
private ContentResolver mResolver;
@@ -256,16 +273,24 @@
// with defaults.
Slog.e(TAG, "Bad app ops settings", e);
}
- STATE_SETTLE_TIME = mParser.getDurationMillis(
- KEY_STATE_SETTLE_TIME, 10 * 1000L);
+ TOP_STATE_SETTLE_TIME = mParser.getDurationMillis(
+ KEY_TOP_STATE_SETTLE_TIME, 30 * 1000L);
+ FG_SERVICE_STATE_SETTLE_TIME = mParser.getDurationMillis(
+ KEY_FG_SERVICE_STATE_SETTLE_TIME, 10 * 1000L);
+ BG_STATE_SETTLE_TIME = mParser.getDurationMillis(
+ KEY_BG_STATE_SETTLE_TIME, 1 * 1000L);
}
}
void dump(PrintWriter pw) {
pw.println(" Settings:");
- pw.print(" "); pw.print(KEY_STATE_SETTLE_TIME); pw.print("=");
- TimeUtils.formatDuration(STATE_SETTLE_TIME, pw);
+ pw.print(" "); pw.print(KEY_TOP_STATE_SETTLE_TIME); pw.print("=");
+ TimeUtils.formatDuration(TOP_STATE_SETTLE_TIME, pw);
+ pw.print(" "); pw.print(KEY_FG_SERVICE_STATE_SETTLE_TIME); pw.print("=");
+ TimeUtils.formatDuration(FG_SERVICE_STATE_SETTLE_TIME, pw);
+ pw.print(" "); pw.print(KEY_BG_STATE_SETTLE_TIME); pw.print("=");
+ TimeUtils.formatDuration(BG_STATE_SETTLE_TIME, pw);
pw.println();
}
}
@@ -304,7 +329,7 @@
int evalMode(int mode) {
if (mode == AppOpsManager.MODE_FOREGROUND) {
- return state <= UID_STATE_FOREGROUND_SERVICE
+ return state <= UID_STATE_LAST_NON_RESTRICTED
? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
}
return mode;
@@ -728,14 +753,22 @@
if (uidState != null && uidState.pendingState != newState) {
final int oldPendingState = uidState.pendingState;
uidState.pendingState = newState;
- if (newState < uidState.state) {
- // We are moving to a more important state, always do it immediately.
+ if (newState < uidState.state || newState <= UID_STATE_LAST_NON_RESTRICTED) {
+ // We are moving to a more important state, or the new state is in the
+ // foreground, then always do it immediately.
commitUidPendingStateLocked(uidState);
} else if (uidState.pendingStateCommitTime == 0) {
// We are moving to a less important state for the first time,
// delay the application for a bit.
- uidState.pendingStateCommitTime = SystemClock.uptimeMillis() +
- mConstants.STATE_SETTLE_TIME;
+ final long settleTime;
+ if (uidState.state <= UID_STATE_TOP) {
+ settleTime = mConstants.TOP_STATE_SETTLE_TIME;
+ } else if (uidState.state <= UID_STATE_FOREGROUND_SERVICE) {
+ settleTime = mConstants.FG_SERVICE_STATE_SETTLE_TIME;
+ } else {
+ settleTime = mConstants.BG_STATE_SETTLE_TIME;
+ }
+ uidState.pendingStateCommitTime = SystemClock.uptimeMillis() + settleTime;
}
if (uidState.startNesting != 0) {
// There is some actively running operation... need to find it
@@ -1858,9 +1891,11 @@
}
private void commitUidPendingStateLocked(UidState uidState) {
+ final boolean lastForeground = uidState.state <= UID_STATE_LAST_NON_RESTRICTED;
+ final boolean nowForeground = uidState.pendingState <= UID_STATE_LAST_NON_RESTRICTED;
uidState.state = uidState.pendingState;
uidState.pendingStateCommitTime = 0;
- if (uidState.hasForegroundWatchers) {
+ if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
if (!uidState.foregroundOps.valueAt(fgi)) {
continue;