Merge "Delay appop revocation when only capability is lost" into udc-dev am: af2f33e70a am: ae2aa39776
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/30757630
Change-Id: Iad3258aed56c10530427912a9a6982fb389561de
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index 23a384f..2dbe282 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -231,20 +231,20 @@
mPendingUidStates.put(uid, uidState);
mPendingCapability.put(uid, capability);
+ boolean hasLostCapability = (prevCapability & ~capability) != 0;
+
if (procState == PROCESS_STATE_NONEXISTENT) {
mPendingGone.put(uid, true);
commitUidPendingState(uid);
- } else if (uidState < prevUidState
- || (uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED
- && prevUidState > UID_STATE_MAX_LAST_NON_RESTRICTED)) {
+ } else if (uidState < prevUidState) {
// We are moving to a more important state, or the new state may be in the
// foreground and the old state is in the background, then always do it
// immediately.
commitUidPendingState(uid);
- } else if (uidState == prevUidState && capability != prevCapability) {
- // No change on process state, but process capability has changed.
+ } else if (uidState == prevUidState && !hasLostCapability) {
+ // No change on process state, but process capability has increased.
commitUidPendingState(uid);
- } else if (uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED) {
+ } else if (uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED && !hasLostCapability) {
// We are moving to a less important state, but it doesn't cross the restriction
// threshold.
commitUidPendingState(uid);
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java
index 1731590..4e11b72 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java
@@ -325,6 +325,10 @@
.backgroundState()
.update();
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_IGNORED,
+ mIntf.evalMode(UID, OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.microphoneCapability()
@@ -342,10 +346,21 @@
.microphoneCapability()
.update();
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED,
+ mIntf.evalMode(UID, OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.update();
+ mClock.advanceTime(mConstants.BG_STATE_SETTLE_TIME - 1);
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED,
+ mIntf.evalMode(UID, OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
+ MODE_FOREGROUND));
+
+ mClock.advanceTime(1);
assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
assertEquals(MODE_IGNORED,
mIntf.evalMode(UID, OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, MODE_FOREGROUND));
@@ -357,6 +372,8 @@
.backgroundState()
.update();
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.cameraCapability()
@@ -372,10 +389,16 @@
.cameraCapability()
.update();
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.update();
+ mClock.advanceTime(mConstants.BG_STATE_SETTLE_TIME - 1);
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+
+ mClock.advanceTime(1);
assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
}
@@ -385,6 +408,9 @@
.backgroundState()
.update();
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.locationCapability()
@@ -401,15 +427,51 @@
.locationCapability()
.update();
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+
procStateBuilder(UID)
.backgroundState()
.update();
+ mClock.advanceTime(mConstants.BG_STATE_SETTLE_TIME - 1);
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
+
+ mClock.advanceTime(1);
assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND));
}
@Test
+ public void testProcStateChangesAndStaysUnrestrictedAndCapabilityRemoved() {
+ procStateBuilder(UID)
+ .topState()
+ .microphoneCapability()
+ .cameraCapability()
+ .locationCapability()
+ .update();
+
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+
+ procStateBuilder(UID)
+ .foregroundState()
+ .update();
+
+ mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME - 1);
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+ assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+
+ mClock.advanceTime(1);
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND));
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_CAMERA, MODE_FOREGROUND));
+ assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_COARSE_LOCATION, MODE_FOREGROUND));
+ }
+
+ @Test
public void testVisibleAppWidget() {
procStateBuilder(UID)
.backgroundState()