Loading services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +17 −16 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private SparseBooleanArray mVisibleAppWidget = new SparseBooleanArray(); private SparseBooleanArray mPendingVisibleAppWidget = new SparseBooleanArray(); private SparseLongArray mPendingCommitTime = new SparseLongArray(); private SparseBooleanArray mPendingGone = new SparseBooleanArray(); private ArrayMap<UidStateChangedCallback, Handler> mUidStateChangedCallbacks = new ArrayMap<>(); Loading Loading @@ -185,16 +186,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { @Override public void updateUidProcState(int uid, int procState, int capability) { mEventLog.logUpdateUidProcState(uid, procState, capability); if (procState == PROCESS_STATE_NONEXISTENT) { mUidStates.delete(uid); mPendingUidStates.delete(uid); mCapability.delete(uid); mPendingCapability.delete(uid); mVisibleAppWidget.delete(uid); mPendingVisibleAppWidget.delete(uid); mPendingCommitTime.delete(uid); return; } int uidState = processStateToUidState(procState); Loading @@ -205,7 +196,10 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { mPendingUidStates.put(uid, uidState); mPendingCapability.put(uid, capability); if (uidState < prevUidState 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)) { // We are moving to a more important state, or the new state may be in the Loading Loading @@ -312,7 +306,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { || capability != pendingCapability || visibleAppWidget != pendingVisibleAppWidget) { boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState > UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED || capability != pendingCapability || visibleAppWidget != pendingVisibleAppWidget; Loading @@ -327,13 +321,20 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { Handler h = mUidStateChangedCallbacks.valueAt(i); h.sendMessage(PooledLambda.obtainMessage(UidStateChangedCallback::onUidStateChanged, cb, uid, uidState, foregroundChange)); cb, uid, pendingUidState, foregroundChange)); } } if (mPendingGone.get(uid, false)) { mUidStates.delete(uid); mCapability.delete(uid); mVisibleAppWidget.delete(uid); mPendingGone.delete(uid); } else { mUidStates.put(uid, pendingUidState); mCapability.put(uid, pendingCapability); mVisibleAppWidget.put(uid, pendingVisibleAppWidget); } mPendingUidStates.delete(uid); mPendingCapability.delete(uid); Loading services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java +371 −9 Original line number Diff line number Diff line Loading @@ -24,11 +24,26 @@ import static android.app.AppOpsManager.OP_COARSE_LOCATION; import static android.app.AppOpsManager.OP_FINE_LOCATION; 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 com.android.server.appop.AppOpsUidStateTracker.processStateToUidState; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.ActivityManager; Loading @@ -41,12 +56,14 @@ import android.util.SparseArray; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.internal.os.Clock; import com.android.server.appop.AppOpsUidStateTracker.UidStateChangedCallback; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.quality.Strictness; import java.util.concurrent.atomic.AtomicLong; Loading Loading @@ -101,7 +118,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testConstantFirstUnrestrictedUidState() { for (int i = 0; i < AppOpsManager.getNumOps(); i++) { assertEquals(AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED, assertEquals(UID_STATE_MAX_LAST_NON_RESTRICTED, AppOpsManager.resolveFirstUnrestrictedUidState(i)); } } Loading @@ -109,7 +126,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testNoCapability() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND)); Loading @@ -121,7 +138,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithMicrophoneCapability() { procStateBuilder(UID) .foregroundState() .topState() .microphoneCapability() .update(); Loading Loading @@ -149,7 +166,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithCameraCapability() { procStateBuilder(UID) .foregroundState() .topState() .cameraCapability() .update(); Loading Loading @@ -177,7 +194,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithLocationCapability() { procStateBuilder(UID) .foregroundState() .topState() .locationCapability() .update(); Loading Loading @@ -205,7 +222,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundNotCapabilitiesTracked() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_NO_CAPABILITIES, MODE_FOREGROUND)); Loading @@ -228,7 +245,7 @@ public class AppOpsUidStateTrackerTest { assertBackground(UID); procStateBuilder(UID) .foregroundState() .topState() .update(); assertForeground(UID); } Loading @@ -236,7 +253,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundToBackgroundTransition() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertForeground(UID); Loading Loading @@ -446,6 +463,328 @@ public class AppOpsUidStateTrackerTest { assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND)); } @Test public void testUidStateChangedCallbackNewProcessTop() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .topState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_TOP), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessForegroundService() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundServiceState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND_SERVICE), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessForeground() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessBackground() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_BACKGROUND), eq(false)); } @Test public void testUidStateChangedCallbackNewProcessCached() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .cachedState() .update(); // Cached is the default, no change in uid state. 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(mHandler, never()).post(any()); verify(cb, never()).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackBackgroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } 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) { AtomicReference<Message> delayedMessage = new AtomicReference<>(); getPostDelayedMessageArguments(delayedMessage, new AtomicLong()); mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1); delayedMessage.get().getCallback().run(); } getLatestPostMessageArgument().getCallback().run(); verify(cb, atLeastOnce()) .onUidStateChanged(eq(UID), eq(finalUidState), eq(foregroundChange)); } private UidStateChangedCallback addUidStateChangeCallback() { UidStateChangedCallback cb = Mockito.mock(UidStateChangedCallback.class); mIntf.addUidStateChangedCallback(mHandler, cb); return cb; } /* If testForegroundNotCapabilitiesTracked fails, this assertion is probably incorrect */ private void assertForeground(int uid) { assertEquals(MODE_ALLOWED, mIntf.evalMode(uid, OP_NO_CAPABILITIES, MODE_FOREGROUND)); Loading @@ -472,6 +811,14 @@ public class AppOpsUidStateTrackerTest { } } private Message getLatestPostMessageArgument() { ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mHandler, atLeast(1)).sendMessage(messageCaptor.capture()); return messageCaptor.getValue(); } private UidProcStateUpdateBuilder procStateBuilder(int uid) { return new UidProcStateUpdateBuilder(mIntf, uid); } Loading @@ -496,7 +843,12 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder foregroundState() { public UidProcStateUpdateBuilder setState(int procState) { mProcState = procState; return this; } public UidProcStateUpdateBuilder topState() { mProcState = ActivityManager.PROCESS_STATE_TOP; return this; } Loading @@ -506,6 +858,11 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder foregroundState() { mProcState = ActivityManager.PROCESS_STATE_BOUND_TOP; return this; } public UidProcStateUpdateBuilder backgroundState() { mProcState = ActivityManager.PROCESS_STATE_SERVICE; return this; Loading @@ -516,6 +873,11 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder nonExistentState() { mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; return this; } public UidProcStateUpdateBuilder locationCapability() { mCapability |= ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; return this; Loading Loading
services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java +17 −16 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { private SparseBooleanArray mVisibleAppWidget = new SparseBooleanArray(); private SparseBooleanArray mPendingVisibleAppWidget = new SparseBooleanArray(); private SparseLongArray mPendingCommitTime = new SparseLongArray(); private SparseBooleanArray mPendingGone = new SparseBooleanArray(); private ArrayMap<UidStateChangedCallback, Handler> mUidStateChangedCallbacks = new ArrayMap<>(); Loading Loading @@ -185,16 +186,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { @Override public void updateUidProcState(int uid, int procState, int capability) { mEventLog.logUpdateUidProcState(uid, procState, capability); if (procState == PROCESS_STATE_NONEXISTENT) { mUidStates.delete(uid); mPendingUidStates.delete(uid); mCapability.delete(uid); mPendingCapability.delete(uid); mVisibleAppWidget.delete(uid); mPendingVisibleAppWidget.delete(uid); mPendingCommitTime.delete(uid); return; } int uidState = processStateToUidState(procState); Loading @@ -205,7 +196,10 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { mPendingUidStates.put(uid, uidState); mPendingCapability.put(uid, capability); if (uidState < prevUidState 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)) { // We are moving to a more important state, or the new state may be in the Loading Loading @@ -312,7 +306,7 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { || capability != pendingCapability || visibleAppWidget != pendingVisibleAppWidget) { boolean foregroundChange = uidState <= UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState > UID_STATE_MAX_LAST_NON_RESTRICTED != pendingUidState <= UID_STATE_MAX_LAST_NON_RESTRICTED || capability != pendingCapability || visibleAppWidget != pendingVisibleAppWidget; Loading @@ -327,13 +321,20 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker { Handler h = mUidStateChangedCallbacks.valueAt(i); h.sendMessage(PooledLambda.obtainMessage(UidStateChangedCallback::onUidStateChanged, cb, uid, uidState, foregroundChange)); cb, uid, pendingUidState, foregroundChange)); } } if (mPendingGone.get(uid, false)) { mUidStates.delete(uid); mCapability.delete(uid); mVisibleAppWidget.delete(uid); mPendingGone.delete(uid); } else { mUidStates.put(uid, pendingUidState); mCapability.put(uid, pendingCapability); mVisibleAppWidget.put(uid, pendingVisibleAppWidget); } mPendingUidStates.delete(uid); mPendingCapability.delete(uid); Loading
services/tests/mockingservicestests/src/com/android/server/appop/AppOpsUidStateTrackerTest.java +371 −9 Original line number Diff line number Diff line Loading @@ -24,11 +24,26 @@ import static android.app.AppOpsManager.OP_COARSE_LOCATION; import static android.app.AppOpsManager.OP_FINE_LOCATION; 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 com.android.server.appop.AppOpsUidStateTracker.processStateToUidState; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.ActivityManager; Loading @@ -41,12 +56,14 @@ import android.util.SparseArray; import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.internal.os.Clock; import com.android.server.appop.AppOpsUidStateTracker.UidStateChangedCallback; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.quality.Strictness; import java.util.concurrent.atomic.AtomicLong; Loading Loading @@ -101,7 +118,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testConstantFirstUnrestrictedUidState() { for (int i = 0; i < AppOpsManager.getNumOps(); i++) { assertEquals(AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED, assertEquals(UID_STATE_MAX_LAST_NON_RESTRICTED, AppOpsManager.resolveFirstUnrestrictedUidState(i)); } } Loading @@ -109,7 +126,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testNoCapability() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertEquals(MODE_IGNORED, mIntf.evalMode(UID, OP_RECORD_AUDIO, MODE_FOREGROUND)); Loading @@ -121,7 +138,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithMicrophoneCapability() { procStateBuilder(UID) .foregroundState() .topState() .microphoneCapability() .update(); Loading Loading @@ -149,7 +166,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithCameraCapability() { procStateBuilder(UID) .foregroundState() .topState() .cameraCapability() .update(); Loading Loading @@ -177,7 +194,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundWithLocationCapability() { procStateBuilder(UID) .foregroundState() .topState() .locationCapability() .update(); Loading Loading @@ -205,7 +222,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundNotCapabilitiesTracked() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_NO_CAPABILITIES, MODE_FOREGROUND)); Loading @@ -228,7 +245,7 @@ public class AppOpsUidStateTrackerTest { assertBackground(UID); procStateBuilder(UID) .foregroundState() .topState() .update(); assertForeground(UID); } Loading @@ -236,7 +253,7 @@ public class AppOpsUidStateTrackerTest { @Test public void testForegroundToBackgroundTransition() { procStateBuilder(UID) .foregroundState() .topState() .update(); assertForeground(UID); Loading Loading @@ -446,6 +463,328 @@ public class AppOpsUidStateTrackerTest { assertEquals(MODE_ALLOWED, mIntf.evalMode(UID, OP_FINE_LOCATION, MODE_FOREGROUND)); } @Test public void testUidStateChangedCallbackNewProcessTop() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .topState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_TOP), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessForegroundService() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundServiceState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND_SERVICE), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessForeground() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .foregroundState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_FOREGROUND), eq(true)); } @Test public void testUidStateChangedCallbackNewProcessBackground() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); getLatestPostMessageArgument().getCallback().run(); verify(cb).onUidStateChanged(eq(UID), eq(UID_STATE_BACKGROUND), eq(false)); } @Test public void testUidStateChangedCallbackNewProcessCached() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .cachedState() .update(); // Cached is the default, no change in uid state. 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(mHandler, never()).post(any()); verify(cb, never()).onUidStateChanged(anyInt(), anyInt(), anyBoolean()); } @Test public void testUidStateChangedCallbackBackgroundToNonexistent() { UidStateChangedCallback cb = addUidStateChangeCallback(); procStateBuilder(UID) .backgroundState() .update(); procStateBuilder(UID) .nonExistentState() .update(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); 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(); getLatestPostMessageArgument().getCallback().run(); verify(cb, atLeastOnce()).onUidStateChanged(eq(UID), eq(UID_STATE_CACHED), eq(true)); } 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) { AtomicReference<Message> delayedMessage = new AtomicReference<>(); getPostDelayedMessageArguments(delayedMessage, new AtomicLong()); mClock.advanceTime(mConstants.TOP_STATE_SETTLE_TIME + 1); delayedMessage.get().getCallback().run(); } getLatestPostMessageArgument().getCallback().run(); verify(cb, atLeastOnce()) .onUidStateChanged(eq(UID), eq(finalUidState), eq(foregroundChange)); } private UidStateChangedCallback addUidStateChangeCallback() { UidStateChangedCallback cb = Mockito.mock(UidStateChangedCallback.class); mIntf.addUidStateChangedCallback(mHandler, cb); return cb; } /* If testForegroundNotCapabilitiesTracked fails, this assertion is probably incorrect */ private void assertForeground(int uid) { assertEquals(MODE_ALLOWED, mIntf.evalMode(uid, OP_NO_CAPABILITIES, MODE_FOREGROUND)); Loading @@ -472,6 +811,14 @@ public class AppOpsUidStateTrackerTest { } } private Message getLatestPostMessageArgument() { ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mHandler, atLeast(1)).sendMessage(messageCaptor.capture()); return messageCaptor.getValue(); } private UidProcStateUpdateBuilder procStateBuilder(int uid) { return new UidProcStateUpdateBuilder(mIntf, uid); } Loading @@ -496,7 +843,12 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder foregroundState() { public UidProcStateUpdateBuilder setState(int procState) { mProcState = procState; return this; } public UidProcStateUpdateBuilder topState() { mProcState = ActivityManager.PROCESS_STATE_TOP; return this; } Loading @@ -506,6 +858,11 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder foregroundState() { mProcState = ActivityManager.PROCESS_STATE_BOUND_TOP; return this; } public UidProcStateUpdateBuilder backgroundState() { mProcState = ActivityManager.PROCESS_STATE_SERVICE; return this; Loading @@ -516,6 +873,11 @@ public class AppOpsUidStateTrackerTest { return this; } public UidProcStateUpdateBuilder nonExistentState() { mProcState = ActivityManager.PROCESS_STATE_NONEXISTENT; return this; } public UidProcStateUpdateBuilder locationCapability() { mCapability |= ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; return this; Loading