Loading packages/SystemUI/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ <uses-permission android:name="android.permission.MANAGE_BIOMETRIC" /> <uses-permission android:name="android.permission.MANAGE_SLICE_PERMISSIONS" /> <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" /> <uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" /> <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked --> <uses-permission android:name="android.permission.SET_WALLPAPER"/> Loading packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +25 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; Loading Loading @@ -202,27 +203,38 @@ public class AppOpsControllerImpl implements AppOpsController, mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); } /** * Does the app-op item refer to a user sensitive permission. Only user sensitive permission * should be shown to the user by default. * * @param item The item * * @return {@code true} iff the app-op item is user sensitive */ private boolean isUserSensitive(AppOpItem item) { String permission = AppOpsManager.opToPermission(item.getCode()); if (permission == null) { return false; } int permFlags = mContext.getPackageManager().getPermissionFlags(permission, item.getPackageName(), UserHandle.getUserHandleForUid(item.getUid())); return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; } /** * 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) { active = new ArrayList<>(mActiveItems); } synchronized (mNotedItems) { active.addAll(mNotedItems); } return active; return getActiveAppOpsForUser(UserHandle.USER_ALL); } /** * Returns a copy of the list containing all the active AppOps that the controller tracks, for * a given user id. * * @param userId User id to track * @param userId User id to track, can be {@link UserHandle#USER_ALL} * * @return List of active AppOps information for that user id */ Loading @@ -232,7 +244,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numActiveItems = mActiveItems.size(); for (int i = 0; i < numActiveItems; i++) { AppOpItem item = mActiveItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) && isUserSensitive(item)) { list.add(item); } } Loading @@ -241,7 +254,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) && isUserSensitive(item)) { list.add(item); } } Loading packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +28 −2 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ 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.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.pm.PackageManager; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -47,12 +50,15 @@ import org.mockito.MockitoAnnotations; @TestableLooper.RunWithLooper public class AppOpsControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = 0; private static final int TEST_UID_OTHER = 500000; private static final int TEST_UID = UserHandle.getUid(0, 0); private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0); private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0); @Mock private AppOpsManager mAppOpsManager; @Mock private PackageManager mPackageManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsControllerImpl.H mMockHandler; Loading @@ -65,6 +71,18 @@ public class AppOpsControllerTest extends SysuiTestCase { getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of // TEST_UID_NON_USER_SENSITIVE are user sensitive. getContext().setMockPackageManager(mPackageManager); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn( PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn( PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0); mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER)); } Loading Loading @@ -156,6 +174,14 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } @Test public void nonUserSensitiveOpsAreIgnored() { mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); assertEquals(0, mController.getActiveAppOpsForUser( UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size()); } @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); Loading Loading
packages/SystemUI/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,7 @@ <uses-permission android:name="android.permission.MANAGE_BIOMETRIC" /> <uses-permission android:name="android.permission.MANAGE_SLICE_PERMISSIONS" /> <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" /> <uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" /> <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked --> <uses-permission android:name="android.permission.SET_WALLPAPER"/> Loading
packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +25 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.android.systemui.Dependency.BG_LOOPER_NAME; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.UserHandle; Loading Loading @@ -202,27 +203,38 @@ public class AppOpsControllerImpl implements AppOpsController, mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS); } /** * Does the app-op item refer to a user sensitive permission. Only user sensitive permission * should be shown to the user by default. * * @param item The item * * @return {@code true} iff the app-op item is user sensitive */ private boolean isUserSensitive(AppOpItem item) { String permission = AppOpsManager.opToPermission(item.getCode()); if (permission == null) { return false; } int permFlags = mContext.getPackageManager().getPermissionFlags(permission, item.getPackageName(), UserHandle.getUserHandleForUid(item.getUid())); return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; } /** * 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) { active = new ArrayList<>(mActiveItems); } synchronized (mNotedItems) { active.addAll(mNotedItems); } return active; return getActiveAppOpsForUser(UserHandle.USER_ALL); } /** * Returns a copy of the list containing all the active AppOps that the controller tracks, for * a given user id. * * @param userId User id to track * @param userId User id to track, can be {@link UserHandle#USER_ALL} * * @return List of active AppOps information for that user id */ Loading @@ -232,7 +244,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numActiveItems = mActiveItems.size(); for (int i = 0; i < numActiveItems; i++) { AppOpItem item = mActiveItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) && isUserSensitive(item)) { list.add(item); } } Loading @@ -241,7 +254,8 @@ public class AppOpsControllerImpl implements AppOpsController, final int numNotedItems = mNotedItems.size(); for (int i = 0; i < numNotedItems; i++) { AppOpItem item = mNotedItems.get(i); if (UserHandle.getUserId(item.getUid()) == userId) { if ((userId == UserHandle.USER_ALL || UserHandle.getUserId(item.getUid()) == userId) && isUserSensitive(item)) { list.add(item); } } Loading
packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +28 −2 Original line number Diff line number Diff line Loading @@ -22,11 +22,14 @@ 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.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.pm.PackageManager; import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -47,12 +50,15 @@ import org.mockito.MockitoAnnotations; @TestableLooper.RunWithLooper public class AppOpsControllerTest extends SysuiTestCase { private static final String TEST_PACKAGE_NAME = "test"; private static final int TEST_UID = 0; private static final int TEST_UID_OTHER = 500000; private static final int TEST_UID = UserHandle.getUid(0, 0); private static final int TEST_UID_OTHER = UserHandle.getUid(1, 0); private static final int TEST_UID_NON_USER_SENSITIVE = UserHandle.getUid(2, 0); @Mock private AppOpsManager mAppOpsManager; @Mock private PackageManager mPackageManager; @Mock private AppOpsController.Callback mCallback; @Mock private AppOpsControllerImpl.H mMockHandler; Loading @@ -65,6 +71,18 @@ public class AppOpsControllerTest extends SysuiTestCase { getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager); // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of // TEST_UID_NON_USER_SENSITIVE are user sensitive. getContext().setMockPackageManager(mPackageManager); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn( PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn( PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED); when(mPackageManager.getPermissionFlags(anyString(), anyString(), eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0); mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER)); } Loading Loading @@ -156,6 +174,14 @@ public class AppOpsControllerTest extends SysuiTestCase { mController.getActiveAppOpsForUser(UserHandle.getUserId(TEST_UID_OTHER)).size()); } @Test public void nonUserSensitiveOpsAreIgnored() { mController.onOpActiveChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID_NON_USER_SENSITIVE, TEST_PACKAGE_NAME, true); assertEquals(0, mController.getActiveAppOpsForUser( UserHandle.getUserId(TEST_UID_NON_USER_SENSITIVE)).size()); } @Test public void opNotedScheduledForRemoval() { mController.setBGHandler(mMockHandler); Loading