Loading services/core/java/com/android/server/appop/AppOpsService.java +37 −33 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ import static android.app.AppOpsManager.SAMPLING_STRATEGY_RARELY_USED; import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM; import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM_OPS; import static android.app.AppOpsManager.SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE; import static android.app.AppOpsManager.UID_STATE_NONEXISTENT; import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager._NUM_OP; import static android.app.AppOpsManager.extractFlagsFromKey; Loading Loading @@ -464,7 +463,19 @@ public class AppOpsService extends IAppOpsService.Stub { Clock.SYSTEM_CLOCK, mConstants); mUidStateTracker.addUidStateChangedCallback(new HandlerExecutor(mHandler), this::onUidStateChanged); new AppOpsUidStateTracker.UidStateChangedCallback() { @Override public void onUidStateChanged(int uid, int uidState, boolean foregroundModeMayChange) { AppOpsService.this .onUidStateChanged(uid, uidState, foregroundModeMayChange); } @Override public void onUidProcessDeath(int uid) { AppOpsService.this.onUidProcessDeath(uid); } }); } return mUidStateTracker; } Loading Loading @@ -1500,9 +1511,6 @@ public class AppOpsService extends IAppOpsService.Stub { // The callback method from AppOpsUidStateTracker private void onUidStateChanged(int uid, int state, boolean foregroundModeMayChange) { synchronized (this) { if (state == UID_STATE_NONEXISTENT) { onUidProcessDeathLocked(uid); } UidState uidState = getUidStateLocked(uid, false); boolean hasForegroundWatchers = false; Loading Loading @@ -1590,11 +1598,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } if (state == UID_STATE_NONEXISTENT) { // For UID_STATE_NONEXISTENT, we don't call onUidStateChanged for AttributedOps return; } if (uidState != null) { int numPkgs = uidState.pkgOps.size(); for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { Loading @@ -1619,8 +1622,8 @@ public class AppOpsService extends IAppOpsService.Stub { } } @GuardedBy("this") private void onUidProcessDeathLocked(int uid) { private void onUidProcessDeath(int uid) { synchronized (this) { if (!mUidStates.contains(uid) || !Flags.finishRunningOpsForKilledPackages()) { return; } Loading @@ -1645,6 +1648,7 @@ public class AppOpsService extends IAppOpsService.Stub { }); finishChainsLocked(chainsToFinish); } } @GuardedBy("this") private void finishChainsLocked(SparseLongArray chainsToFinish) { Loading services/core/java/com/android/server/appop/AppOpsUidStateTracker.java +13 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.appop; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_TOP; Loading @@ -27,8 +28,10 @@ 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.UID_STATE_NONEXISTENT; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.permission.flags.Flags.finishRunningOpsForKilledPackages; import android.annotation.CallbackExecutor; import android.util.SparseArray; Loading Loading @@ -68,6 +71,14 @@ interface AppOpsUidStateTracker { return UID_STATE_BACKGROUND; } if (finishRunningOpsForKilledPackages()) { if (procState < PROCESS_STATE_NONEXISTENT) { return UID_STATE_CACHED; } return UID_STATE_NONEXISTENT; } // UID_STATE_NONEXISTENT is deliberately excluded here return UID_STATE_CACHED; } Loading Loading @@ -119,6 +130,8 @@ interface AppOpsUidStateTracker { * evaluated result may have changed. */ void onUidStateChanged(int uid, int uidState, boolean foregroundModeMayChange); void onUidProcessDeath(int uid); } void dumpUidState(PrintWriter pw, int uid, long nowElapsed); Loading services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +20 −17 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.ProcessCapability; import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE; import static android.app.AppOpsManager.MODE_ALLOWED; Loading @@ -32,6 +31,7 @@ import static android.app.AppOpsManager.OP_CONTROL_AUDIO; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.UID_STATE_CACHED; import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_NONEXISTENT; Loading Loading @@ -75,7 +75,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private SparseBooleanArray mAppWidgetVisible = new SparseBooleanArray(); private SparseBooleanArray mPendingAppWidgetVisible = new SparseBooleanArray(); private SparseLongArray mPendingCommitTime = new SparseLongArray(); private SparseBooleanArray mPendingGone = new SparseBooleanArray(); private ArrayMap<UidStateChangedCallback, Executor> mUidStateChangedCallbacks = new ArrayMap<>(); Loading Loading @@ -221,11 +220,12 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { public void updateUidProcState(int uid, int procState, int capability) { int uidState = processStateToUidState(procState); int prevUidState = mUidStates.get(uid, AppOpsManager.MIN_PRIORITY_UID_STATE); int prevUidState = mUidStates.get(uid, AppOpsManager.UID_STATE_NONEXISTENT); int prevCapability = mCapability.get(uid, PROCESS_CAPABILITY_NONE); int pendingUidState = mPendingUidStates.get(uid, MIN_PRIORITY_UID_STATE); int pendingUidState = mPendingUidStates.get(uid, UID_STATE_NONEXISTENT); int pendingCapability = mPendingCapability.get(uid, PROCESS_CAPABILITY_NONE); long pendingStateCommitTime = mPendingCommitTime.get(uid, 0); if ((pendingStateCommitTime == 0 && (uidState != prevUidState || capability != prevCapability)) || (pendingStateCommitTime != 0 Loading @@ -239,8 +239,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { boolean hasLostCapability = (prevCapability & ~capability) != 0; if (procState == PROCESS_STATE_NONEXISTENT) { mPendingGone.put(uid, true); if (uidState == UID_STATE_NONEXISTENT) { commitUidPendingState(uid); } else if (uidState < prevUidState) { // We are moving to a more important state, or the new state may be in the Loading Loading @@ -342,7 +341,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private void commitUidPendingState(int uid) { int uidState = mUidStates.get(uid, MIN_PRIORITY_UID_STATE); int uidState = mUidStates.get(uid, UID_STATE_NONEXISTENT); int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE); boolean appWidgetVisible = mAppWidgetVisible.get(uid, false); Loading @@ -350,18 +349,23 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { int pendingCapability = mPendingCapability.get(uid, capability); boolean pendingAppWidgetVisible = mPendingAppWidgetVisible.get(uid, appWidgetVisible); boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED // UID_STATE_NONEXISTENT is a state that isn't used outside of this class, nonexistent // processes have always been represented as CACHED int externalUidState = Math.min(uidState, UID_STATE_CACHED); int externalPendingUidState = Math.min(pendingUidState, UID_STATE_CACHED); boolean foregroundChange = externalUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != externalPendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED || capability != pendingCapability || appWidgetVisible != pendingAppWidgetVisible; if (uidState != pendingUidState if (externalUidState != externalPendingUidState || capability != pendingCapability || appWidgetVisible != pendingAppWidgetVisible) { if (foregroundChange) { // To save on memory usage, log only interesting changes. mEventLog.logCommitUidState(uid, pendingUidState, pendingCapability, mEventLog.logCommitUidState(uid, externalPendingUidState, pendingCapability, pendingAppWidgetVisible, appWidgetVisible != pendingAppWidgetVisible); } Loading @@ -370,24 +374,23 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { Executor executor = mUidStateChangedCallbacks.valueAt(i); executor.execute(PooledLambda.obtainRunnable( UidStateChangedCallback::onUidStateChanged, cb, uid, pendingUidState, foregroundChange)); UidStateChangedCallback::onUidStateChanged, cb, uid, externalPendingUidState, foregroundChange)); } } if (mPendingGone.get(uid, false)) { if (pendingUidState == UID_STATE_NONEXISTENT && uidState != pendingUidState) { mUidStates.delete(uid); mCapability.delete(uid); mAppWidgetVisible.delete(uid); mPendingGone.delete(uid); if (finishRunningOpsForKilledPackages()) { for (int i = 0; i < mUidStateChangedCallbacks.size(); i++) { UidStateChangedCallback cb = mUidStateChangedCallbacks.keyAt(i); Executor executor = mUidStateChangedCallbacks.valueAt(i); // If foregroundness changed it should be handled in earlier callback invocation executor.execute(PooledLambda.obtainRunnable( UidStateChangedCallback::onUidStateChanged, cb, uid, UID_STATE_NONEXISTENT, foregroundChange)); UidStateChangedCallback::onUidProcessDeath, cb, uid)); } } } else { Loading services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java +0 −247 Original line number Diff line number Diff line Loading @@ -26,15 +26,12 @@ import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUD import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.OP_WIFI_SCAN; 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.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.permission.flags.Flags.delayUidStateChangesFromCapabilityUpdates; import static com.android.server.appop.AppOpsUidStateTracker.processStateToUidState; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -42,7 +39,6 @@ import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading @@ -64,7 +60,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.quality.Strictness; import java.util.PriorityQueue; Loading Loading @@ -94,7 +89,6 @@ public class AppOpsUidStateTrackerTest { public void setUp() { mSession = ExtendedMockito.mockitoSession() .initMocks(this) .strictness(Strictness.LENIENT) .startMocking(); mConstants.TOP_STATE_SETTLE_TIME = 10 * 1000L; mConstants.FG_SERVICE_STATE_SETTLE_TIME = 5 * 1000L; Loading Loading @@ -590,221 +584,6 @@ public class AppOpsUidStateTrackerTest { verify(cb, times(0)).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackCachedToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackCachedToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackCachedToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackCachedToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackBackgroundToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackBackgroundToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackBackgroundToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackBackgroundToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackForegroundToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackForegroundToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackForegroundToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackForegroundToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackForegroundServiceToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackForegroundServiceToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackForegroundServiceToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackForegroundServiceToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackTopToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackTopToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackTopToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackTopToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackCachedToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .cachedState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, never()).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackBackgroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(false)); } @Test public void testUidStateChangedCallbackForegroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedCallbackForegroundServiceToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundServiceState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedCallbackTopToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .topState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedBackgroundThenForegroundImmediately() { procStateBuilder(UID) Loading Loading @@ -882,32 +661,6 @@ public class AppOpsUidStateTrackerTest { assertEquals(UID_STATE_TOP, mIntf.getUidState(UID)); } public void testUidStateChangedCallback(int initialState, int finalState) { int initialUidState = processStateToUidState(initialState); int finalUidState = processStateToUidState(finalState); boolean foregroundChange = initialUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != finalUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED; boolean finalUidStateIsBackgroundAndLessImportant = finalUidState > UID_STATE_MAX_LAST_NON_RESTRICTED && finalUidState > initialUidState; UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .setState(initialState) .update(); procStateBuilder(UID) .setState(finalState) .update(); if (finalUidStateIsBackgroundAndLessImportant) { mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1); } verify(cb, atLeastOnce()) .onUidStateChanged(eq(UID), eq(finalUidState), eq(foregroundChange)); } private UidStateChangedCallback addUidStateChangeCallback() { UidStateChangedCallback cb = Loading services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTransitionCallbackTest.java 0 → 100644 +260 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/appop/AppOpsService.java +37 −33 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ import static android.app.AppOpsManager.SAMPLING_STRATEGY_RARELY_USED; import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM; import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM_OPS; import static android.app.AppOpsManager.SECURITY_EXCEPTION_ON_INVALID_ATTRIBUTION_TAG_CHANGE; import static android.app.AppOpsManager.UID_STATE_NONEXISTENT; import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager._NUM_OP; import static android.app.AppOpsManager.extractFlagsFromKey; Loading Loading @@ -464,7 +463,19 @@ public class AppOpsService extends IAppOpsService.Stub { Clock.SYSTEM_CLOCK, mConstants); mUidStateTracker.addUidStateChangedCallback(new HandlerExecutor(mHandler), this::onUidStateChanged); new AppOpsUidStateTracker.UidStateChangedCallback() { @Override public void onUidStateChanged(int uid, int uidState, boolean foregroundModeMayChange) { AppOpsService.this .onUidStateChanged(uid, uidState, foregroundModeMayChange); } @Override public void onUidProcessDeath(int uid) { AppOpsService.this.onUidProcessDeath(uid); } }); } return mUidStateTracker; } Loading Loading @@ -1500,9 +1511,6 @@ public class AppOpsService extends IAppOpsService.Stub { // The callback method from AppOpsUidStateTracker private void onUidStateChanged(int uid, int state, boolean foregroundModeMayChange) { synchronized (this) { if (state == UID_STATE_NONEXISTENT) { onUidProcessDeathLocked(uid); } UidState uidState = getUidStateLocked(uid, false); boolean hasForegroundWatchers = false; Loading Loading @@ -1590,11 +1598,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } if (state == UID_STATE_NONEXISTENT) { // For UID_STATE_NONEXISTENT, we don't call onUidStateChanged for AttributedOps return; } if (uidState != null) { int numPkgs = uidState.pkgOps.size(); for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { Loading @@ -1619,8 +1622,8 @@ public class AppOpsService extends IAppOpsService.Stub { } } @GuardedBy("this") private void onUidProcessDeathLocked(int uid) { private void onUidProcessDeath(int uid) { synchronized (this) { if (!mUidStates.contains(uid) || !Flags.finishRunningOpsForKilledPackages()) { return; } Loading @@ -1645,6 +1648,7 @@ public class AppOpsService extends IAppOpsService.Stub { }); finishChainsLocked(chainsToFinish); } } @GuardedBy("this") private void finishChainsLocked(SparseLongArray chainsToFinish) { Loading
services/core/java/com/android/server/appop/AppOpsUidStateTracker.java +13 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.appop; import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_TOP; Loading @@ -27,8 +28,10 @@ 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.UID_STATE_NONEXISTENT; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.permission.flags.Flags.finishRunningOpsForKilledPackages; import android.annotation.CallbackExecutor; import android.util.SparseArray; Loading Loading @@ -68,6 +71,14 @@ interface AppOpsUidStateTracker { return UID_STATE_BACKGROUND; } if (finishRunningOpsForKilledPackages()) { if (procState < PROCESS_STATE_NONEXISTENT) { return UID_STATE_CACHED; } return UID_STATE_NONEXISTENT; } // UID_STATE_NONEXISTENT is deliberately excluded here return UID_STATE_CACHED; } Loading Loading @@ -119,6 +130,8 @@ interface AppOpsUidStateTracker { * evaluated result may have changed. */ void onUidStateChanged(int uid, int uidState, boolean foregroundModeMayChange); void onUidProcessDeath(int uid); } void dumpUidState(PrintWriter pw, int uid, long nowElapsed); Loading
services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +20 −17 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.ActivityManager.ProcessCapability; import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE; import static android.app.AppOpsManager.MODE_ALLOWED; Loading @@ -32,6 +31,7 @@ import static android.app.AppOpsManager.OP_CONTROL_AUDIO; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.UID_STATE_CACHED; import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_NONEXISTENT; Loading Loading @@ -75,7 +75,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private SparseBooleanArray mAppWidgetVisible = new SparseBooleanArray(); private SparseBooleanArray mPendingAppWidgetVisible = new SparseBooleanArray(); private SparseLongArray mPendingCommitTime = new SparseLongArray(); private SparseBooleanArray mPendingGone = new SparseBooleanArray(); private ArrayMap<UidStateChangedCallback, Executor> mUidStateChangedCallbacks = new ArrayMap<>(); Loading Loading @@ -221,11 +220,12 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { public void updateUidProcState(int uid, int procState, int capability) { int uidState = processStateToUidState(procState); int prevUidState = mUidStates.get(uid, AppOpsManager.MIN_PRIORITY_UID_STATE); int prevUidState = mUidStates.get(uid, AppOpsManager.UID_STATE_NONEXISTENT); int prevCapability = mCapability.get(uid, PROCESS_CAPABILITY_NONE); int pendingUidState = mPendingUidStates.get(uid, MIN_PRIORITY_UID_STATE); int pendingUidState = mPendingUidStates.get(uid, UID_STATE_NONEXISTENT); int pendingCapability = mPendingCapability.get(uid, PROCESS_CAPABILITY_NONE); long pendingStateCommitTime = mPendingCommitTime.get(uid, 0); if ((pendingStateCommitTime == 0 && (uidState != prevUidState || capability != prevCapability)) || (pendingStateCommitTime != 0 Loading @@ -239,8 +239,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { boolean hasLostCapability = (prevCapability & ~capability) != 0; if (procState == PROCESS_STATE_NONEXISTENT) { mPendingGone.put(uid, true); if (uidState == UID_STATE_NONEXISTENT) { commitUidPendingState(uid); } else if (uidState < prevUidState) { // We are moving to a more important state, or the new state may be in the Loading Loading @@ -342,7 +341,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private void commitUidPendingState(int uid) { int uidState = mUidStates.get(uid, MIN_PRIORITY_UID_STATE); int uidState = mUidStates.get(uid, UID_STATE_NONEXISTENT); int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE); boolean appWidgetVisible = mAppWidgetVisible.get(uid, false); Loading @@ -350,18 +349,23 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { int pendingCapability = mPendingCapability.get(uid, capability); boolean pendingAppWidgetVisible = mPendingAppWidgetVisible.get(uid, appWidgetVisible); boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED // UID_STATE_NONEXISTENT is a state that isn't used outside of this class, nonexistent // processes have always been represented as CACHED int externalUidState = Math.min(uidState, UID_STATE_CACHED); int externalPendingUidState = Math.min(pendingUidState, UID_STATE_CACHED); boolean foregroundChange = externalUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != externalPendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED || capability != pendingCapability || appWidgetVisible != pendingAppWidgetVisible; if (uidState != pendingUidState if (externalUidState != externalPendingUidState || capability != pendingCapability || appWidgetVisible != pendingAppWidgetVisible) { if (foregroundChange) { // To save on memory usage, log only interesting changes. mEventLog.logCommitUidState(uid, pendingUidState, pendingCapability, mEventLog.logCommitUidState(uid, externalPendingUidState, pendingCapability, pendingAppWidgetVisible, appWidgetVisible != pendingAppWidgetVisible); } Loading @@ -370,24 +374,23 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { Executor executor = mUidStateChangedCallbacks.valueAt(i); executor.execute(PooledLambda.obtainRunnable( UidStateChangedCallback::onUidStateChanged, cb, uid, pendingUidState, foregroundChange)); UidStateChangedCallback::onUidStateChanged, cb, uid, externalPendingUidState, foregroundChange)); } } if (mPendingGone.get(uid, false)) { if (pendingUidState == UID_STATE_NONEXISTENT && uidState != pendingUidState) { mUidStates.delete(uid); mCapability.delete(uid); mAppWidgetVisible.delete(uid); mPendingGone.delete(uid); if (finishRunningOpsForKilledPackages()) { for (int i = 0; i < mUidStateChangedCallbacks.size(); i++) { UidStateChangedCallback cb = mUidStateChangedCallbacks.keyAt(i); Executor executor = mUidStateChangedCallbacks.valueAt(i); // If foregroundness changed it should be handled in earlier callback invocation executor.execute(PooledLambda.obtainRunnable( UidStateChangedCallback::onUidStateChanged, cb, uid, UID_STATE_NONEXISTENT, foregroundChange)); UidStateChangedCallback::onUidProcessDeath, cb, uid)); } } } else { Loading
services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java +0 −247 Original line number Diff line number Diff line Loading @@ -26,15 +26,12 @@ import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUD import static android.app.AppOpsManager.OP_RECORD_AUDIO; import static android.app.AppOpsManager.OP_WIFI_SCAN; 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.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.permission.flags.Flags.delayUidStateChangesFromCapabilityUpdates; import static com.android.server.appop.AppOpsUidStateTracker.processStateToUidState; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -42,7 +39,6 @@ import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading @@ -64,7 +60,6 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.quality.Strictness; import java.util.PriorityQueue; Loading Loading @@ -94,7 +89,6 @@ public class AppOpsUidStateTrackerTest { public void setUp() { mSession = ExtendedMockito.mockitoSession() .initMocks(this) .strictness(Strictness.LENIENT) .startMocking(); mConstants.TOP_STATE_SETTLE_TIME = 10 * 1000L; mConstants.FG_SERVICE_STATE_SETTLE_TIME = 5 * 1000L; Loading Loading @@ -590,221 +584,6 @@ public class AppOpsUidStateTrackerTest { verify(cb, times(0)).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackCachedToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackCachedToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackCachedToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackCachedToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackBackgroundToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackBackgroundToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackBackgroundToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackBackgroundToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_RECEIVER, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackForegroundToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackForegroundToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackForegroundToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackForegroundToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_BOUND_TOP, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackForegroundServiceToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackForegroundServiceToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackForegroundServiceToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackForegroundServiceToTop() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, ActivityManager.PROCESS_STATE_TOP); } @Test public void testUidStateChangedCallbackTopToCached() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); } @Test public void testUidStateChangedCallbackTopToBackground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_RECEIVER); } @Test public void testUidStateChangedCallbackTopToForeground() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_BOUND_TOP); } @Test public void testUidStateChangedCallbackTopToForegroundService() { testUidStateChangedCallback( ActivityManager.PROCESS_STATE_TOP, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); } @Test public void testUidStateChangedCallbackCachedToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .cachedState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, never()).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackBackgroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(false)); } @Test public void testUidStateChangedCallbackForegroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedCallbackForegroundServiceToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundServiceState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedCallbackTopToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .topState() .update(); procStateBuilder(UID) .nonExistentState() .update(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } @Test public void testUidStateChangedBackgroundThenForegroundImmediately() { procStateBuilder(UID) Loading Loading @@ -882,32 +661,6 @@ public class AppOpsUidStateTrackerTest { assertEquals(UID_STATE_TOP, mIntf.getUidState(UID)); } public void testUidStateChangedCallback(int initialState, int finalState) { int initialUidState = processStateToUidState(initialState); int finalUidState = processStateToUidState(finalState); boolean foregroundChange = initialUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != finalUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED; boolean finalUidStateIsBackgroundAndLessImportant = finalUidState > UID_STATE_MAX_LAST_NON_RESTRICTED && finalUidState > initialUidState; UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .setState(initialState) .update(); procStateBuilder(UID) .setState(finalState) .update(); if (finalUidStateIsBackgroundAndLessImportant) { mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1); } verify(cb, atLeastOnce()) .onUidStateChanged(eq(UID), eq(finalUidState), eq(foregroundChange)); } private UidStateChangedCallback addUidStateChangeCallback() { UidStateChangedCallback cb = Loading
services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTransitionCallbackTest.java 0 → 100644 +260 −0 File added.Preview size limit exceeded, changes collapsed. Show changes