summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/AppOpsManager.java14
-rw-r--r--core/java/android/provider/Settings.java4
-rw-r--r--services/core/java/com/android/server/AppOpsService.java65
3 files changed, 63 insertions, 20 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 21a3c0721371..fcab8c10db9e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -156,6 +156,12 @@ public class AppOpsManager {
public static final int UID_STATE_FOREGROUND_SERVICE = 2;
/**
+ * Last UID state in which we don't restrict what an op can do.
+ * @hide
+ */
+ public static final int UID_STATE_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
+
+ /**
* Metrics about an op when its uid is in the foreground for any other reasons.
* @hide
*/
@@ -1594,11 +1600,11 @@ public class AppOpsManager {
}
public long getLastAccessForegroundTime() {
- return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_FOREGROUND_SERVICE + 1);
+ return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
}
public long getLastAccessBackgroundTime() {
- return maxTime(mTimes, UID_STATE_FOREGROUND_SERVICE + 1, _NUM_UID_STATE);
+ return maxTime(mTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
}
public long getLastTimeFor(int uidState) {
@@ -1614,11 +1620,11 @@ public class AppOpsManager {
}
public long getLastRejectForegroundTime() {
- return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_FOREGROUND_SERVICE + 1);
+ return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
}
public long getLastRejectBackgroundTime() {
- return maxTime(mRejectTimes, UID_STATE_FOREGROUND_SERVICE + 1, _NUM_UID_STATE);
+ return maxTime(mRejectTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
}
public long getLastRejectTimeFor(int uidState) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 37204d7e8147..2c39094e5599 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10455,7 +10455,9 @@ public final class Settings {
* The following keys are supported:
*
* <pre>
- * state_settle_time (long)
+ * top_state_settle_time (long)
+ * fg_service_state_settle_time (long)
+ * bg_state_settle_time (long)
* </pre>
*
* <p>
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 4c914c205815..61b1dcc3177c 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.Iterator;
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 @@ public class AppOpsService extends IAppOpsService.Stub {
*/
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 @@ public class AppOpsService extends IAppOpsService.Stub {
// 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 @@ public class AppOpsService extends IAppOpsService.Stub {
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 @@ public class AppOpsService extends IAppOpsService.Stub {
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 @@ public class AppOpsService extends IAppOpsService.Stub {
}
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;