Update allowed on restricted networks getter/setter

As API review feedback, setting allowed on restricted networks
should be by uid instead of package name for security reason.
Thus, update the getter/setter to return/accept set of uids.

Bug: 188085693
Test: atest FrameworksNetTests
Ignore-AOSP-First: Needs cherry-picks
Change-Id: I979bf98075e6c9c0ed7e891582843fddb62643cb
This commit is contained in:
paulhu
2021-05-26 16:16:57 +08:00
parent 58b943a701
commit 68aacb407a
4 changed files with 130 additions and 136 deletions

View File

@@ -48,7 +48,6 @@ package android.net {
public class ConnectivitySettingsManager { public class ConnectivitySettingsManager {
method public static void clearGlobalProxy(@NonNull android.content.Context); method public static void clearGlobalProxy(@NonNull android.content.Context);
method @NonNull public static java.util.Set<java.lang.String> getAppsAllowedOnRestrictedNetworks(@NonNull android.content.Context);
method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context); method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
method public static int getCaptivePortalMode(@NonNull android.content.Context, int); method public static int getCaptivePortalMode(@NonNull android.content.Context, int);
method @NonNull public static java.time.Duration getConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration); method @NonNull public static java.time.Duration getConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
@@ -66,9 +65,9 @@ package android.net {
method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context); method @NonNull public static String getPrivateDnsDefaultMode(@NonNull android.content.Context);
method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context); method @Nullable public static String getPrivateDnsHostname(@NonNull android.content.Context);
method public static int getPrivateDnsMode(@NonNull android.content.Context); method public static int getPrivateDnsMode(@NonNull android.content.Context);
method @NonNull public static java.util.Set<java.lang.Integer> getUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context);
method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean); method public static boolean getWifiAlwaysRequested(@NonNull android.content.Context, boolean);
method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method @NonNull public static java.time.Duration getWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
method public static void setAppsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.String>);
method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String); method public static void setCaptivePortalHttpUrl(@NonNull android.content.Context, @Nullable String);
method public static void setCaptivePortalMode(@NonNull android.content.Context, int); method public static void setCaptivePortalMode(@NonNull android.content.Context, int);
method public static void setConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setConnectivityKeepPendingIntentDuration(@NonNull android.content.Context, @NonNull java.time.Duration);
@@ -86,6 +85,7 @@ package android.net {
method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int); method public static void setPrivateDnsDefaultMode(@NonNull android.content.Context, @NonNull int);
method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String); method public static void setPrivateDnsHostname(@NonNull android.content.Context, @Nullable String);
method public static void setPrivateDnsMode(@NonNull android.content.Context, int); method public static void setPrivateDnsMode(@NonNull android.content.Context, int);
method public static void setUidsAllowedOnRestrictedNetworks(@NonNull android.content.Context, @NonNull java.util.Set<java.lang.Integer>);
method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean); method public static void setWifiAlwaysRequested(@NonNull android.content.Context, boolean);
method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration); method public static void setWifiDataActivityTimeout(@NonNull android.content.Context, @NonNull java.time.Duration);
field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2 field public static final int CAPTIVE_PORTAL_MODE_AVOID = 2; // 0x2

View File

@@ -374,12 +374,12 @@ public class ConnectivitySettingsManager {
private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname"; private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME_STRING = "hostname";
/** /**
* A list of apps that is allowed on restricted networks. * A list of uids that is allowed to use restricted networks.
* *
* @hide * @hide
*/ */
public static final String APPS_ALLOWED_ON_RESTRICTED_NETWORKS = public static final String UIDS_ALLOWED_ON_RESTRICTED_NETWORKS =
"apps_allowed_on_restricted_networks"; "uids_allowed_on_restricted_networks";
/** /**
* Get mobile data activity timeout from {@link Settings}. * Get mobile data activity timeout from {@link Settings}.
@@ -1003,6 +1003,28 @@ public class ConnectivitySettingsManager {
context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE, preference); context.getContentResolver(), NETWORK_METERED_MULTIPATH_PREFERENCE, preference);
} }
private static Set<Integer> getUidSetFromString(@Nullable String uidList) {
final Set<Integer> uids = new ArraySet<>();
if (TextUtils.isEmpty(uidList)) {
return uids;
}
for (String uid : uidList.split(";")) {
uids.add(Integer.valueOf(uid));
}
return uids;
}
private static String getUidStringFromSet(@NonNull Set<Integer> uidList) {
final StringJoiner joiner = new StringJoiner(";");
for (Integer uid : uidList) {
if (uid < 0 || UserHandle.getAppId(uid) > Process.LAST_APPLICATION_UID) {
throw new IllegalArgumentException("Invalid uid");
}
joiner.add(uid.toString());
}
return joiner.toString();
}
/** /**
* Get the list of uids(from {@link Settings}) that should go on cellular networks in preference * Get the list of uids(from {@link Settings}) that should go on cellular networks in preference
* even when higher-priority networks are connected. * even when higher-priority networks are connected.
@@ -1015,14 +1037,7 @@ public class ConnectivitySettingsManager {
public static Set<Integer> getMobileDataPreferredUids(@NonNull Context context) { public static Set<Integer> getMobileDataPreferredUids(@NonNull Context context) {
final String uidList = Settings.Secure.getString( final String uidList = Settings.Secure.getString(
context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS); context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS);
final Set<Integer> uids = new ArraySet<>(); return getUidSetFromString(uidList);
if (TextUtils.isEmpty(uidList)) {
return uids;
}
for (String uid : uidList.split(";")) {
uids.add(Integer.valueOf(uid));
}
return uids;
} }
/** /**
@@ -1035,53 +1050,41 @@ public class ConnectivitySettingsManager {
*/ */
public static void setMobileDataPreferredUids(@NonNull Context context, public static void setMobileDataPreferredUids(@NonNull Context context,
@NonNull Set<Integer> uidList) { @NonNull Set<Integer> uidList) {
final StringJoiner joiner = new StringJoiner(";"); final String uids = getUidStringFromSet(uidList);
for (Integer uid : uidList) { Settings.Secure.putString(context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS, uids);
if (uid < 0 || UserHandle.getAppId(uid) > Process.LAST_APPLICATION_UID) {
throw new IllegalArgumentException("Invalid uid");
}
joiner.add(uid.toString());
}
Settings.Secure.putString(
context.getContentResolver(), MOBILE_DATA_PREFERRED_UIDS, joiner.toString());
} }
/** /**
* Get the list of apps(from {@link Settings}) that is allowed on restricted networks. * Get the list of uids (from {@link Settings}) allowed to use restricted networks.
*
* Access to restricted networks is controlled by the (preinstalled-only)
* CONNECTIVITY_USE_RESTRICTED_NETWORKS permission, but highly privileged
* callers can also set a list of uids that can access restricted networks.
*
* This is useful for example in some jurisdictions where government apps,
* that can't be preinstalled, must still have access to emergency services.
* *
* @param context The {@link Context} to query the setting. * @param context The {@link Context} to query the setting.
* @return A list of apps that is allowed on restricted networks or null if no setting * @return A list of uids that is allowed to use restricted networks or null if no setting
* value. * value.
*/ */
@NonNull @NonNull
public static Set<String> getAppsAllowedOnRestrictedNetworks(@NonNull Context context) { public static Set<Integer> getUidsAllowedOnRestrictedNetworks(@NonNull Context context) {
final String appList = Settings.Secure.getString( final String uidList = Settings.Secure.getString(
context.getContentResolver(), APPS_ALLOWED_ON_RESTRICTED_NETWORKS); context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS);
if (TextUtils.isEmpty(appList)) { return getUidSetFromString(uidList);
return new ArraySet<>();
}
return new ArraySet<>(appList.split(";"));
} }
/** /**
* Set the list of apps(from {@link Settings}) that is allowed on restricted networks. * Set the list of uids(from {@link Settings}) that is allowed to use restricted networks.
*
* Note: Please refer to android developer guidelines for valid app(package name).
* https://developer.android.com/guide/topics/manifest/manifest-element.html#package
* *
* @param context The {@link Context} to set the setting. * @param context The {@link Context} to set the setting.
* @param list A list of apps that is allowed on restricted networks. * @param uidList A list of uids that is allowed to use restricted networks.
*/ */
public static void setAppsAllowedOnRestrictedNetworks(@NonNull Context context, public static void setUidsAllowedOnRestrictedNetworks(@NonNull Context context,
@NonNull Set<String> list) { @NonNull Set<Integer> uidList) {
final StringJoiner joiner = new StringJoiner(";"); final String uids = getUidStringFromSet(uidList);
for (String app : list) { Settings.Secure.putString(context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS,
if (app == null || app.contains(";")) { uids);
throw new IllegalArgumentException("Invalid app(package name)");
}
joiner.add(app);
}
Settings.Secure.putString(context.getContentResolver(), APPS_ALLOWED_ON_RESTRICTED_NETWORKS,
joiner.toString());
} }
} }

View File

@@ -24,7 +24,7 @@ import static android.Manifest.permission.UPDATE_DEVICE_STATS;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivitySettingsManager.APPS_ALLOWED_ON_RESTRICTED_NETWORKS; import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.INVALID_UID; import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID; import static android.os.Process.SYSTEM_UID;
@@ -109,13 +109,13 @@ public class PermissionMonitor {
@GuardedBy("this") @GuardedBy("this")
private final Set<Integer> mAllApps = new HashSet<>(); private final Set<Integer> mAllApps = new HashSet<>();
// A set of apps which are allowed to use restricted networks. These apps can't hold the // A set of uids which are allowed to use restricted networks. The packages of these uids can't
// CONNECTIVITY_USE_RESTRICTED_NETWORKS permission because they can't be signature|privileged // hold the CONNECTIVITY_USE_RESTRICTED_NETWORKS permission because they can't be
// apps. However, these apps should still be able to use restricted networks under certain // signature|privileged apps. However, these apps should still be able to use restricted
// conditions (e.g. government app using emergency services). So grant netd system permission // networks under certain conditions (e.g. government app using emergency services). So grant
// to uids whose package name is listed in APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting. // netd system permission to these uids which is listed in UIDS_ALLOWED_ON_RESTRICTED_NETWORKS.
@GuardedBy("this") @GuardedBy("this")
private final Set<String> mAppsAllowedOnRestrictedNetworks = new ArraySet<>(); private final Set<Integer> mUidsAllowedOnRestrictedNetworks = new ArraySet<>();
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override @Override
@@ -149,10 +149,10 @@ public class PermissionMonitor {
} }
/** /**
* Get apps allowed to use restricted networks via ConnectivitySettingsManager. * Get uids allowed to use restricted networks via ConnectivitySettingsManager.
*/ */
public Set<String> getAppsAllowedOnRestrictedNetworks(@NonNull Context context) { public Set<Integer> getUidsAllowedOnRestrictedNetworks(@NonNull Context context) {
return ConnectivitySettingsManager.getAppsAllowedOnRestrictedNetworks(context); return ConnectivitySettingsManager.getUidsAllowedOnRestrictedNetworks(context);
} }
/** /**
@@ -194,10 +194,10 @@ public class PermissionMonitor {
mIntentReceiver, intentFilter, null /* broadcastPermission */, mIntentReceiver, intentFilter, null /* broadcastPermission */,
null /* scheduler */); null /* scheduler */);
// Register APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting observer // Register UIDS_ALLOWED_ON_RESTRICTED_NETWORKS setting observer
mDeps.registerContentObserver( mDeps.registerContentObserver(
userAllContext, userAllContext,
Settings.Secure.getUriFor(APPS_ALLOWED_ON_RESTRICTED_NETWORKS), Settings.Secure.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS),
false /* notifyForDescendants */, false /* notifyForDescendants */,
new ContentObserver(null) { new ContentObserver(null) {
@Override @Override
@@ -206,9 +206,9 @@ public class PermissionMonitor {
} }
}); });
// Read APPS_ALLOWED_ON_RESTRICTED_NETWORKS setting and update // Read UIDS_ALLOWED_ON_RESTRICTED_NETWORKS setting and update
// mAppsAllowedOnRestrictedNetworks. // mUidsAllowedOnRestrictedNetworks.
updateAppsAllowedOnRestrictedNetworks(mDeps.getAppsAllowedOnRestrictedNetworks(mContext)); updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext));
List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS List<PackageInfo> apps = mPackageManager.getInstalledPackages(GET_PERMISSIONS
| MATCH_ANY_USER); | MATCH_ANY_USER);
@@ -265,9 +265,9 @@ public class PermissionMonitor {
} }
@VisibleForTesting @VisibleForTesting
void updateAppsAllowedOnRestrictedNetworks(final Set<String> apps) { void updateUidsAllowedOnRestrictedNetworks(final Set<Integer> uids) {
mAppsAllowedOnRestrictedNetworks.clear(); mUidsAllowedOnRestrictedNetworks.clear();
mAppsAllowedOnRestrictedNetworks.addAll(apps); mUidsAllowedOnRestrictedNetworks.addAll(uids);
} }
@VisibleForTesting @VisibleForTesting
@@ -285,10 +285,11 @@ public class PermissionMonitor {
} }
@VisibleForTesting @VisibleForTesting
boolean isAppAllowedOnRestrictedNetworks(@NonNull final PackageInfo app) { boolean isUidAllowedOnRestrictedNetworks(final ApplicationInfo appInfo) {
// Check whether package name is in allowed on restricted networks app list. If so, this app if (appInfo == null) return false;
// can have netd system permission. // Check whether package's uid is in allowed on restricted networks uid list. If so, this
return mAppsAllowedOnRestrictedNetworks.contains(app.packageName); // uid can have netd system permission.
return mUidsAllowedOnRestrictedNetworks.contains(appInfo.uid);
} }
@VisibleForTesting @VisibleForTesting
@@ -310,7 +311,8 @@ public class PermissionMonitor {
boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) { boolean hasRestrictedNetworkPermission(@NonNull final PackageInfo app) {
// TODO : remove carryover package check in the future(b/31479477). All apps should just // TODO : remove carryover package check in the future(b/31479477). All apps should just
// request the appropriate permission for their use case since android Q. // request the appropriate permission for their use case since android Q.
return isCarryoverPackage(app.applicationInfo) || isAppAllowedOnRestrictedNetworks(app) return isCarryoverPackage(app.applicationInfo)
|| isUidAllowedOnRestrictedNetworks(app.applicationInfo)
|| hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK) || hasPermission(app, PERMISSION_MAINLINE_NETWORK_STACK)
|| hasPermission(app, NETWORK_STACK) || hasPermission(app, NETWORK_STACK)
|| hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS); || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
@@ -770,35 +772,31 @@ public class PermissionMonitor {
} }
private synchronized void onSettingChanged() { private synchronized void onSettingChanged() {
// Step1. Update apps allowed to use restricted networks and compute the set of packages to // Step1. Update uids allowed to use restricted networks and compute the set of uids to
// update. // update.
final Set<String> packagesToUpdate = new ArraySet<>(mAppsAllowedOnRestrictedNetworks); final Set<Integer> uidsToUpdate = new ArraySet<>(mUidsAllowedOnRestrictedNetworks);
updateAppsAllowedOnRestrictedNetworks(mDeps.getAppsAllowedOnRestrictedNetworks(mContext)); updateUidsAllowedOnRestrictedNetworks(mDeps.getUidsAllowedOnRestrictedNetworks(mContext));
packagesToUpdate.addAll(mAppsAllowedOnRestrictedNetworks); uidsToUpdate.addAll(mUidsAllowedOnRestrictedNetworks);
final Map<Integer, Boolean> updatedApps = new HashMap<>(); final Map<Integer, Boolean> updatedUids = new HashMap<>();
final Map<Integer, Boolean> removedApps = new HashMap<>(); final Map<Integer, Boolean> removedUids = new HashMap<>();
// Step2. For each package to update, find out its new permission. // Step2. For each uid to update, find out its new permission.
for (String app : packagesToUpdate) { for (Integer uid : uidsToUpdate) {
final PackageInfo info = getPackageInfo(app);
if (info == null || info.applicationInfo == null) continue;
final int uid = info.applicationInfo.uid;
final Boolean permission = highestUidNetworkPermission(uid); final Boolean permission = highestUidNetworkPermission(uid);
if (null == permission) { if (null == permission) {
removedApps.put(uid, NETWORK); // Doesn't matter which permission is set here. removedUids.put(uid, NETWORK); // Doesn't matter which permission is set here.
mApps.remove(uid); mApps.remove(uid);
} else { } else {
updatedApps.put(uid, permission); updatedUids.put(uid, permission);
mApps.put(uid, permission); mApps.put(uid, permission);
} }
} }
// Step3. Update or revoke permission for uids with netd. // Step3. Update or revoke permission for uids with netd.
update(mUsers, updatedApps, true /* add */); update(mUsers, updatedUids, true /* add */);
update(mUsers, removedApps, false /* add */); update(mUsers, removedUids, false /* add */);
} }
/** Dump info to dumpsys */ /** Dump info to dumpsys */

View File

@@ -30,7 +30,7 @@ import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.net.ConnectivitySettingsManager.APPS_ALLOWED_ON_RESTRICTED_NETWORKS; import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.SYSTEM_UID; import static android.os.Process.SYSTEM_UID;
@@ -142,7 +142,7 @@ public class PermissionMonitorTest {
final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext)); final Context asUserCtx = mock(Context.class, AdditionalAnswers.delegatesTo(mContext));
doReturn(UserHandle.ALL).when(asUserCtx).getUser(); doReturn(UserHandle.ALL).when(asUserCtx).getUser();
when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx); when(mContext.createContextAsUser(eq(UserHandle.ALL), anyInt())).thenReturn(asUserCtx);
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>()); when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps)); mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
@@ -341,9 +341,9 @@ public class PermissionMonitorTest {
} }
@Test @Test
public void testHasRestrictedNetworkPermissionAppAllowedOnRestrictedNetworks() { public void testHasRestrictedNetworkPermissionUidAllowedOnRestrictedNetworks() {
mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks( mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(
new ArraySet<>(new String[] { MOCK_PACKAGE1 })); new ArraySet<>(new Integer[] { MOCK_UID1 }));
assertTrue(hasRestrictedNetworkPermission( assertTrue(hasRestrictedNetworkPermission(
PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1)); PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1));
assertTrue(hasRestrictedNetworkPermission( assertTrue(hasRestrictedNetworkPermission(
@@ -352,11 +352,11 @@ public class PermissionMonitorTest {
PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL)); PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE1, MOCK_UID1, CONNECTIVITY_INTERNAL));
assertFalse(hasRestrictedNetworkPermission( assertFalse(hasRestrictedNetworkPermission(
PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1)); PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2));
assertFalse(hasRestrictedNetworkPermission( assertFalse(hasRestrictedNetworkPermission(
PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1, CHANGE_NETWORK_STATE)); PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2, CHANGE_NETWORK_STATE));
assertFalse(hasRestrictedNetworkPermission( assertFalse(hasRestrictedNetworkPermission(
PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID1, CONNECTIVITY_INTERNAL)); PARTITION_VENDOR, VERSION_Q, MOCK_PACKAGE2, MOCK_UID2, CONNECTIVITY_INTERNAL));
} }
@@ -396,32 +396,32 @@ public class PermissionMonitorTest {
assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1)); assertFalse(wouldBeCarryoverPackage(PARTITION_PRODUCT, VERSION_Q, MOCK_UID1));
} }
private boolean wouldBeAppAllowedOnRestrictedNetworks(String packageName) { private boolean wouldBeUidAllowedOnRestrictedNetworks(int uid) {
final PackageInfo packageInfo = new PackageInfo(); final ApplicationInfo applicationInfo = new ApplicationInfo();
packageInfo.packageName = packageName; applicationInfo.uid = uid;
return mPermissionMonitor.isAppAllowedOnRestrictedNetworks(packageInfo); return mPermissionMonitor.isUidAllowedOnRestrictedNetworks(applicationInfo);
} }
@Test @Test
public void testIsAppAllowedOnRestrictedNetworks() { public void testIsAppAllowedOnRestrictedNetworks() {
mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks(new ArraySet<>()); mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(new ArraySet<>());
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1));
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2));
mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks( mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(
new ArraySet<>(new String[] { MOCK_PACKAGE1 })); new ArraySet<>(new Integer[] { MOCK_UID1 }));
assertTrue(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1)); assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1));
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2));
mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks( mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(
new ArraySet<>(new String[] { MOCK_PACKAGE2 })); new ArraySet<>(new Integer[] { MOCK_UID2 }));
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1));
assertTrue(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2)); assertTrue(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2));
mPermissionMonitor.updateAppsAllowedOnRestrictedNetworks( mPermissionMonitor.updateUidsAllowedOnRestrictedNetworks(
new ArraySet<>(new String[] { "com.android.test" })); new ArraySet<>(new Integer[] { 123 }));
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE1)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID1));
assertFalse(wouldBeAppAllowedOnRestrictedNetworks(MOCK_PACKAGE2)); assertFalse(wouldBeUidAllowedOnRestrictedNetworks(MOCK_UID2));
} }
private void assertBackgroundPermission(boolean hasPermission, String name, int uid, private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
@@ -901,12 +901,12 @@ public class PermissionMonitorTest {
} }
@Test @Test
public void testAppsAllowedOnRestrictedNetworksChanged() throws Exception { public void testUidsAllowedOnRestrictedNetworksChanged() throws Exception {
final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService); final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
final ArgumentCaptor<ContentObserver> captor = final ArgumentCaptor<ContentObserver> captor =
ArgumentCaptor.forClass(ContentObserver.class); ArgumentCaptor.forClass(ContentObserver.class);
verify(mDeps, times(1)).registerContentObserver(any(), verify(mDeps, times(1)).registerContentObserver(any(),
argThat(uri -> uri.getEncodedPath().contains(APPS_ALLOWED_ON_RESTRICTED_NETWORKS)), argThat(uri -> uri.getEncodedPath().contains(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)),
anyBoolean(), captor.capture()); anyBoolean(), captor.capture());
final ContentObserver contentObserver = captor.getValue(); final ContentObserver contentObserver = captor.getValue();
@@ -924,24 +924,24 @@ public class PermissionMonitorTest {
when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2); when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
when(mPackageManager.getPackagesForUid(MOCK_UID2)).thenReturn(new String[]{MOCK_PACKAGE2}); when(mPackageManager.getPackagesForUid(MOCK_UID2)).thenReturn(new String[]{MOCK_PACKAGE2});
// MOCK_PACKAGE1 is listed in setting that allow to use restricted networks, MOCK_UID1 // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should have SYSTEM permission. // should have SYSTEM permission.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn( when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new String[] { MOCK_PACKAGE1 })); new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */); contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1}); mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2}); mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
// MOCK_PACKAGE2 is listed in setting that allow to use restricted networks, MOCK_UID2 // MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2
// should have SYSTEM permission but MOCK_UID1 should revoke permission. // should have SYSTEM permission but MOCK_UID1 should revoke permission.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn( when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new String[] { MOCK_PACKAGE2 })); new ArraySet<>(new Integer[] { MOCK_UID2 }));
contentObserver.onChange(true /* selfChange */); contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2}); mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1}); mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// No app lists in setting, should revoke permission from all uids. // No uid lists in setting, should revoke permission from all uids.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>()); when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */); contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectNoPermission( mNetdMonitor.expectNoPermission(
new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2}); new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2});
@@ -953,7 +953,7 @@ public class PermissionMonitorTest {
final ArgumentCaptor<ContentObserver> captor = final ArgumentCaptor<ContentObserver> captor =
ArgumentCaptor.forClass(ContentObserver.class); ArgumentCaptor.forClass(ContentObserver.class);
verify(mDeps, times(1)).registerContentObserver(any(), verify(mDeps, times(1)).registerContentObserver(any(),
argThat(uri -> uri.getEncodedPath().contains(APPS_ALLOWED_ON_RESTRICTED_NETWORKS)), argThat(uri -> uri.getEncodedPath().contains(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)),
anyBoolean(), captor.capture()); anyBoolean(), captor.capture());
final ContentObserver contentObserver = captor.getValue(); final ContentObserver contentObserver = captor.getValue();
@@ -974,22 +974,15 @@ public class PermissionMonitorTest {
addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1); addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1}); mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// MOCK_PACKAGE2 is listed in setting that allow to use restricted networks, MOCK_UID1 // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should upgrade to SYSTEM permission. // should upgrade to SYSTEM permission.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn( when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new String[] { MOCK_PACKAGE2 })); new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// MOCK_PACKAGE1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should still have SYSTEM permission.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new String[] { MOCK_PACKAGE1 }));
contentObserver.onChange(true /* selfChange */); contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1}); mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission. // No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission.
when(mDeps.getAppsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>()); when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */); contentObserver.onChange(true /* selfChange */);
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1}); mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});