Loading core/java/android/net/NetworkCapabilities.java +73 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public final class NetworkCapabilities implements Parcelable { mUids = nc.mUids; mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid; mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; mSSID = nc.mSSID; } } Loading @@ -86,6 +87,7 @@ public final class NetworkCapabilities implements Parcelable { mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; mUids = null; mEstablishingVpnAppUid = INVALID_UID; mSSID = null; } /** Loading Loading @@ -921,7 +923,7 @@ public final class NetworkCapabilities implements Parcelable { /** * Sets the signal strength. This is a signed integer, with higher values indicating a stronger * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units * reported by WifiManager. * reported by wifi code. * <p> * Note that when used to register a network callback, this specifies the minimum acceptable * signal strength. When received as the state of an existing network it specifies the current Loading Loading @@ -1053,7 +1055,7 @@ public final class NetworkCapabilities implements Parcelable { } /** * Tests if the set of UIDs that this network applies to is the same of the passed set of UIDs. * Tests if the set of UIDs that this network applies to is the same as the passed network. * <p> * This test only checks whether equal range objects are in both sets. It will * return false if the ranges are not exactly the same, even if the covered UIDs Loading Loading @@ -1143,6 +1145,62 @@ public final class NetworkCapabilities implements Parcelable { mUids.addAll(nc.mUids); } /** * The SSID of the network, or null if not applicable or unknown. * <p> * This is filled in by wifi code. * @hide */ private String mSSID; /** * Sets the SSID of this network. * @hide */ public NetworkCapabilities setSSID(String ssid) { mSSID = ssid; return this; } /** * Gets the SSID of this network, or null if none or unknown. * @hide */ public String getSSID() { return mSSID; } /** * Tests if the SSID of this network is the same as the SSID of the passed network. * @hide */ public boolean equalsSSID(NetworkCapabilities nc) { return Objects.equals(mSSID, nc.mSSID); } /** * Check if the SSID requirements of this object are matched by the passed object. * @hide */ public boolean satisfiedBySSID(NetworkCapabilities nc) { return mSSID == null || mSSID.equals(nc.mSSID); } /** * Combine SSIDs of the capabilities. * <p> * This is only legal if either the SSID of this object is null, or both SSIDs are * equal. * @hide */ private void combineSSIDs(NetworkCapabilities nc) { if (mSSID != null && !mSSID.equals(nc.mSSID)) { throw new IllegalStateException("Can't combine two SSIDs"); } setSSID(nc.mSSID); } /** * Combine a set of Capabilities to this one. Useful for coming up with the complete set * @hide Loading @@ -1154,6 +1212,7 @@ public final class NetworkCapabilities implements Parcelable { combineSpecifiers(nc); combineSignalStrength(nc); combineUids(nc); combineSSIDs(nc); } /** Loading @@ -1172,7 +1231,8 @@ public final class NetworkCapabilities implements Parcelable { && (onlyImmutable || satisfiedByLinkBandwidths(nc)) && satisfiedBySpecifier(nc) && (onlyImmutable || satisfiedBySignalStrength(nc)) && (onlyImmutable || satisfiedByUids(nc))); && (onlyImmutable || satisfiedByUids(nc)) && (onlyImmutable || satisfiedBySSID(nc))); } /** Loading Loading @@ -1259,7 +1319,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsLinkBandwidths(that) && equalsSignalStrength(that) && equalsSpecifier(that) && equalsUids(that)); && equalsUids(that) && equalsSSID(that)); } @Override Loading @@ -1274,7 +1335,8 @@ public final class NetworkCapabilities implements Parcelable { + (mLinkDownBandwidthKbps * 19) + Objects.hashCode(mNetworkSpecifier) * 23 + (mSignalStrength * 29) + Objects.hashCode(mUids) * 31; + Objects.hashCode(mUids) * 31 + Objects.hashCode(mSSID) * 37; } @Override Loading @@ -1291,6 +1353,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); dest.writeInt(mSignalStrength); dest.writeArraySet(mUids); dest.writeString(mSSID); } public static final Creator<NetworkCapabilities> CREATOR = Loading @@ -1308,6 +1371,7 @@ public final class NetworkCapabilities implements Parcelable { netCap.mSignalStrength = in.readInt(); netCap.mUids = (ArraySet<UidRange>) in.readArraySet( null /* ClassLoader, null for default */); netCap.mSSID = in.readString(); return netCap; } @Override Loading Loading @@ -1358,6 +1422,10 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid); } if (null != mSSID) { sb.append(" SSID: ").append(mSSID); } sb.append("]"); return sb.toString(); } Loading services/core/java/com/android/server/ConnectivityService.java +30 −5 Original line number Diff line number Diff line Loading @@ -1383,7 +1383,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai != null) { synchronized (nai) { if (nai.networkCapabilities != null) { return networkCapabilitiesWithoutUidsUnlessAllowed(nai.networkCapabilities, return networkCapabilitiesRestrictedForCallerPermissions( nai.networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); } } Loading @@ -1397,10 +1398,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); } private NetworkCapabilities networkCapabilitiesWithoutUidsUnlessAllowed( private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid) { if (checkSettingsPermission(callerPid, callerUid)) return new NetworkCapabilities(nc); return new NetworkCapabilities(nc).setUids(null); final NetworkCapabilities newNc = new NetworkCapabilities(nc); if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null); if (!checkNetworkStackPermission(callerPid, callerUid)) newNc.setSSID(null); return newNc; } private void restrictRequestUidsForCaller(NetworkCapabilities nc) { Loading Loading @@ -1659,6 +1662,11 @@ public class ConnectivityService extends IConnectivityManager.Stub android.Manifest.permission.NETWORK_SETTINGS, pid, uid); } private boolean checkNetworkStackPermission(int pid, int uid) { return PERMISSION_GRANTED == mContext.checkPermission( android.Manifest.permission.NETWORK_STACK, pid, uid); } private void enforceTetherAccessPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, Loading Loading @@ -4235,6 +4243,15 @@ public class ConnectivityService extends IConnectivityManager.Stub } } // This checks that the passed capabilities either do not request a specific SSID, or the // calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid) { if (null != nc.getSSID() && !checkNetworkStackPermission(callerPid, callerUid)) { throw new SecurityException("Insufficient permissions to request a specific SSID"); } } private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { final SortedSet<Integer> thresholds = new TreeSet(); synchronized (nai) { Loading Loading @@ -4304,6 +4321,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); } ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); // Set the UID range for this request to the single UID of the requester, or to an empty // set of UIDs if the caller has the appropriate permission and UIDs have not been set. // This will overwrite any allowed UIDs in the requested capabilities. Though there Loading Loading @@ -4382,6 +4401,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); ensureValidNetworkSpecifier(networkCapabilities); restrictRequestUidsForCaller(networkCapabilities); Loading Loading @@ -4437,6 +4458,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); restrictRequestUidsForCaller(nc); // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get Loading @@ -4463,6 +4486,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } ensureValidNetworkSpecifier(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); restrictRequestUidsForCaller(nc); Loading Loading @@ -5034,7 +5059,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } case ConnectivityManager.CALLBACK_CAP_CHANGED: { // networkAgent can't be null as it has been accessed a few lines above. final NetworkCapabilities nc = networkCapabilitiesWithoutUidsUnlessAllowed( final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions( networkAgent.networkCapabilities, nri.mPid, nri.mUid); putParcelable(bundle, nc); break; Loading tests/net/java/android/net/NetworkCapabilitiesTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -39,12 +39,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -53,6 +55,8 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class NetworkCapabilitiesTest { private static final String TEST_SSID = "TEST_SSID"; @Test public void testMaybeMarkCapabilitiesRestricted() { // verify EIMS is restricted Loading Loading @@ -259,6 +263,8 @@ public class NetworkCapabilitiesTest { .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); assertEqualsThroughMarshalling(netCap); netCap.setSSID(TEST_SSID); assertEqualsThroughMarshalling(netCap); } @Test Loading Loading @@ -353,6 +359,21 @@ public class NetworkCapabilitiesTest { assertTrue(nc1.equalsNetCapabilities(nc2)); } @Test public void testSSID() { NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); assertTrue(nc2.satisfiedBySSID(nc1)); nc1.setSSID(TEST_SSID); assertTrue(nc2.satisfiedBySSID(nc1)); nc2.setSSID("different " + TEST_SSID); assertFalse(nc2.satisfiedBySSID(nc1)); assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2)); assertFalse(nc1.satisfiedByNetworkCapabilities(nc2)); } @Test public void testCombineCapabilities() { NetworkCapabilities nc1 = new NetworkCapabilities(); Loading @@ -374,6 +395,19 @@ public class NetworkCapabilitiesTest { // will never be satisfied. assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING)); nc1.setSSID(TEST_SSID); nc2.combineCapabilities(nc1); assertTrue(TEST_SSID.equals(nc2.getSSID())); // Because they now have the same SSID, the folllowing call should not throw nc2.combineCapabilities(nc1); nc1.setSSID("different " + TEST_SSID); try { nc2.combineCapabilities(nc1); fail("Expected IllegalStateException: can't combine different SSIDs"); } catch (IllegalStateException expected) {} } @Test Loading Loading
core/java/android/net/NetworkCapabilities.java +73 −5 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ public final class NetworkCapabilities implements Parcelable { mUids = nc.mUids; mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid; mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; mSSID = nc.mSSID; } } Loading @@ -86,6 +87,7 @@ public final class NetworkCapabilities implements Parcelable { mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED; mUids = null; mEstablishingVpnAppUid = INVALID_UID; mSSID = null; } /** Loading Loading @@ -921,7 +923,7 @@ public final class NetworkCapabilities implements Parcelable { /** * Sets the signal strength. This is a signed integer, with higher values indicating a stronger * signal. The exact units are bearer-dependent. For example, Wi-Fi uses the same RSSI units * reported by WifiManager. * reported by wifi code. * <p> * Note that when used to register a network callback, this specifies the minimum acceptable * signal strength. When received as the state of an existing network it specifies the current Loading Loading @@ -1053,7 +1055,7 @@ public final class NetworkCapabilities implements Parcelable { } /** * Tests if the set of UIDs that this network applies to is the same of the passed set of UIDs. * Tests if the set of UIDs that this network applies to is the same as the passed network. * <p> * This test only checks whether equal range objects are in both sets. It will * return false if the ranges are not exactly the same, even if the covered UIDs Loading Loading @@ -1143,6 +1145,62 @@ public final class NetworkCapabilities implements Parcelable { mUids.addAll(nc.mUids); } /** * The SSID of the network, or null if not applicable or unknown. * <p> * This is filled in by wifi code. * @hide */ private String mSSID; /** * Sets the SSID of this network. * @hide */ public NetworkCapabilities setSSID(String ssid) { mSSID = ssid; return this; } /** * Gets the SSID of this network, or null if none or unknown. * @hide */ public String getSSID() { return mSSID; } /** * Tests if the SSID of this network is the same as the SSID of the passed network. * @hide */ public boolean equalsSSID(NetworkCapabilities nc) { return Objects.equals(mSSID, nc.mSSID); } /** * Check if the SSID requirements of this object are matched by the passed object. * @hide */ public boolean satisfiedBySSID(NetworkCapabilities nc) { return mSSID == null || mSSID.equals(nc.mSSID); } /** * Combine SSIDs of the capabilities. * <p> * This is only legal if either the SSID of this object is null, or both SSIDs are * equal. * @hide */ private void combineSSIDs(NetworkCapabilities nc) { if (mSSID != null && !mSSID.equals(nc.mSSID)) { throw new IllegalStateException("Can't combine two SSIDs"); } setSSID(nc.mSSID); } /** * Combine a set of Capabilities to this one. Useful for coming up with the complete set * @hide Loading @@ -1154,6 +1212,7 @@ public final class NetworkCapabilities implements Parcelable { combineSpecifiers(nc); combineSignalStrength(nc); combineUids(nc); combineSSIDs(nc); } /** Loading @@ -1172,7 +1231,8 @@ public final class NetworkCapabilities implements Parcelable { && (onlyImmutable || satisfiedByLinkBandwidths(nc)) && satisfiedBySpecifier(nc) && (onlyImmutable || satisfiedBySignalStrength(nc)) && (onlyImmutable || satisfiedByUids(nc))); && (onlyImmutable || satisfiedByUids(nc)) && (onlyImmutable || satisfiedBySSID(nc))); } /** Loading Loading @@ -1259,7 +1319,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsLinkBandwidths(that) && equalsSignalStrength(that) && equalsSpecifier(that) && equalsUids(that)); && equalsUids(that) && equalsSSID(that)); } @Override Loading @@ -1274,7 +1335,8 @@ public final class NetworkCapabilities implements Parcelable { + (mLinkDownBandwidthKbps * 19) + Objects.hashCode(mNetworkSpecifier) * 23 + (mSignalStrength * 29) + Objects.hashCode(mUids) * 31; + Objects.hashCode(mUids) * 31 + Objects.hashCode(mSSID) * 37; } @Override Loading @@ -1291,6 +1353,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); dest.writeInt(mSignalStrength); dest.writeArraySet(mUids); dest.writeString(mSSID); } public static final Creator<NetworkCapabilities> CREATOR = Loading @@ -1308,6 +1371,7 @@ public final class NetworkCapabilities implements Parcelable { netCap.mSignalStrength = in.readInt(); netCap.mUids = (ArraySet<UidRange>) in.readArraySet( null /* ClassLoader, null for default */); netCap.mSSID = in.readString(); return netCap; } @Override Loading Loading @@ -1358,6 +1422,10 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid); } if (null != mSSID) { sb.append(" SSID: ").append(mSSID); } sb.append("]"); return sb.toString(); } Loading
services/core/java/com/android/server/ConnectivityService.java +30 −5 Original line number Diff line number Diff line Loading @@ -1383,7 +1383,8 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai != null) { synchronized (nai) { if (nai.networkCapabilities != null) { return networkCapabilitiesWithoutUidsUnlessAllowed(nai.networkCapabilities, return networkCapabilitiesRestrictedForCallerPermissions( nai.networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); } } Loading @@ -1397,10 +1398,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network)); } private NetworkCapabilities networkCapabilitiesWithoutUidsUnlessAllowed( private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions( NetworkCapabilities nc, int callerPid, int callerUid) { if (checkSettingsPermission(callerPid, callerUid)) return new NetworkCapabilities(nc); return new NetworkCapabilities(nc).setUids(null); final NetworkCapabilities newNc = new NetworkCapabilities(nc); if (!checkSettingsPermission(callerPid, callerUid)) newNc.setUids(null); if (!checkNetworkStackPermission(callerPid, callerUid)) newNc.setSSID(null); return newNc; } private void restrictRequestUidsForCaller(NetworkCapabilities nc) { Loading Loading @@ -1659,6 +1662,11 @@ public class ConnectivityService extends IConnectivityManager.Stub android.Manifest.permission.NETWORK_SETTINGS, pid, uid); } private boolean checkNetworkStackPermission(int pid, int uid) { return PERMISSION_GRANTED == mContext.checkPermission( android.Manifest.permission.NETWORK_STACK, pid, uid); } private void enforceTetherAccessPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, Loading Loading @@ -4235,6 +4243,15 @@ public class ConnectivityService extends IConnectivityManager.Stub } } // This checks that the passed capabilities either do not request a specific SSID, or the // calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, int callerPid, int callerUid) { if (null != nc.getSSID() && !checkNetworkStackPermission(callerPid, callerUid)) { throw new SecurityException("Insufficient permissions to request a specific SSID"); } } private ArrayList<Integer> getSignalStrengthThresholds(NetworkAgentInfo nai) { final SortedSet<Integer> thresholds = new TreeSet(); synchronized (nai) { Loading Loading @@ -4304,6 +4321,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); } ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); // Set the UID range for this request to the single UID of the requester, or to an empty // set of UIDs if the caller has the appropriate permission and UIDs have not been set. // This will overwrite any allowed UIDs in the requested capabilities. Though there Loading Loading @@ -4382,6 +4401,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); ensureValidNetworkSpecifier(networkCapabilities); restrictRequestUidsForCaller(networkCapabilities); Loading Loading @@ -4437,6 +4458,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); restrictRequestUidsForCaller(nc); // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get Loading @@ -4463,6 +4486,8 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } ensureValidNetworkSpecifier(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, Binder.getCallingPid(), Binder.getCallingUid()); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); restrictRequestUidsForCaller(nc); Loading Loading @@ -5034,7 +5059,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } case ConnectivityManager.CALLBACK_CAP_CHANGED: { // networkAgent can't be null as it has been accessed a few lines above. final NetworkCapabilities nc = networkCapabilitiesWithoutUidsUnlessAllowed( final NetworkCapabilities nc = networkCapabilitiesRestrictedForCallerPermissions( networkAgent.networkCapabilities, nri.mPid, nri.mUid); putParcelable(bundle, nc); break; Loading
tests/net/java/android/net/NetworkCapabilitiesTest.java +34 −0 Original line number Diff line number Diff line Loading @@ -39,12 +39,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Parcel; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -53,6 +55,8 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) @SmallTest public class NetworkCapabilitiesTest { private static final String TEST_SSID = "TEST_SSID"; @Test public void testMaybeMarkCapabilitiesRestricted() { // verify EIMS is restricted Loading Loading @@ -259,6 +263,8 @@ public class NetworkCapabilitiesTest { .addCapability(NET_CAPABILITY_EIMS) .addCapability(NET_CAPABILITY_NOT_METERED); assertEqualsThroughMarshalling(netCap); netCap.setSSID(TEST_SSID); assertEqualsThroughMarshalling(netCap); } @Test Loading Loading @@ -353,6 +359,21 @@ public class NetworkCapabilitiesTest { assertTrue(nc1.equalsNetCapabilities(nc2)); } @Test public void testSSID() { NetworkCapabilities nc1 = new NetworkCapabilities(); NetworkCapabilities nc2 = new NetworkCapabilities(); assertTrue(nc2.satisfiedBySSID(nc1)); nc1.setSSID(TEST_SSID); assertTrue(nc2.satisfiedBySSID(nc1)); nc2.setSSID("different " + TEST_SSID); assertFalse(nc2.satisfiedBySSID(nc1)); assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2)); assertFalse(nc1.satisfiedByNetworkCapabilities(nc2)); } @Test public void testCombineCapabilities() { NetworkCapabilities nc1 = new NetworkCapabilities(); Loading @@ -374,6 +395,19 @@ public class NetworkCapabilitiesTest { // will never be satisfied. assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING)); assertTrue(nc2.hasUnwantedCapability(NET_CAPABILITY_NOT_ROAMING)); nc1.setSSID(TEST_SSID); nc2.combineCapabilities(nc1); assertTrue(TEST_SSID.equals(nc2.getSSID())); // Because they now have the same SSID, the folllowing call should not throw nc2.combineCapabilities(nc1); nc1.setSSID("different " + TEST_SSID); try { nc2.combineCapabilities(nc1); fail("Expected IllegalStateException: can't combine different SSIDs"); } catch (IllegalStateException expected) {} } @Test Loading