Loading packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +93 −26 Original line number Diff line number Diff line Loading @@ -39,25 +39,39 @@ import java.util.Set; * NotificationPresenter to be displayed to the user. */ public class AppOpsControllerImpl implements AppOpsController, AppOpsManager.OnOpActiveChangedListener { AppOpsManager.OnOpActiveChangedListener, AppOpsManager.OnOpNotedListener { private static final long LOCATION_TIME_DELAY_MS = 5000; private static final long NOTED_OP_TIME_DELAY_MS = 5000; private static final String TAG = "AppOpsControllerImpl"; private static final boolean DEBUG = false; private final Context mContext; protected final AppOpsManager mAppOps; private final H mBGHandler; private final AppOpsManager mAppOps; private H mBGHandler; private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>(); private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>(); @GuardedBy("mActiveItems") private final List<AppOpItem> mActiveItems = new ArrayList<>(); @GuardedBy("mNotedItems") private final List<AppOpItem> mNotedItems = new ArrayList<>(); protected static final int[] OPS; protected static final String[] OPS_STRING = new String[] { AppOpsManager.OPSTR_CAMERA, AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, AppOpsManager.OPSTR_RECORD_AUDIO, AppOpsManager.OPSTR_COARSE_LOCATION, AppOpsManager.OPSTR_FINE_LOCATION}; protected static final int[] OPS = new int[] {AppOpsManager.OP_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION}; static { int numOps = OPS_STRING.length; OPS = new int[numOps]; for (int i = 0; i < numOps; i++) { OPS[i] = AppOpsManager.strOpToOp(OPS_STRING[i]); } } public AppOpsControllerImpl(Context context, Looper bgLooper) { mContext = context; Loading @@ -69,12 +83,19 @@ public class AppOpsControllerImpl implements AppOpsController, } } @VisibleForTesting protected void setBGHandler(H handler) { mBGHandler = handler; } @VisibleForTesting protected void setListening(boolean listening) { if (listening) { mAppOps.startWatchingActive(OPS, this); mAppOps.startWatchingNoted(OPS_STRING, this); } else { mAppOps.stopWatchingActive(this); mAppOps.stopWatchingNoted(this); } } Loading Loading @@ -124,10 +145,11 @@ public class AppOpsControllerImpl implements AppOpsController, if (mCallbacks.isEmpty()) setListening(false); } private AppOpItem getAppOpItem(int code, int uid, String packageName) { final int itemsQ = mActiveItems.size(); private AppOpItem getAppOpItem(List<AppOpItem> appOpList, int code, int uid, String packageName) { final int itemsQ = appOpList.size(); for (int i = 0; i < itemsQ; i++) { AppOpItem item = mActiveItems.get(i); AppOpItem item = appOpList.get(i); if (item.getCode() == code && item.getUid() == uid && item.getPackageName().equals(packageName)) { return item; Loading @@ -138,39 +160,59 @@ public class AppOpsControllerImpl implements AppOpsController, private boolean updateActives(int code, int uid, String packageName, boolean active) { synchronized (mActiveItems) { AppOpItem item = getAppOpItem(code, uid, packageName); AppOpItem item = getAppOpItem(mActiveItems, code, uid, packageName); if (item == null && active) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); mActiveItems.add(item); if (code == AppOpsManager.OP_COARSE_LOCATION || code == AppOpsManager.OP_FINE_LOCATION) { mBGHandler.scheduleRemoval(item, LOCATION_TIME_DELAY_MS); } if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); return true; } else if (item != null && !active) { mActiveItems.remove(item); if (DEBUG) Log.w(TAG, "Removed item: " + item.toString()); return true; } else if (item != null && active && (code == AppOpsManager.OP_COARSE_LOCATION || code == AppOpsManager.OP_FINE_LOCATION)) { mBGHandler.scheduleRemoval(item, LOCATION_TIME_DELAY_MS); return true; } return false; } } private void removeNoted(int code, int uid, String packageName) { AppOpItem item; synchronized (mNotedItems) { item = getAppOpItem(mNotedItems, code, uid, packageName); if (item == null) return; mNotedItems.remove(item); if (DEBUG) Log.w(TAG, "Removed item: " + item.toString()); } notifySuscribers(code, uid, packageName, false); } private void addNoted(int code, int uid, String packageName) { AppOpItem item; synchronized (mNotedItems) { item = getAppOpItem(mNotedItems, code, uid, packageName); if (item == null) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); mNotedItems.add(item); if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); } } mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); } /** * Returns a copy of the list containing all the active AppOps that the controller tracks. * * @return List of active AppOps information */ public List<AppOpItem> getActiveAppOps() { ArrayList<AppOpItem> active; synchronized (mActiveItems) { return new ArrayList<>(mActiveItems); active = new ArrayList<>(mActiveItems); } synchronized (mNotedItems) { active.addAll(mNotedItems); } return active; } /** Loading @@ -192,19 +234,45 @@ public class AppOpsControllerImpl implements AppOpsController, } } } synchronized (mNotedItems) { final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { list.add(item); } } } return list; } @Override public void onOpActiveChanged(int code, int uid, String packageName, boolean active) { if (updateActives(code, uid, packageName, active)) { notifySuscribers(code, uid, packageName, active); } } @Override public void onOpNoted(String code, int uid, String packageName, int result) { if (DEBUG) { Log.w(TAG, "Op: " + code + " with result " + AppOpsManager.MODE_NAMES[result]); } if (result != AppOpsManager.MODE_ALLOWED) return; int op_code = AppOpsManager.strOpToOp(code); addNoted(op_code, uid, packageName); notifySuscribers(op_code, uid, packageName, true); } private void notifySuscribers(int code, int uid, String packageName, boolean active) { if (mCallbacksByCode.containsKey(code)) { for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); } } } private final class H extends Handler { protected final class H extends Handler { H(Looper looper) { super(looper); } Loading @@ -214,8 +282,7 @@ public class AppOpsControllerImpl implements AppOpsController, postDelayed(new Runnable() { @Override public void run() { onOpActiveChanged(item.getCode(), item.getUid(), item.getPackageName(), false); removeNoted(item.getCode(), item.getUid(), item.getPackageName()); } }, item, timeToRemoval); } Loading packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class PrivacyItemController(val context: Context, val callback: Callback) { private fun updatePrivacyList() { privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } .mapNotNull { toPrivacyItem(it) } .mapNotNull { toPrivacyItem(it) }.distinct() } private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { Loading packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +31 −10 Original line number Diff line number Diff line Loading @@ -17,8 +17,10 @@ package com.android.systemui.appops; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading @@ -32,7 +34,6 @@ import android.testing.TestableLooper; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationPresenter; import org.junit.Before; import org.junit.Test; Loading @@ -48,9 +49,12 @@ public class AppOpsControllerTest extends SysuiTestCase { private static final int TEST_UID = 0; private static final int TEST_UID_OTHER = 500000; @Mock private NotificationPresenter mPresenter; @Mock private AppOpsManager mAppOpsManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsManager mAppOpsManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsControllerImpl.H mMockHandler; private AppOpsControllerImpl mController; Loading @@ -77,9 +81,13 @@ public class AppOpsControllerTest extends SysuiTestCase { @Test public void addCallback_includedCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mController.addCallback( new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } Loading @@ -106,7 +114,7 @@ public class AppOpsControllerTest extends SysuiTestCase { @Test public void addCallback_notSameCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mController.removeCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, Loading @@ -128,17 +136,30 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, true); assertEquals(2, mController.getActiveAppOps().size()); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); assertEquals(3, mController.getActiveAppOps().size()); } @Test public void getActiveItemsForUser() { @Test public void getActiveItemsForUser() { mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged(AppOpsManager.OP_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); assertEquals(1, mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); assertEquals(2, mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size()); assertEquals(1, mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size()); mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); verify(mMockHandler).scheduleRemoval(any(AppOpItem.class), anyLong()); } } packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +24 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.privacy import android.app.ActivityManager import android.app.AppOpsManager import android.content.Intent import android.content.pm.UserInfo import android.os.Handler import android.os.UserHandle import android.os.UserManager Loading @@ -30,13 +31,16 @@ import com.android.systemui.Dependency import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyList import org.mockito.ArgumentMatchers.eq import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.doReturn Loading @@ -52,8 +56,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { companion object { val CURRENT_USER_ID = ActivityManager.getCurrentUser() val OTHER_USER = UserHandle(CURRENT_USER_ID + 1) const val TAG = "PrivacyItemControllerTest" fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() } @Mock Loading @@ -62,6 +66,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { private lateinit var callback: PrivacyItemController.Callback @Mock private lateinit var userManager: UserManager @Captor private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>> private lateinit var testableLooper: TestableLooper private lateinit var privacyItemController: PrivacyItemController Loading @@ -76,8 +82,11 @@ class PrivacyItemControllerTest : SysuiTestCase() { mDependency.injectTestDependency(Dependency.MAIN_HANDLER, Handler(testableLooper.looper)) mContext.addMockSystemService(UserManager::class.java, userManager) doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, 0, "", 0))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) doReturn(listOf(object : UserInfo() { init { id = CURRENT_USER_ID } })).`when`(userManager).getProfiles(anyInt()) privacyItemController = PrivacyItemController(mContext, callback) } Loading @@ -99,6 +108,18 @@ class PrivacyItemControllerTest : SysuiTestCase() { any(AppOpsController.Callback::class.java)) } @Test fun testDistinctItems() { doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, CURRENT_USER_ID, "", 0), AppOpItem(AppOpsManager.OP_CAMERA, CURRENT_USER_ID, "", 1))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) privacyItemController.setListening(true) testableLooper.processAllMessages() verify(callback).privacyChanged(capture(argCaptor)) assertEquals(1, argCaptor.value.size) } @Test fun testRegisterReceiver_allUsers() { val spiedContext = spy(mContext) Loading Loading
packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +93 −26 Original line number Diff line number Diff line Loading @@ -39,25 +39,39 @@ import java.util.Set; * NotificationPresenter to be displayed to the user. */ public class AppOpsControllerImpl implements AppOpsController, AppOpsManager.OnOpActiveChangedListener { AppOpsManager.OnOpActiveChangedListener, AppOpsManager.OnOpNotedListener { private static final long LOCATION_TIME_DELAY_MS = 5000; private static final long NOTED_OP_TIME_DELAY_MS = 5000; private static final String TAG = "AppOpsControllerImpl"; private static final boolean DEBUG = false; private final Context mContext; protected final AppOpsManager mAppOps; private final H mBGHandler; private final AppOpsManager mAppOps; private H mBGHandler; private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>(); private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>(); @GuardedBy("mActiveItems") private final List<AppOpItem> mActiveItems = new ArrayList<>(); @GuardedBy("mNotedItems") private final List<AppOpItem> mNotedItems = new ArrayList<>(); protected static final int[] OPS; protected static final String[] OPS_STRING = new String[] { AppOpsManager.OPSTR_CAMERA, AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, AppOpsManager.OPSTR_RECORD_AUDIO, AppOpsManager.OPSTR_COARSE_LOCATION, AppOpsManager.OPSTR_FINE_LOCATION}; protected static final int[] OPS = new int[] {AppOpsManager.OP_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION}; static { int numOps = OPS_STRING.length; OPS = new int[numOps]; for (int i = 0; i < numOps; i++) { OPS[i] = AppOpsManager.strOpToOp(OPS_STRING[i]); } } public AppOpsControllerImpl(Context context, Looper bgLooper) { mContext = context; Loading @@ -69,12 +83,19 @@ public class AppOpsControllerImpl implements AppOpsController, } } @VisibleForTesting protected void setBGHandler(H handler) { mBGHandler = handler; } @VisibleForTesting protected void setListening(boolean listening) { if (listening) { mAppOps.startWatchingActive(OPS, this); mAppOps.startWatchingNoted(OPS_STRING, this); } else { mAppOps.stopWatchingActive(this); mAppOps.stopWatchingNoted(this); } } Loading Loading @@ -124,10 +145,11 @@ public class AppOpsControllerImpl implements AppOpsController, if (mCallbacks.isEmpty()) setListening(false); } private AppOpItem getAppOpItem(int code, int uid, String packageName) { final int itemsQ = mActiveItems.size(); private AppOpItem getAppOpItem(List<AppOpItem> appOpList, int code, int uid, String packageName) { final int itemsQ = appOpList.size(); for (int i = 0; i < itemsQ; i++) { AppOpItem item = mActiveItems.get(i); AppOpItem item = appOpList.get(i); if (item.getCode() == code && item.getUid() == uid && item.getPackageName().equals(packageName)) { return item; Loading @@ -138,39 +160,59 @@ public class AppOpsControllerImpl implements AppOpsController, private boolean updateActives(int code, int uid, String packageName, boolean active) { synchronized (mActiveItems) { AppOpItem item = getAppOpItem(code, uid, packageName); AppOpItem item = getAppOpItem(mActiveItems, code, uid, packageName); if (item == null && active) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); mActiveItems.add(item); if (code == AppOpsManager.OP_COARSE_LOCATION || code == AppOpsManager.OP_FINE_LOCATION) { mBGHandler.scheduleRemoval(item, LOCATION_TIME_DELAY_MS); } if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); return true; } else if (item != null && !active) { mActiveItems.remove(item); if (DEBUG) Log.w(TAG, "Removed item: " + item.toString()); return true; } else if (item != null && active && (code == AppOpsManager.OP_COARSE_LOCATION || code == AppOpsManager.OP_FINE_LOCATION)) { mBGHandler.scheduleRemoval(item, LOCATION_TIME_DELAY_MS); return true; } return false; } } private void removeNoted(int code, int uid, String packageName) { AppOpItem item; synchronized (mNotedItems) { item = getAppOpItem(mNotedItems, code, uid, packageName); if (item == null) return; mNotedItems.remove(item); if (DEBUG) Log.w(TAG, "Removed item: " + item.toString()); } notifySuscribers(code, uid, packageName, false); } private void addNoted(int code, int uid, String packageName) { AppOpItem item; synchronized (mNotedItems) { item = getAppOpItem(mNotedItems, code, uid, packageName); if (item == null) { item = new AppOpItem(code, uid, packageName, System.currentTimeMillis()); mNotedItems.add(item); if (DEBUG) Log.w(TAG, "Added item: " + item.toString()); } } mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); } /** * Returns a copy of the list containing all the active AppOps that the controller tracks. * * @return List of active AppOps information */ public List<AppOpItem> getActiveAppOps() { ArrayList<AppOpItem> active; synchronized (mActiveItems) { return new ArrayList<>(mActiveItems); active = new ArrayList<>(mActiveItems); } synchronized (mNotedItems) { active.addAll(mNotedItems); } return active; } /** Loading @@ -192,19 +234,45 @@ public class AppOpsControllerImpl implements AppOpsController, } } } synchronized (mNotedItems) { final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { list.add(item); } } } return list; } @Override public void onOpActiveChanged(int code, int uid, String packageName, boolean active) { if (updateActives(code, uid, packageName, active)) { notifySuscribers(code, uid, packageName, active); } } @Override public void onOpNoted(String code, int uid, String packageName, int result) { if (DEBUG) { Log.w(TAG, "Op: " + code + " with result " + AppOpsManager.MODE_NAMES[result]); } if (result != AppOpsManager.MODE_ALLOWED) return; int op_code = AppOpsManager.strOpToOp(code); addNoted(op_code, uid, packageName); notifySuscribers(op_code, uid, packageName, true); } private void notifySuscribers(int code, int uid, String packageName, boolean active) { if (mCallbacksByCode.containsKey(code)) { for (Callback cb: mCallbacksByCode.get(code)) { cb.onActiveStateChanged(code, uid, packageName, active); } } } private final class H extends Handler { protected final class H extends Handler { H(Looper looper) { super(looper); } Loading @@ -214,8 +282,7 @@ public class AppOpsControllerImpl implements AppOpsController, postDelayed(new Runnable() { @Override public void run() { onOpActiveChanged(item.getCode(), item.getUid(), item.getPackageName(), false); removeNoted(item.getCode(), item.getUid(), item.getPackageName()); } }, item, timeToRemoval); } Loading
packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ class PrivacyItemController(val context: Context, val callback: Callback) { private fun updatePrivacyList() { privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) } .mapNotNull { toPrivacyItem(it) } .mapNotNull { toPrivacyItem(it) }.distinct() } private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? { Loading
packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +31 −10 Original line number Diff line number Diff line Loading @@ -17,8 +17,10 @@ package com.android.systemui.appops; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading @@ -32,7 +34,6 @@ import android.testing.TestableLooper; import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationPresenter; import org.junit.Before; import org.junit.Test; Loading @@ -48,9 +49,12 @@ public class AppOpsControllerTest extends SysuiTestCase { private static final int TEST_UID = 0; private static final int TEST_UID_OTHER = 500000; @Mock private NotificationPresenter mPresenter; @Mock private AppOpsManager mAppOpsManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsManager mAppOpsManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsControllerImpl.H mMockHandler; private AppOpsControllerImpl mController; Loading @@ -77,9 +81,13 @@ public class AppOpsControllerTest extends SysuiTestCase { @Test public void addCallback_includedCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mController.addCallback( new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } Loading @@ -106,7 +114,7 @@ public class AppOpsControllerTest extends SysuiTestCase { @Test public void addCallback_notSameCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mController.removeCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback); mController.onOpActiveChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, Loading @@ -128,17 +136,30 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, true); assertEquals(2, mController.getActiveAppOps().size()); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); assertEquals(3, mController.getActiveAppOps().size()); } @Test public void getActiveItemsForUser() { @Test public void getActiveItemsForUser() { mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged(AppOpsManager.OP_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); assertEquals(1, mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); assertEquals(2, mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size()); assertEquals(1, mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID)).size()); mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); mController.onOpNoted(AppOpsManager.OPSTR_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME, AppOpsManager.MODE_ALLOWED); verify(mMockHandler).scheduleRemoval(any(AppOpItem.class), anyLong()); } }
packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt +24 −3 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.privacy import android.app.ActivityManager import android.app.AppOpsManager import android.content.Intent import android.content.pm.UserInfo import android.os.Handler import android.os.UserHandle import android.os.UserManager Loading @@ -30,13 +31,16 @@ import com.android.systemui.Dependency import com.android.systemui.SysuiTestCase import com.android.systemui.appops.AppOpItem import com.android.systemui.appops.AppOpsController import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyList import org.mockito.ArgumentMatchers.eq import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.doReturn Loading @@ -52,8 +56,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { companion object { val CURRENT_USER_ID = ActivityManager.getCurrentUser() val OTHER_USER = UserHandle(CURRENT_USER_ID + 1) const val TAG = "PrivacyItemControllerTest" fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture() } @Mock Loading @@ -62,6 +66,8 @@ class PrivacyItemControllerTest : SysuiTestCase() { private lateinit var callback: PrivacyItemController.Callback @Mock private lateinit var userManager: UserManager @Captor private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>> private lateinit var testableLooper: TestableLooper private lateinit var privacyItemController: PrivacyItemController Loading @@ -76,8 +82,11 @@ class PrivacyItemControllerTest : SysuiTestCase() { mDependency.injectTestDependency(Dependency.MAIN_HANDLER, Handler(testableLooper.looper)) mContext.addMockSystemService(UserManager::class.java, userManager) doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, 0, "", 0))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) doReturn(listOf(object : UserInfo() { init { id = CURRENT_USER_ID } })).`when`(userManager).getProfiles(anyInt()) privacyItemController = PrivacyItemController(mContext, callback) } Loading @@ -99,6 +108,18 @@ class PrivacyItemControllerTest : SysuiTestCase() { any(AppOpsController.Callback::class.java)) } @Test fun testDistinctItems() { doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, CURRENT_USER_ID, "", 0), AppOpItem(AppOpsManager.OP_CAMERA, CURRENT_USER_ID, "", 1))) .`when`(appOpsController).getActiveAppOpsForUser(anyInt()) privacyItemController.setListening(true) testableLooper.processAllMessages() verify(callback).privacyChanged(capture(argCaptor)) assertEquals(1, argCaptor.value.size) } @Test fun testRegisterReceiver_allUsers() { val spiedContext = spy(mContext) Loading