diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java index da2715eee8..67846bc93c 100755 --- a/service/src/com/android/server/connectivity/PermissionMonitor.java +++ b/service/src/com/android/server/connectivity/PermissionMonitor.java @@ -23,7 +23,6 @@ import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; -import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS; import static android.net.INetd.PERMISSION_INTERNET; import static android.net.INetd.PERMISSION_NETWORK; @@ -60,9 +59,9 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.system.OsConstants; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; -import android.util.SparseArray; import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; @@ -98,9 +97,9 @@ public class PermissionMonitor { @GuardedBy("this") private final Set mUsers = new HashSet<>(); - // Keys are appIds. Values are true for SYSTEM permission and false for NETWORK permission. + // Keys are uids. Values are netd network permissions. @GuardedBy("this") - private final SparseIntArray mApps = new SparseIntArray(); + private final SparseIntArray mUidToNetworkPerm = new SparseIntArray(); // Keys are active non-bypassable and fully-routed VPN's interface name, Values are uid ranges // for apps under the VPN @@ -121,6 +120,11 @@ public class PermissionMonitor { @GuardedBy("this") private final Set mUidsAllowedOnRestrictedNetworks = new ArraySet<>(); + @GuardedBy("this") + private final Map mUsersPackageManager = new ArrayMap<>(); + + private static final int SYSTEM_APPID = SYSTEM_UID; + private static final int MAX_PERMISSION_UPDATE_LOGS = 40; private final SharedLog mPermissionUpdateLogs = new SharedLog(MAX_PERMISSION_UPDATE_LOGS, TAG); @@ -212,6 +216,83 @@ public class PermissionMonitor { return targetPermission > currentPermission; } + private List getInstalledPackagesAsUser(final UserHandle user) { + return mPackageManager.getInstalledPackagesAsUser(GET_PERMISSIONS, user.getIdentifier()); + } + + private synchronized void updateAllApps(final List apps) { + for (PackageInfo app : apps) { + final int appId = app.applicationInfo != null + ? UserHandle.getAppId(app.applicationInfo.uid) : INVALID_UID; + if (appId < 0) { + continue; + } + mAllApps.add(appId); + } + } + + // Return the network permission for the passed list of apps. Note that this depends on the + // current settings of the device (See isUidAllowedOnRestrictedNetworks). + private SparseIntArray makeUidsNetworkPerm(final List apps) { + final SparseIntArray uidsPerm = new SparseIntArray(); + for (PackageInfo app : apps) { + final int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID; + if (uid < 0) { + continue; + } + final int permission = getPackageNetdNetworkPermission(app); + if (isHigherNetworkPermission(permission, uidsPerm.get(uid, PERMISSION_NONE))) { + uidsPerm.put(uid, permission); + } + } + return uidsPerm; + } + + private static SparseIntArray makeAppIdsTrafficPerm(final List apps) { + final SparseIntArray appIdsPerm = new SparseIntArray(); + for (PackageInfo app : apps) { + final int appId = app.applicationInfo != null + ? UserHandle.getAppId(app.applicationInfo.uid) : INVALID_UID; + if (appId < 0) { + continue; + } + final int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions, + app.requestedPermissionsFlags); + appIdsPerm.put(appId, appIdsPerm.get(appId) | otherNetdPerms); + } + return appIdsPerm; + } + + private synchronized void updateUidsNetworkPermission(final SparseIntArray uids) { + for (int i = 0; i < uids.size(); i++) { + mUidToNetworkPerm.put(uids.keyAt(i), uids.valueAt(i)); + } + sendUidsNetworkPermission(uids, true /* add */); + } + + private void updateAppIdsTrafficPermission(final SparseIntArray appIds, + final SparseIntArray extraAppIds) { + for (int i = 0; i < extraAppIds.size(); i++) { + final int appId = extraAppIds.keyAt(i); + final int permission = extraAppIds.valueAt(i); + appIds.put(appId, appIds.get(appId) | permission); + } + sendAppIdsTrafficPermission(appIds); + } + + private SparseIntArray getSystemTrafficPerm() { + final SparseIntArray appIdsPerm = new SparseIntArray(); + for (final int uid : mSystemConfigManager.getSystemPermissionUids(INTERNET)) { + final int appId = UserHandle.getAppId(uid); + appIdsPerm.put(appId, appIdsPerm.get(appId) | PERMISSION_INTERNET); + } + for (final int uid : mSystemConfigManager.getSystemPermissionUids(UPDATE_DEVICE_STATS)) { + final int appId = UserHandle.getAppId(uid); + appIdsPerm.put(appId, appIdsPerm.get(appId) | PERMISSION_UPDATE_DEVICE_STATS); + } + return appIdsPerm; + } + // Intended to be called only once at startup, after the system is ready. Installs a broadcast // receiver to monitor ongoing UID changes, so this shouldn't/needn't be called again. public synchronized void startMonitoring() { @@ -252,65 +333,18 @@ public class PermissionMonitor { // mUidsAllowedOnRestrictedNetworks. updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext)); - List apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS - | MATCH_ANY_USER); - if (apps == null) { - loge("No apps"); - return; + final List usrs = mUserManager.getUserHandles(true /* excludeDying */); + // Update netd permissions for all users. + for (UserHandle user : usrs) { + onUserAdded(user); } - - final SparseIntArray netdPermsAppIds = new SparseIntArray(); - - for (PackageInfo app : apps) { - int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID; - if (uid < 0) { - continue; - } - final int appId = UserHandle.getAppId(uid); - mAllApps.add(appId); - - final int permission = getPackageNetdNetworkPermission(app); - if (isHigherNetworkPermission(permission, mApps.get(appId, PERMISSION_NONE))) { - mApps.put(appId, permission); - } - - //TODO: unify the management of the permissions into one codepath. - int otherNetdPerms = getNetdPermissionMask(app.requestedPermissions, - app.requestedPermissionsFlags); - netdPermsAppIds.put(appId, netdPermsAppIds.get(appId) | otherNetdPerms); - } - - mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */)); - - final SparseArray netdPermToSystemPerm = new SparseArray<>(); - netdPermToSystemPerm.put(PERMISSION_INTERNET, INTERNET); - netdPermToSystemPerm.put(PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS); - for (int i = 0; i < netdPermToSystemPerm.size(); i++) { - final int netdPermission = netdPermToSystemPerm.keyAt(i); - final String systemPermission = netdPermToSystemPerm.valueAt(i); - final int[] hasPermissionUids = - mSystemConfigManager.getSystemPermissionUids(systemPermission); - for (int j = 0; j < hasPermissionUids.length; j++) { - final int appId = UserHandle.getAppId(hasPermissionUids[j]); - netdPermsAppIds.put(appId, netdPermsAppIds.get(appId) | netdPermission); - } - } - log("Users: " + mUsers.size() + ", Apps: " + mApps.size()); - update(mUsers, mApps, true); - sendPackagePermissionsToNetd(netdPermsAppIds); + log("Users: " + mUsers.size() + ", UidToNetworkPerm: " + mUidToNetworkPerm.size()); } @VisibleForTesting synchronized void updateUidsAllowedOnRestrictedNetworks(final Set uids) { mUidsAllowedOnRestrictedNetworks.clear(); - // This is necessary for the app id to match in isUidAllowedOnRestrictedNetworks, and will - // grant the permission to all uids associated with the app ID. This is safe even if the app - // is only installed on some users because the uid cannot match some other app – this uid is - // in effect not installed and can't be run. - // TODO (b/192431153): Change appIds back to uids. - for (int uid : uids) { - mUidsAllowedOnRestrictedNetworks.add(UserHandle.getAppId(uid)); - } + mUidsAllowedOnRestrictedNetworks.addAll(uids); } @VisibleForTesting @@ -324,7 +358,8 @@ public class PermissionMonitor { return (appInfo.targetSdkVersion < VERSION_Q && isVendorApp(appInfo)) // Backward compatibility for b/114245686, on devices that launched before Q daemons // and apps running as the system UID are exempted from this check. - || (appInfo.uid == SYSTEM_UID && mDeps.getDeviceFirstSdkInt() < VERSION_Q); + || (UserHandle.getAppId(appInfo.uid) == SYSTEM_APPID + && mDeps.getDeviceFirstSdkInt() < VERSION_Q); } @VisibleForTesting @@ -332,7 +367,7 @@ public class PermissionMonitor { if (appInfo == null) return false; // Check whether package's uid is in allowed on restricted networks uid list. If so, this // uid can have netd system permission. - return mUidsAllowedOnRestrictedNetworks.contains(UserHandle.getAppId(appInfo.uid)); + return mUidsAllowedOnRestrictedNetworks.contains(appInfo.uid); } @VisibleForTesting @@ -365,33 +400,30 @@ public class PermissionMonitor { public synchronized boolean hasUseBackgroundNetworksPermission(final int uid) { // Apps with any of the CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_INTERNAL or // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission has the permission to use background - // networks. mApps contains the result of checks for both hasNetworkPermission and - // hasRestrictedNetworkPermission. If uid is in the mApps list that means uid has one of - // permissions at least. - return mApps.get(UserHandle.getAppId(uid), PERMISSION_NONE) != PERMISSION_NONE; + // networks. mUidToNetworkPerm contains the result of checks for hasNetworkPermission and + // hasRestrictedNetworkPermission, as well as the list of UIDs allowed on restricted + // networks. If uid is in the mUidToNetworkPerm list that means uid has one of permissions + // at least. + return mUidToNetworkPerm.get(uid, PERMISSION_NONE) != PERMISSION_NONE; } /** * Returns whether the given uid has permission to use restricted networks. */ public synchronized boolean hasRestrictedNetworksPermission(int uid) { - return PERMISSION_SYSTEM == mApps.get(UserHandle.getAppId(uid), PERMISSION_NONE); + return PERMISSION_SYSTEM == mUidToNetworkPerm.get(uid, PERMISSION_NONE); } - private void update(Set users, SparseIntArray apps, boolean add) { + private void sendUidsNetworkPermission(SparseIntArray uids, boolean add) { List network = new ArrayList<>(); List system = new ArrayList<>(); - for (int i = 0; i < apps.size(); i++) { - final int permission = apps.valueAt(i); + for (int i = 0; i < uids.size(); i++) { + final int permission = uids.valueAt(i); if (PERMISSION_NONE == permission) { continue; // Normally NONE is not stored in this map, but just in case } List list = (PERMISSION_SYSTEM == permission) ? system : network; - for (UserHandle user : users) { - if (user == null) continue; - - list.add(user.getUid(apps.keyAt(i))); - } + list.add(uids.keyAt(i)); } try { if (add) { @@ -415,7 +447,19 @@ public class PermissionMonitor { */ public synchronized void onUserAdded(@NonNull UserHandle user) { mUsers.add(user); - update(Set.of(user), mApps, true); + + final List apps = getInstalledPackagesAsUser(user); + + // Save all apps + updateAllApps(apps); + + // Uids network permissions + final SparseIntArray uids = makeUidsNetworkPerm(apps); + updateUidsNetworkPermission(uids); + + // App ids traffic permission + final SparseIntArray appIds = makeAppIdsTrafficPerm(apps); + updateAppIdsTrafficPermission(appIds, getSystemTrafficPerm()); } /** @@ -427,44 +471,54 @@ public class PermissionMonitor { */ public synchronized void onUserRemoved(@NonNull UserHandle user) { mUsers.remove(user); - update(Set.of(user), mApps, false); + + final SparseIntArray removedUids = new SparseIntArray(); + final SparseIntArray allUids = mUidToNetworkPerm.clone(); + for (int i = 0; i < allUids.size(); i++) { + final int uid = allUids.keyAt(i); + if (user.equals(UserHandle.getUserHandleForUid(uid))) { + mUidToNetworkPerm.delete(uid); + removedUids.put(uid, allUids.valueAt(i)); + } + } + sendUidsNetworkPermission(removedUids, false /* add */); } /** * Compare the current network permission and the given package's permission to find out highest * permission for the uid. * + * @param uid The target uid * @param currentPermission Current uid network permission * @param name The package has same uid that need compare its permission to update uid network * permission. */ @VisibleForTesting - protected int highestPermissionForUid(int currentPermission, String name) { + protected int highestPermissionForUid(int uid, int currentPermission, String name) { + // If multiple packages share a UID (cf: android:sharedUserId) and ask for different + // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). if (currentPermission == PERMISSION_SYSTEM) { return currentPermission; } - try { - final PackageInfo app = mPackageManager.getPackageInfo(name, - GET_PERMISSIONS | MATCH_ANY_USER); - final int permission = getPackageNetdNetworkPermission(app); - if (isHigherNetworkPermission(permission, currentPermission)) { - return permission; - } - } catch (NameNotFoundException e) { - // App not found. - loge("NameNotFoundException " + name); + final PackageInfo app = getPackageInfoAsUser(name, UserHandle.getUserHandleForUid(uid)); + if (app == null) return currentPermission; + + final int permission = getPackageNetdNetworkPermission(app); + if (isHigherNetworkPermission(permission, currentPermission)) { + return permission; } return currentPermission; } - private int getPermissionForUid(final int uid) { + private int getTrafficPermissionForUid(final int uid) { int permission = PERMISSION_NONE; // Check all the packages for this UID. The UID has the permission if any of the // packages in it has the permission. final String[] packages = mPackageManager.getPackagesForUid(uid); if (packages != null && packages.length > 0) { for (String name : packages) { - final PackageInfo app = getPackageInfo(name); + final PackageInfo app = getPackageInfoAsUser(name, + UserHandle.getUserHandleForUid(uid)); if (app != null && app.requestedPermissions != null) { permission |= getNetdPermissionMask(app.requestedPermissions, app.requestedPermissionsFlags); @@ -524,24 +578,23 @@ public class PermissionMonitor { */ public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) { final int appId = UserHandle.getAppId(uid); - final int trafficPerm = getPermissionForUid(uid); + final int trafficPerm = getTrafficPermissionForUid(uid); sendPackagePermissionsForAppId(appId, trafficPerm); - // If multiple packages share a UID (cf: android:sharedUserId) and ask for different - // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is). - final int currentPermission = mApps.get(appId, PERMISSION_NONE); - final int permission = highestPermissionForUid(currentPermission, packageName); + final int currentPermission = mUidToNetworkPerm.get(uid, PERMISSION_NONE); + final int permission = highestPermissionForUid(uid, currentPermission, packageName); if (permission != currentPermission) { - mApps.put(appId, permission); + mUidToNetworkPerm.put(uid, permission); SparseIntArray apps = new SparseIntArray(); - apps.put(appId, permission); - update(mUsers, apps, true); + apps.put(uid, permission); + sendUidsNetworkPermission(apps, true /* add */); } // If the newly-installed package falls within some VPN's uid range, update Netd with it. - // This needs to happen after the mApps update above, since removeBypassingUids() in - // updateVpnUid() depends on mApps to check if the package can bypass VPN. + // This needs to happen after the mUidToNetworkPerm update above, since + // removeBypassingUids() in updateVpnUid() depends on mUidToNetworkPerm to check if the + // package can bypass VPN. updateVpnUid(uid, true /* add */); mAllApps.add(appId); mPermissionUpdateLogs.log("Package add: name=" + packageName + ", uid=" + uid @@ -557,7 +610,7 @@ public class PermissionMonitor { for (String name : packages) { // If multiple packages have the same UID, give the UID all permissions that // any package in that UID has. - permission = highestPermissionForUid(permission, name); + permission = highestPermissionForUid(uid, permission, name); if (permission == PERMISSION_SYSTEM) { break; } @@ -576,19 +629,20 @@ public class PermissionMonitor { */ public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) { final int appId = UserHandle.getAppId(uid); - final int trafficPerm = getPermissionForUid(uid); + final int trafficPerm = getTrafficPermissionForUid(uid); sendPackagePermissionsForAppId(appId, trafficPerm); // If the newly-removed package falls within some VPN's uid range, update Netd with it. - // This needs to happen before the mApps update below, since removeBypassingUids() in - // updateVpnUid() depends on mApps to check if the package can bypass VPN. + // This needs to happen before the mUidToNetworkPerm update below, since + // removeBypassingUids() in updateVpnUid() depends on mUidToNetworkPerm to check if the + // package can bypass VPN. updateVpnUid(uid, false /* add */); // If the package has been removed from all users on the device, clear it form mAllApps. if (mPackageManager.getNameForUid(uid) == null) { mAllApps.remove(appId); } - final int currentPermission = mApps.get(appId, PERMISSION_NONE); + final int currentPermission = mUidToNetworkPerm.get(uid, PERMISSION_NONE); final int permission = highestUidNetworkPermission(uid); mPermissionUpdateLogs.log("Package remove: name=" + packageName + ", uid=" + uid + ", nPerm=(" + permissionToString(permission) + "/" @@ -605,19 +659,19 @@ public class PermissionMonitor { final SparseIntArray apps = new SparseIntArray(); if (permission != PERMISSION_NONE) { - mApps.put(appId, permission); - apps.put(appId, permission); - update(mUsers, apps, true); + mUidToNetworkPerm.put(uid, permission); + apps.put(uid, permission); + sendUidsNetworkPermission(apps, true); } else { - mApps.delete(appId); - apps.put(appId, PERMISSION_NETWORK); // doesn't matter which permission we pick here - update(mUsers, apps, false); + mUidToNetworkPerm.delete(uid); + apps.put(uid, PERMISSION_NETWORK); // doesn't matter which permission we pick here + sendUidsNetworkPermission(apps, false); } } private static int getNetdPermissionMask(String[] requestedPermissions, int[] requestedPermissionsFlags) { - int permissions = 0; + int permissions = PERMISSION_NONE; if (requestedPermissions == null || requestedPermissionsFlags == null) return permissions; for (int i = 0; i < requestedPermissions.length; i++) { if (requestedPermissions[i].equals(INTERNET) @@ -632,12 +686,23 @@ public class PermissionMonitor { return permissions; } - private PackageInfo getPackageInfo(String packageName) { + private synchronized PackageManager getPackageManagerAsUser(UserHandle user) { + PackageManager pm = mUsersPackageManager.get(user); + if (pm == null) { + pm = mContext.createContextAsUser(user, 0 /* flag */).getPackageManager(); + mUsersPackageManager.put(user, pm); + } + return pm; + } + + private PackageInfo getPackageInfoAsUser(String packageName, UserHandle user) { try { - PackageInfo app = mPackageManager.getPackageInfo(packageName, GET_PERMISSIONS - | MATCH_ANY_USER); - return app; + final PackageInfo info = getPackageManagerAsUser(user) + .getPackageInfo(packageName, GET_PERMISSIONS); + return info; } catch (NameNotFoundException e) { + // App not found. + loge("NameNotFoundException " + packageName); return null; } } @@ -725,8 +790,7 @@ public class PermissionMonitor { */ private void removeBypassingUids(Set uids, int vpnAppUid) { uids.remove(vpnAppUid); - uids.removeIf(uid -> - mApps.get(UserHandle.getAppId(uid), PERMISSION_NONE) == PERMISSION_SYSTEM); + uids.removeIf(uid -> mUidToNetworkPerm.get(uid, PERMISSION_NONE) == PERMISSION_SYSTEM); } /** @@ -773,7 +837,7 @@ public class PermissionMonitor { void sendPackagePermissionsForAppId(int appId, int permissions) { SparseIntArray netdPermissionsAppIds = new SparseIntArray(); netdPermissionsAppIds.put(appId, permissions); - sendPackagePermissionsToNetd(netdPermissionsAppIds); + sendAppIdsTrafficPermission(netdPermissionsAppIds); } /** @@ -785,16 +849,16 @@ public class PermissionMonitor { * @hide */ @VisibleForTesting - void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) { + void sendAppIdsTrafficPermission(SparseIntArray netdPermissionsAppIds) { if (mNetd == null) { Log.e(TAG, "Failed to get the netd service"); return; } - ArrayList allPermissionAppIds = new ArrayList<>(); - ArrayList internetPermissionAppIds = new ArrayList<>(); - ArrayList updateStatsPermissionAppIds = new ArrayList<>(); - ArrayList noPermissionAppIds = new ArrayList<>(); - ArrayList uninstalledAppIds = new ArrayList<>(); + final ArrayList allPermissionAppIds = new ArrayList<>(); + final ArrayList internetPermissionAppIds = new ArrayList<>(); + final ArrayList updateStatsPermissionAppIds = new ArrayList<>(); + final ArrayList noPermissionAppIds = new ArrayList<>(); + final ArrayList uninstalledAppIds = new ArrayList<>(); for (int i = 0; i < netdPermissionsAppIds.size(); i++) { int permissions = netdPermissionsAppIds.valueAt(i); switch(permissions) { @@ -865,20 +929,19 @@ public class PermissionMonitor { for (Integer uid : uidsToUpdate) { final int permission = highestUidNetworkPermission(uid); - final int appId = UserHandle.getAppId(uid); if (PERMISSION_NONE == permission) { // Doesn't matter which permission is set here. - removedUids.put(appId, PERMISSION_NETWORK); - mApps.delete(appId); + removedUids.put(uid, PERMISSION_NETWORK); + mUidToNetworkPerm.delete(uid); } else { - updatedUids.put(appId, permission); - mApps.put(appId, permission); + updatedUids.put(uid, permission); + mUidToNetworkPerm.put(uid, permission); } } // Step3. Update or revoke permission for uids with netd. - update(mUsers, updatedUids, true /* add */); - update(mUsers, removedUids, false /* add */); + sendUidsNetworkPermission(updatedUids, true /* add */); + sendUidsNetworkPermission(removedUids, false /* add */); mPermissionUpdateLogs.log("Setting change: update=" + updatedUids + ", remove=" + removedUids); } @@ -890,11 +953,13 @@ public class PermissionMonitor { } for (String app : pkgList) { - final PackageInfo info = getPackageInfo(app); - if (info == null || info.applicationInfo == null) continue; + for (UserHandle user : mUsers) { + final PackageInfo info = getPackageInfoAsUser(app, user); + if (info == null || info.applicationInfo == null) continue; - final int appId = info.applicationInfo.uid; - onPackageAdded(app, appId); // Use onPackageAdded to add package one by one. + final int uid = info.applicationInfo.uid; + onPackageAdded(app, uid); // Use onPackageAdded to add package one by one. + } } } diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 5493e9bb4c..044ff0204b 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -38,7 +38,6 @@ import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageManager.FEATURE_WIFI; import static android.content.pm.PackageManager.FEATURE_WIFI_DIRECT; import static android.content.pm.PackageManager.GET_PERMISSIONS; -import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN; @@ -2006,7 +2005,7 @@ public class ConnectivityServiceTest { buildPackageInfo(/* SYSTEM */ false, APP1_UID), buildPackageInfo(/* SYSTEM */ false, APP2_UID), buildPackageInfo(/* SYSTEM */ false, VPN_UID) - })).when(mPackageManager).getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER)); + })).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); // Create a fake always-on VPN package. final int userId = UserHandle.getCallingUserId(); @@ -3334,7 +3333,7 @@ public class ConnectivityServiceTest { private void grantUsingBackgroundNetworksPermissionForUid( final int uid, final String packageName) throws Exception { doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager) - .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS | MATCH_ANY_USER)); + .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS)); mService.mPermissionMonitor.onPackageAdded(packageName, uid); } diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java index ecda338b49..99ef80b616 100644 --- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -60,6 +60,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -118,10 +119,13 @@ public class PermissionMonitorTest { private static final int SYSTEM_APPID1 = 1100; private static final int SYSTEM_APPID2 = 1108; private static final int VPN_APPID = 10002; - private static final int MOCK_UID1 = MOCK_USER1.getUid(MOCK_APPID1); - private static final int MOCK_UID2 = MOCK_USER1.getUid(MOCK_APPID2); - private static final int SYSTEM_APP_UID1 = MOCK_USER1.getUid(SYSTEM_APPID1); + private static final int MOCK_UID11 = MOCK_USER1.getUid(MOCK_APPID1); + private static final int MOCK_UID12 = MOCK_USER1.getUid(MOCK_APPID2); + private static final int SYSTEM_APP_UID11 = MOCK_USER1.getUid(SYSTEM_APPID1); private static final int VPN_UID = MOCK_USER1.getUid(VPN_APPID); + private static final int MOCK_UID21 = MOCK_USER2.getUid(MOCK_APPID1); + private static final int MOCK_UID22 = MOCK_USER2.getUid(MOCK_APPID2); + private static final int SYSTEM_APP_UID21 = MOCK_USER2.getUid(SYSTEM_APPID1); private static final String REAL_SYSTEM_PACKAGE_NAME = "android"; private static final String MOCK_PACKAGE1 = "appName1"; private static final String MOCK_PACKAGE2 = "appName2"; @@ -161,9 +165,13 @@ public class PermissionMonitorTest { doCallRealMethod().when(mContext).getSystemService(SystemConfigManager.class); } when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]); - final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); - doReturn(UserHandle.ALL).when(asUserCtx).getUser(); - when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx); + doAnswer(invocation -> { + final Object[] args = invocation.getArguments(); + final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); + final UserHandle user = (UserHandle) args[0]; + doReturn(user).when(asUserCtx).getUser(); + return asUserCtx; + }).when(mContext).createContextAsUser(any(), anyInt()); when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of()); // Set DEVICE_INITIAL_SDK_INT to Q that SYSTEM_UID won't have restricted network permission // by default. @@ -172,7 +180,7 @@ public class PermissionMonitorTest { mPermissionMonitor = new PermissionMonitor(mContext, mNetdService, mDeps); mNetdMonitor = new NetdMonitor(mNetdService); - doReturn(List.of()).when(mPackageManager).getInstalledPackages(anyInt()); + doReturn(List.of()).when(mPackageManager).getInstalledPackagesAsUser(anyInt(), anyInt()); } private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, @@ -330,26 +338,26 @@ public class PermissionMonitorTest { @Test public void testHasRestrictedNetworkPermission() { assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1)); + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE)); + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, NETWORK_STACK)); + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, NETWORK_STACK)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CHANGE_WIFI_STATE)); + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_WIFI_STATE)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, + PARTITION_SYSTEM, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, PERMISSION_MAINLINE_NETWORK_STACK)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1)); + PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); + PARTITION_SYSTEM, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL)); } @Test @@ -376,43 +384,43 @@ public class PermissionMonitorTest { @Test public void testHasRestrictedNetworkPermissionVendorApp() { assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1)); + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE)); + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, NETWORK_STACK)); + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, NETWORK_STACK)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID1, CHANGE_WIFI_STATE)); + PARTITION_VENDOR, VERSION_P, MOCK_PACKAGE1, MOCK_UID11, CHANGE_WIFI_STATE)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE)); } @Test public void testHasRestrictedNetworkPermissionUidAllowedOnRestrictedNetworks() { - mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID1)); + mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID11)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE)); assertTrue(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_INTERNAL)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2, CHANGE_NETWORK_STATE)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE)); assertFalse(hasRestrictedNetworkPermission( - PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2, CONNECTIVITY_INTERNAL)); + PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID12, CONNECTIVITY_INTERNAL)); } @@ -429,27 +437,27 @@ public class PermissionMonitorTest { doReturn(VERSION_P).when(mDeps).getDeviceFirstSdkInt(); assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID)); assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID)); - assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1)); - assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1)); + assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID11)); + assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID11)); assertTrue(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID)); assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID)); - assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1)); - assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1)); + assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID11)); + assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID11)); doReturn(VERSION_Q).when(mDeps).getDeviceFirstSdkInt(); assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID)); assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, SYSTEM_UID)); - assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID1)); - assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID1)); + assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_P, MOCK_UID11)); + assertTrue(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_P, MOCK_UID11)); assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID)); assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, SYSTEM_UID)); - assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1)); - assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID1)); + assertFalse(wouldBeCarryoverPackage(PARTITION_SYSTEM, VERSION_Q, MOCK_UID11)); + assertFalse(wouldBeCarryoverPackage(PARTITION_VENDOR, VERSION_Q, MOCK_UID11)); assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, SYSTEM_UID)); assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, SYSTEM_UID)); - assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID1)); - assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1)); + assertFalse(wouldBeCarryoverPackage(PARTITION_OEM, VERSION_Q, MOCK_UID11)); + assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID11)); } private boolean wouldBeUidAllowedOnRestrictedNetworks(int uid) { @@ -461,20 +469,20 @@ public class PermissionMonitorTest { @Test public void testIsAppAllowedOnRestrictedNetworks() { mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of()); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1)); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12)); - mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID1)); - assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1)); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2)); + mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID11)); + assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12)); - mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID2)); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1)); - assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2)); + mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(MOCK_UID12)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11)); + assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12)); mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(Set.of(123)); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1)); - assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID11)); + assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID12)); } private void assertBackgroundPermission(boolean hasPermission, String name, int uid, @@ -491,16 +499,16 @@ public class PermissionMonitorTest { assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE); assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK); - assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1)); - assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1); - assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1, + assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID11)); + assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID11); + assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS); - assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2)); - assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2); - assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2, + assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID12)); + assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID12); + assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID12, CONNECTIVITY_INTERNAL); - assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK); + assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID12, NETWORK_STACK); } private class NetdMonitor { @@ -589,13 +597,13 @@ public class PermissionMonitorTest { @Test public void testUserAndPackageAddRemove() throws Exception { - // MOCK_UID1: MOCK_PACKAGE1 only has network permission. - // SYSTEM_APP_UID1: SYSTEM_PACKAGE1 has system permission. - // SYSTEM_APP_UID1: SYSTEM_PACKAGE2 only has network permission. - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE); - buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE1, SYSTEM_APP_UID1, + // MOCK_UID11: MOCK_PACKAGE1 only has network permission. + // SYSTEM_APP_UID11: SYSTEM_PACKAGE1 has system permission. + // SYSTEM_APP_UID11: SYSTEM_PACKAGE2 only has network permission. + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE); + buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS); - buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE2, SYSTEM_APP_UID1, + buildAndMockPackageInfoWithPermissions(SYSTEM_PACKAGE2, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE); // Add user MOCK_USER1. @@ -610,16 +618,19 @@ public class PermissionMonitorTest { mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, SYSTEM_APPID1); + final List pkgs = List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID21, + CONNECTIVITY_USE_RESTRICTED_NETWORKS), + buildPackageInfo(SYSTEM_PACKAGE2, SYSTEM_APP_UID21, CHANGE_NETWORK_STATE)); + doReturn(pkgs).when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), + eq(MOCK_USER_ID2)); // Add user MOCK_USER2. mPermissionMonitor.onUserAdded(MOCK_USER2); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_APPID1); // Remove SYSTEM_PACKAGE2, expect keep system permission. - when(mPackageManager.getPackagesForUid(SYSTEM_APP_UID1)) - .thenReturn(new String[]{SYSTEM_PACKAGE1}); - when(mPackageManager.getPackagesForUid(MOCK_USER2.getUid(SYSTEM_APPID1))) - .thenReturn(new String[]{SYSTEM_PACKAGE1}); + doReturn(new String[]{SYSTEM_PACKAGE1}).when(mPackageManager) + .getPackagesForUid(intThat(uid -> UserHandle.getAppId(uid) == SYSTEM_APPID1)); removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_APPID1); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, @@ -631,6 +642,8 @@ public class PermissionMonitorTest { mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_APPID1); + // Add MOCK_PACKAGE1 + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID21, CHANGE_NETWORK_STATE); addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, SYSTEM_APPID1); @@ -638,9 +651,8 @@ public class PermissionMonitorTest { MOCK_APPID1); // Remove MOCK_PACKAGE1, expect no permission left for all user. - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - when(mPackageManager.getPackagesForUid(MOCK_USER2.getUid(MOCK_APPID1))) - .thenReturn(new String[]{}); + doReturn(new String[]{}).when(mPackageManager) + .getPackagesForUid(intThat(uid -> UserHandle.getAppId(uid) == MOCK_APPID1)); removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID1); @@ -674,68 +686,71 @@ public class PermissionMonitorTest { @Test public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception { - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID1, CHANGE_NETWORK_STATE, - CONNECTIVITY_USE_RESTRICTED_NETWORKS), - buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1), - buildPackageInfo(MOCK_PACKAGE2, MOCK_UID2), - buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID))); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1); + doReturn(List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, + CONNECTIVITY_USE_RESTRICTED_NETWORKS), + buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11), + buildPackageInfo(MOCK_PACKAGE2, MOCK_UID12), + buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID))) + .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11); mPermissionMonitor.startMonitoring(); - // Every app on user 0 except MOCK_UID2 are under VPN. + // Every app on user 0 except MOCK_UID12 are under VPN. final Set vpnRange1 = Set.of( - new UidRange(0, MOCK_UID2 - 1), - new UidRange(MOCK_UID2 + 1, UserHandle.PER_USER_RANGE - 1)); - final Set vpnRange2 = Set.of(new UidRange(MOCK_UID2, MOCK_UID2)); + new UidRange(0, MOCK_UID12 - 1), + new UidRange(MOCK_UID12 + 1, UserHandle.PER_USER_RANGE - 1)); + final Set vpnRange2 = Set.of(new UidRange(MOCK_UID12, MOCK_UID12)); - // When VPN is connected, expect a rule to be set up for user app MOCK_UID1 + // When VPN is connected, expect a rule to be set up for user app MOCK_UID11 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange1, VPN_UID); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID1})); + verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID11})); reset(mNetdService); - // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[]{MOCK_UID1})); - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_UID1); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID1})); + // When MOCK_UID11 package is uninstalled and reinstalled, expect Netd to be updated + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); + verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[]{MOCK_UID11})); + mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_UID11); + verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID11})); reset(mNetdService); // During VPN uid update (vpnRange1 -> vpnRange2), ConnectivityService first deletes the // old UID rules then adds the new ones. Expect netd to be updated mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange1, VPN_UID); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); + verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID11})); mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange2, VPN_UID); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID2})); + verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID12})); reset(mNetdService); // When VPN is disconnected, expect rules to be torn down mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange2, VPN_UID); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID2})); + verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID12})); assertNull(mPermissionMonitor.getVpnUidRanges("tun0")); } @Test public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception { - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID1, CHANGE_NETWORK_STATE, - NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS), - buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID))); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1); + doReturn(List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, + NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS), + buildPackageInfo(SYSTEM_PACKAGE2, VPN_UID))) + .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11); mPermissionMonitor.startMonitoring(); - final Set vpnRange = Set.of(UidRange.createForUser(MOCK_USER1)); + final Set vpnRange = Set.of(UidRange.createForUser(MOCK_USER1), + UidRange.createForUser(MOCK_USER2)); mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID); // Newly-installed package should have uid rules added - mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, MOCK_UID1); - verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID1})); + addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_APPID1); + verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID11})); + verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"), aryEq(new int[]{MOCK_UID21})); // Removed package should have its uid rules removed - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); - verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1})); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); + verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[]{MOCK_UID11})); + verify(mNetdService, never()).firewallRemoveUidInterfaceRules(aryEq(new int[]{MOCK_UID21})); } @@ -767,7 +782,7 @@ public class PermissionMonitorTest { netdPermissionsAppIds.put(SYSTEM_APPID2, PERMISSION_UPDATE_DEVICE_STATS); // Send the permission information to netd, expect permission updated. - mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds); + mPermissionMonitor.sendAppIdsTrafficPermission(netdPermissionsAppIds); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID2); @@ -790,69 +805,69 @@ public class PermissionMonitorTest { @Test public void testPackageInstall() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET, UPDATE_DEVICE_STATS); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); - addPackage(MOCK_PACKAGE2, MOCK_UID2, INTERNET); + addPackage(MOCK_PACKAGE2, MOCK_UID12, INTERNET); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID2); } @Test public void testPackageInstallSharedUid() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET, UPDATE_DEVICE_STATS); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); // Install another package with the same uid and no permissions should not cause the app id // to lose permissions. - addPackage(MOCK_PACKAGE2, MOCK_UID1); + addPackage(MOCK_PACKAGE2, MOCK_UID11); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); } @Test public void testPackageUninstallBasic() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET, UPDATE_DEVICE_STATS); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{}); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1); } @Test public void testPackageRemoveThenAdd() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET, UPDATE_DEVICE_STATS); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{}); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1); - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); } @Test public void testPackageUpdate() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1); + addPackage(MOCK_PACKAGE1, MOCK_UID11); mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1); - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); } @Test public void testPackageUninstallWithMultiplePackages() throws Exception { - addPackage(MOCK_PACKAGE1, MOCK_UID1, INTERNET, UPDATE_DEVICE_STATS); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); // Install another package with the same uid but different permissions. - addPackage(MOCK_PACKAGE2, MOCK_UID1, INTERNET); - mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID1); + addPackage(MOCK_PACKAGE2, MOCK_UID11, INTERNET); + mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_UID11); // Uninstall MOCK_PACKAGE1 and expect only INTERNET permission left. - when(mPackageManager.getPackagesForUid(eq(MOCK_UID1))) + when(mPackageManager.getPackagesForUid(eq(MOCK_UID11))) .thenReturn(new String[]{MOCK_PACKAGE2}); - mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1); + mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); } @@ -871,9 +886,9 @@ public class PermissionMonitorTest { @Test public void testUpdateUidPermissionsFromSystemConfig() throws Exception { when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET))) - .thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 }); + .thenReturn(new int[]{ MOCK_UID11, MOCK_UID12 }); when(mSystemConfigManager.getSystemPermissionUids(eq(UPDATE_DEVICE_STATS))) - .thenReturn(new int[]{ MOCK_UID2 }); + .thenReturn(new int[]{ MOCK_UID12 }); mPermissionMonitor.startMonitoring(); mNetdMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); @@ -904,17 +919,17 @@ public class PermissionMonitorTest { // Verify receiving PACKAGE_ADDED intent. final Intent addedIntent = new Intent(Intent.ACTION_PACKAGE_ADDED, Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */)); - addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, INTERNET, + addedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID11); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); receiver.onReceive(mContext, addedIntent); mNetdMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); // Verify receiving PACKAGE_REMOVED intent. - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{}); + when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{}); final Intent removedIntent = new Intent(Intent.ACTION_PACKAGE_REMOVED, Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */)); - removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1); + removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID11); receiver.onReceive(mContext, removedIntent); mNetdMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1); } @@ -934,20 +949,20 @@ public class PermissionMonitorTest { Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)); // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2 - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12); - // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1 + // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11 // should have SYSTEM permission. - when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID1)); + when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11)); contentObserver.onChange(true /* selfChange */); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2); - // MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2 - // should have SYSTEM permission but MOCK_UID1 should revoke permission. - when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID2)); + // MOCK_UID12 is listed in setting that allow to use restricted networks, MOCK_UID12 + // should have SYSTEM permission but MOCK_UID11 should revoke permission. + when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID12)); contentObserver.onChange(true /* selfChange */); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_APPID2); @@ -965,29 +980,29 @@ public class PermissionMonitorTest { final ContentObserver contentObserver = expectRegisterContentObserver( Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID1); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11); - // MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID1 should have NETWORK permission. + // MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID11 should have NETWORK permission. addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_APPID1); mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); - // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1 + // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11 // should upgrade to SYSTEM permission. - when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID1)); + when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11)); contentObserver.onChange(true /* selfChange */); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); - // No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission. + // No app lists in setting, MOCK_UID11 should downgrade to NETWORK permission. when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of()); contentObserver.onChange(true /* selfChange */); mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); - // MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID1. - when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE2}); + // MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID11. + when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{MOCK_PACKAGE2}); removePackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_APPID1); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1); } @@ -998,33 +1013,39 @@ public class PermissionMonitorTest { final ContentObserver contentObserver = expectRegisterContentObserver( Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)); - // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2. - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2); + // Prepare PackageInfo for MOCK_APPID1 and MOCK_APPID2 in MOCK_USER1. + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12); - // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1 - // should have SYSTEM permission and MOCK_UID2 has no permissions. - when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID1)); + // MOCK_UID11 is listed in setting that allow to use restricted networks, MOCK_UID11 should + // have SYSTEM permission and MOCK_UID12 has no permissions. + when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID11)); contentObserver.onChange(true /* selfChange */); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2); // Add user MOCK_USER2. + final List pkgs = List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID21)); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID22); + doReturn(pkgs).when(mPackageManager) + .getInstalledPackagesAsUser(eq(GET_PERMISSIONS), eq(MOCK_USER_ID2)); mPermissionMonitor.onUserAdded(MOCK_USER2); - // MOCK_APPID1 in both users should all have SYSTEM permission and MOCK_APPID2 has no - // permissions in either user. - mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, + // MOCK_APPID1 in MOCK_USER1 should have SYSTEM permission but in MOCK_USER2 should have no + // permissions. And MOCK_APPID2 has no permissions in either users. + mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); + mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER2}, MOCK_APPID1); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID2); - // MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_APPID2 - // in both users should have SYSTEM permission and MOCK_APPID1 has no permissions in either - // user. - when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(Set.of(MOCK_UID2)); + // MOCK_UID22 is listed in setting that allow to use restricted networks, + // MOCK_APPID2 in MOCK_USER2 should have SYSTEM permission but in MOCK_USER1 should have no + // permissions. And MOCK_APPID1 has no permissions in either users. + doReturn(Set.of(MOCK_UID22)).when(mDeps).getUidsAllowedOnRestrictedNetworks(any()); contentObserver.onChange(true /* selfChange */); - mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2}, + mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER2}, MOCK_APPID2); + mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID2); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_APPID1); // Remove user MOCK_USER1 @@ -1044,9 +1065,9 @@ public class PermissionMonitorTest { public void testOnExternalApplicationsAvailable() throws Exception { // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external // and have different uids. There has no permission for both uids. - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1), - buildPackageInfo(MOCK_PACKAGE2, MOCK_UID2))); + doReturn(List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11), + buildPackageInfo(MOCK_PACKAGE2, MOCK_UID12))) + .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); mPermissionMonitor.startMonitoring(); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1, MOCK_APPID2); mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1, MOCK_APPID2); @@ -1057,9 +1078,9 @@ public class PermissionMonitorTest { final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST, new String[] { MOCK_PACKAGE1 , MOCK_PACKAGE2}); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS, INTERNET); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2, CHANGE_NETWORK_STATE, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE, UPDATE_DEVICE_STATS); receiver.onReceive(mContext, externalIntent); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1}, @@ -1079,9 +1100,9 @@ public class PermissionMonitorTest { // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external // and have different uids. There has no permission for both uids. - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS, INTERNET); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2, CHANGE_NETWORK_STATE, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID12, CHANGE_NETWORK_STATE, UPDATE_DEVICE_STATS); // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd. @@ -1101,10 +1122,10 @@ public class PermissionMonitorTest { public void testOnExternalApplicationsAvailableWithSharedUid() throws Exception { // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external - // storage and shared on MOCK_UID1. There has no permission for MOCK_UID1. - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1), - buildPackageInfo(MOCK_PACKAGE2, MOCK_UID1))); + // storage and shared on MOCK_UID11. There has no permission for MOCK_UID11. + doReturn(List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11), + buildPackageInfo(MOCK_PACKAGE2, MOCK_UID11))) + .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); mPermissionMonitor.startMonitoring(); mNetdMonitor.expectNoNetworkPerm(new UserHandle[]{MOCK_USER1}, MOCK_APPID1); mNetdMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1); @@ -1114,8 +1135,8 @@ public class PermissionMonitorTest { // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd. final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST, new String[] {MOCK_PACKAGE1}); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID1, UPDATE_DEVICE_STATS); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE); + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11, UPDATE_DEVICE_STATS); receiver.onReceive(mContext, externalIntent); mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); @@ -1126,12 +1147,11 @@ public class PermissionMonitorTest { public void testOnExternalApplicationsAvailableWithSharedUid_DifferentStorage() throws Exception { // Initial the permission state. MOCK_PACKAGE1 is installed on external storage and - // MOCK_PACKAGE2 is installed on device. These two packages are shared on MOCK_UID1. - // MOCK_UID1 has NETWORK and INTERNET permissions. - when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn( - List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID1), - buildPackageInfo(MOCK_PACKAGE2, MOCK_UID1, CHANGE_NETWORK_STATE, - INTERNET))); + // MOCK_PACKAGE2 is installed on device. These two packages are shared on MOCK_UID11. + // MOCK_UID11 has NETWORK and INTERNET permissions. + doReturn(List.of(buildPackageInfo(MOCK_PACKAGE1, MOCK_UID11), + buildPackageInfo(MOCK_PACKAGE2, MOCK_UID11, CHANGE_NETWORK_STATE, INTERNET))) + .when(mPackageManager).getInstalledPackagesAsUser(eq(GET_PERMISSIONS), anyInt()); mPermissionMonitor.startMonitoring(); mNetdMonitor.expectNetworkPerm(PERMISSION_NETWORK, new UserHandle[]{MOCK_USER1}, MOCK_APPID1); @@ -1142,9 +1162,9 @@ public class PermissionMonitorTest { // Verify receiving EXTERNAL_APPLICATIONS_AVAILABLE intent and update permission to netd. final Intent externalIntent = new Intent(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); externalIntent.putExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST, new String[] {MOCK_PACKAGE1}); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID11, CONNECTIVITY_USE_RESTRICTED_NETWORKS, UPDATE_DEVICE_STATS); - buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID1, CHANGE_NETWORK_STATE, + buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID11, CHANGE_NETWORK_STATE, INTERNET); receiver.onReceive(mContext, externalIntent); mNetdMonitor.expectNetworkPerm(PERMISSION_SYSTEM, new UserHandle[]{MOCK_USER1},