Downgrade list of subIds in NetworkCapabilities to @SystemApi

This change downgrades API visibility for the list-of-subIds in the
NetworkCapabilities to SystemApi

Bug: 175662146
Test: atest NetworkCapabilitiesTest#testSubIds
Test: atest FrameworksNetTests
Change-Id: I372fa9eaa7585aefd1710948ca007456feedd578
This commit is contained in:
Benedict Wong
2021-03-24 14:01:51 -07:00
parent 2f6519b747
commit 53de25fe46
6 changed files with 93 additions and 2 deletions

View File

@@ -298,7 +298,6 @@ package android.net {
method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier(); method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
method public int getOwnerUid(); method public int getOwnerUid();
method public int getSignalStrength(); method public int getSignalStrength();
method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @Nullable public android.net.TransportInfo getTransportInfo(); method @Nullable public android.net.TransportInfo getTransportInfo();
method public boolean hasCapability(int); method public boolean hasCapability(int);
method public boolean hasTransport(int); method public boolean hasTransport(int);
@@ -408,7 +407,6 @@ package android.net {
method public android.net.NetworkRequest.Builder removeTransportType(int); method public android.net.NetworkRequest.Builder removeTransportType(int);
method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String); method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier); method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
} }
public class ParseException extends java.lang.RuntimeException { public class ParseException extends java.lang.RuntimeException {

View File

@@ -274,6 +274,7 @@ package android.net {
public final class NetworkCapabilities implements android.os.Parcelable { public final class NetworkCapabilities implements android.os.Parcelable {
method @NonNull public int[] getAdministratorUids(); method @NonNull public int[] getAdministratorUids();
method @Nullable public String getSsid(); method @Nullable public String getSsid();
method @NonNull public java.util.Set<java.lang.Integer> getSubIds();
method @NonNull public int[] getTransportTypes(); method @NonNull public int[] getTransportTypes();
method public boolean isPrivateDnsBroken(); method public boolean isPrivateDnsBroken();
method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities); method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
@@ -327,6 +328,7 @@ package android.net {
public static class NetworkRequest.Builder { public static class NetworkRequest.Builder {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int); method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
method @NonNull public android.net.NetworkRequest.Builder setSubIds(@NonNull java.util.Set<java.lang.Integer>);
} }
public final class NetworkScore implements android.os.Parcelable { public final class NetworkScore implements android.os.Parcelable {

View File

@@ -2346,9 +2346,15 @@ public final class NetworkCapabilities implements Parcelable {
/** /**
* Gets the subscription ID set that associated to this network or request. * Gets the subscription ID set that associated to this network or request.
*
* <p>Instances of NetworkCapabilities will only have this field populated by the system if the
* receiver holds the NETWORK_FACTORY permission. In all other cases, it will be the empty set.
*
* @return * @return
* @hide
*/ */
@NonNull @NonNull
@SystemApi
public Set<Integer> getSubIds() { public Set<Integer> getSubIds() {
return new ArraySet<>(mSubIds); return new ArraySet<>(mSubIds);
} }
@@ -2713,10 +2719,17 @@ public final class NetworkCapabilities implements Parcelable {
/** /**
* Set the subscription ID set. * Set the subscription ID set.
* *
* <p>SubIds are populated in NetworkCapability instances from the system only for callers
* that hold the NETWORK_FACTORY permission. Similarly, the system will reject any
* NetworkRequests filed with a non-empty set of subIds unless the caller holds the
* NETWORK_FACTORY permission.
*
* @param subIds a set that represent the subscription IDs. Empty if clean up. * @param subIds a set that represent the subscription IDs. Empty if clean up.
* @return this builder. * @return this builder.
* @hide
*/ */
@NonNull @NonNull
@SystemApi
public Builder setSubIds(@NonNull final Set<Integer> subIds) { public Builder setSubIds(@NonNull final Set<Integer> subIds) {
mCaps.setSubIds(subIds); mCaps.setSubIds(subIds);
return this; return this;

View File

@@ -501,9 +501,14 @@ public class NetworkRequest implements Parcelable {
* A network will satisfy this request only if it matches one of the subIds in this set. * A network will satisfy this request only if it matches one of the subIds in this set.
* An empty set matches all networks, including those without a subId. * An empty set matches all networks, including those without a subId.
* *
* <p>Registering a NetworkRequest with a non-empty set of subIds requires the
* NETWORK_FACTORY permission.
*
* @param subIds A {@code Set} that represents subscription IDs. * @param subIds A {@code Set} that represents subscription IDs.
* @hide
*/ */
@NonNull @NonNull
@SystemApi
public Builder setSubIds(@NonNull Set<Integer> subIds) { public Builder setSubIds(@NonNull Set<Integer> subIds) {
mNetworkCapabilities.setSubIds(subIds); mNetworkCapabilities.setSubIds(subIds);
return this; return this;

View File

@@ -1895,6 +1895,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact()); newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
} }
newNc.setAdministratorUids(new int[0]); newNc.setAdministratorUids(new int[0]);
if (!checkAnyPermissionOf(
callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
newNc.setSubIds(Collections.emptySet());
}
return newNc; return newNc;
} }
@@ -5666,6 +5670,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
"Insufficient permissions to request a specific signal strength"); "Insufficient permissions to request a specific signal strength");
} }
mAppOpsManager.checkPackage(callerUid, callerPackageName); mAppOpsManager.checkPackage(callerUid, callerPackageName);
if (!nc.getSubIds().isEmpty()) {
enforceNetworkFactoryPermission();
}
} }
private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {

View File

@@ -18,6 +18,7 @@ package com.android.server;
import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CHANGE_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.NETWORK_FACTORY;
import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.content.Intent.ACTION_USER_ADDED; import static android.content.Intent.ACTION_USER_ADDED;
@@ -12186,4 +12187,68 @@ public class ConnectivityServiceTest {
mCm.setProfileNetworkPreference(testHandle, mCm.setProfileNetworkPreference(testHandle,
PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null)); PROFILE_NETWORK_PREFERENCE_ENTERPRISE, null, null));
} }
@Test
public void testSubIdsClearedWithoutNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);
final NetworkCapabilities nc = new NetworkCapabilities();
nc.setSubIds(Collections.singleton(Process.myUid()));
final NetworkCapabilities result =
mService.networkCapabilitiesRestrictedForCallerPermissions(
nc, Process.myPid(), Process.myUid());
assertTrue(result.getSubIds().isEmpty());
}
@Test
public void testSubIdsExistWithNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
final Set<Integer> subIds = Collections.singleton(Process.myUid());
final NetworkCapabilities nc = new NetworkCapabilities();
nc.setSubIds(subIds);
final NetworkCapabilities result =
mService.networkCapabilitiesRestrictedForCallerPermissions(
nc, Process.myPid(), Process.myUid());
assertEquals(subIds, result.getSubIds());
}
private NetworkRequest getRequestWithSubIds() {
return new NetworkRequest.Builder()
.setSubIds(Collections.singleton(Process.myUid()))
.build();
}
@Test
public void testNetworkRequestWithSubIdsWithNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(
mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
final NetworkCallback networkCallback1 = new NetworkCallback();
final NetworkCallback networkCallback2 = new NetworkCallback();
mCm.requestNetwork(getRequestWithSubIds(), networkCallback1);
mCm.requestNetwork(getRequestWithSubIds(), pendingIntent);
mCm.registerNetworkCallback(getRequestWithSubIds(), networkCallback2);
mCm.unregisterNetworkCallback(networkCallback1);
mCm.releaseNetworkRequest(pendingIntent);
mCm.unregisterNetworkCallback(networkCallback2);
}
@Test
public void testNetworkRequestWithSubIdsWithoutNetworkFactoryPermission() throws Exception {
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_DENIED);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(
mContext, 0 /* requestCode */, new Intent("a"), FLAG_IMMUTABLE);
final Class<SecurityException> expected = SecurityException.class;
assertThrows(
expected, () -> mCm.requestNetwork(getRequestWithSubIds(), new NetworkCallback()));
assertThrows(expected, () -> mCm.requestNetwork(getRequestWithSubIds(), pendingIntent));
assertThrows(
expected,
() -> mCm.registerNetworkCallback(getRequestWithSubIds(), new NetworkCallback()));
}
} }