diff options
| -rw-r--r-- | api/current.txt | 4 | ||||
| -rw-r--r-- | api/system-current.txt | 4 | ||||
| -rw-r--r-- | api/test-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/net/MatchAllNetworkSpecifier.java | 80 | ||||
| -rw-r--r-- | core/java/android/net/NetworkCapabilities.java | 69 | ||||
| -rw-r--r-- | core/java/android/net/NetworkRequest.java | 26 | ||||
| -rw-r--r-- | core/java/android/net/NetworkSpecifier.java | 36 | ||||
| -rw-r--r-- | core/java/android/net/StringNetworkSpecifier.java | 79 | ||||
| -rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 17 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/ConnectivityServiceTest.java | 86 |
10 files changed, 331 insertions, 74 deletions
diff --git a/api/current.txt b/api/current.txt index 268613e032e6..497ef59cd5bc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24136,6 +24136,10 @@ package android.net { method public android.net.NetworkRequest.Builder removeCapability(int); method public android.net.NetworkRequest.Builder removeTransportType(int); method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String); + method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier); + } + + public abstract class NetworkSpecifier { } public class ParseException extends java.lang.RuntimeException { diff --git a/api/system-current.txt b/api/system-current.txt index 83a79d1291d1..5ea9f1c74e13 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -25999,6 +25999,7 @@ package android.net { method public android.net.NetworkRequest.Builder removeCapability(int); method public android.net.NetworkRequest.Builder removeTransportType(int); method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String); + method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier); } public class NetworkScoreManager { @@ -26018,6 +26019,9 @@ package android.net { field public static final java.lang.String EXTRA_PACKAGE_NAME = "packageName"; } + public abstract class NetworkSpecifier { + } + public class ParseException extends java.lang.RuntimeException { field public java.lang.String response; } diff --git a/api/test-current.txt b/api/test-current.txt index 063b0112b525..89b73238530a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -24210,6 +24210,10 @@ package android.net { method public android.net.NetworkRequest.Builder removeCapability(int); method public android.net.NetworkRequest.Builder removeTransportType(int); method public android.net.NetworkRequest.Builder setNetworkSpecifier(java.lang.String); + method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier); + } + + public abstract class NetworkSpecifier { } public class ParseException extends java.lang.RuntimeException { diff --git a/core/java/android/net/MatchAllNetworkSpecifier.java b/core/java/android/net/MatchAllNetworkSpecifier.java new file mode 100644 index 000000000000..7aafc93bb4a1 --- /dev/null +++ b/core/java/android/net/MatchAllNetworkSpecifier.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * MatchAllNetworkSpecifier is a marker class used by NetworkFactory classes to indicate + * that they accept (match) any network specifier in requests. + * + * The class must never be used as part of a network request (those semantics aren't specified). + * + * @hide + */ +public final class MatchAllNetworkSpecifier extends NetworkSpecifier implements Parcelable { + /** + * Utility method which verifies that the ns argument is not a MatchAllNetworkSpecifier and + * throws an IllegalArgumentException if it is. + */ + public static void checkNotMatchAllNetworkSpecifier(NetworkSpecifier ns) { + if (ns instanceof MatchAllNetworkSpecifier) { + throw new IllegalArgumentException("A MatchAllNetworkSpecifier is not permitted"); + } + } + + public boolean satisfiedBy(NetworkSpecifier other) { + /* + * The method is called by a NetworkRequest to see if it is satisfied by a proposed + * network (e.g. as offered by a network factory). Since MatchAllNetweorkSpecifier must + * not be used in network requests this method should never be called. + */ + throw new IllegalStateException( + "MatchAllNetworkSpecifier must not be used in NetworkRequests"); + } + + @Override + public boolean equals(Object o) { + return o instanceof MatchAllNetworkSpecifier; + } + + @Override + public int hashCode() { + return 0; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + // Nothing to write. + } + + public static final Parcelable.Creator<MatchAllNetworkSpecifier> CREATOR = + new Parcelable.Creator<MatchAllNetworkSpecifier>() { + public MatchAllNetworkSpecifier createFromParcel(Parcel in) { + return new MatchAllNetworkSpecifier(); + } + public MatchAllNetworkSpecifier[] newArray(int size) { + return new MatchAllNetworkSpecifier[size]; + } + }; +} diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 4dd8ce9c8beb..c28294f9fe9d 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -18,8 +18,9 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; -import android.text.TextUtils; -import java.lang.IllegalArgumentException; +import android.util.Log; + +import java.util.Objects; /** * This class represents the capabilities of a network. This is used both to specify @@ -33,6 +34,8 @@ import java.lang.IllegalArgumentException; * all cellular based connections are metered and all Wi-Fi based connections are not. */ public final class NetworkCapabilities implements Parcelable { + private static final String TAG = "NetworkCapabilities"; + /** * @hide */ @@ -205,19 +208,6 @@ public final class NetworkCapabilities implements Parcelable { (1 << NET_CAPABILITY_FOREGROUND); /** - * Network specifier for factories which want to match any network specifier - * (NS) in a request. Behavior: - * <li>Empty NS in request matches any network factory NS</li> - * <li>Empty NS in the network factory NS only matches a request with an - * empty NS</li> - * <li>"*" (this constant) NS in the network factory matches requests with - * any NS</li> - * - * @hide - */ - public static final String MATCH_ALL_REQUESTS_NETWORK_SPECIFIER = "*"; - - /** * Network capabilities that are not allowed in NetworkRequests. This exists because the * NetworkFactory / NetworkAgent model does not deal well with the situation where a * capability's presence cannot be known in advance. If such a capability is requested, then we @@ -581,63 +571,56 @@ public final class NetworkCapabilities implements Parcelable { this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps); } - private String mNetworkSpecifier; + private NetworkSpecifier mNetworkSpecifier = null; + /** * Sets the optional bearer specific network specifier. * This has no meaning if a single transport is also not specified, so calling * this without a single transport set will generate an exception, as will * subsequently adding or removing transports after this is set. * </p> - * The interpretation of this {@code String} is bearer specific and bearers that use - * it should document their particulars. For example, Bluetooth may use some sort of - * device id while WiFi could used SSID and/or BSSID. Cellular may use carrier SPN (name) - * or Subscription ID. * - * @param networkSpecifier An {@code String} of opaque format used to specify the bearer - * specific network specifier where the bearer has a choice of - * networks. + * @param networkSpecifier A concrete, parcelable framework class that extends + * NetworkSpecifier. * @return This NetworkCapabilities instance, to facilitate chaining. * @hide */ - public NetworkCapabilities setNetworkSpecifier(String networkSpecifier) { - if (TextUtils.isEmpty(networkSpecifier) == false && Long.bitCount(mTransportTypes) != 1) { + public NetworkCapabilities setNetworkSpecifier(NetworkSpecifier networkSpecifier) { + if (networkSpecifier != null && Long.bitCount(mTransportTypes) != 1) { throw new IllegalStateException("Must have a single transport specified to use " + "setNetworkSpecifier"); } + mNetworkSpecifier = networkSpecifier; + return this; } /** * Gets the optional bearer specific network specifier. * - * @return The optional {@code String} specifying the bearer specific network specifier. - * See {@link #setNetworkSpecifier}. + * @return The optional {@link NetworkSpecifier} specifying the bearer specific network + * specifier. See {@link #setNetworkSpecifier}. * @hide */ - public String getNetworkSpecifier() { + public NetworkSpecifier getNetworkSpecifier() { return mNetworkSpecifier; } private void combineSpecifiers(NetworkCapabilities nc) { - String otherSpecifier = nc.getNetworkSpecifier(); - if (TextUtils.isEmpty(otherSpecifier)) return; - if (TextUtils.isEmpty(mNetworkSpecifier) == false) { + if (mNetworkSpecifier != null && !mNetworkSpecifier.equals(nc.mNetworkSpecifier)) { throw new IllegalStateException("Can't combine two networkSpecifiers"); } - setNetworkSpecifier(otherSpecifier); + setNetworkSpecifier(nc.mNetworkSpecifier); } + private boolean satisfiedBySpecifier(NetworkCapabilities nc) { - return (TextUtils.isEmpty(mNetworkSpecifier) || - mNetworkSpecifier.equals(nc.mNetworkSpecifier) || - MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(nc.mNetworkSpecifier)); + return mNetworkSpecifier == null || mNetworkSpecifier.satisfiedBy(nc.mNetworkSpecifier) + || nc.mNetworkSpecifier instanceof MatchAllNetworkSpecifier; } + private boolean equalsSpecifier(NetworkCapabilities nc) { - if (TextUtils.isEmpty(mNetworkSpecifier)) { - return TextUtils.isEmpty(nc.mNetworkSpecifier); - } else { - return mNetworkSpecifier.equals(nc.mNetworkSpecifier); - } + return Objects.equals(mNetworkSpecifier, nc.mNetworkSpecifier); } /** @@ -799,7 +782,7 @@ public final class NetworkCapabilities implements Parcelable { ((int)(mTransportTypes >> 32) * 7) + (mLinkUpBandwidthKbps * 11) + (mLinkDownBandwidthKbps * 13) + - (TextUtils.isEmpty(mNetworkSpecifier) ? 0 : mNetworkSpecifier.hashCode() * 17) + + Objects.hashCode(mNetworkSpecifier) * 17 + (mSignalStrength * 19)); } @@ -813,7 +796,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeLong(mTransportTypes); dest.writeInt(mLinkUpBandwidthKbps); dest.writeInt(mLinkDownBandwidthKbps); - dest.writeString(mNetworkSpecifier); + dest.writeParcelable((Parcelable) mNetworkSpecifier, flags); dest.writeInt(mSignalStrength); } @@ -827,7 +810,7 @@ public final class NetworkCapabilities implements Parcelable { netCap.mTransportTypes = in.readLong(); netCap.mLinkUpBandwidthKbps = in.readInt(); netCap.mLinkDownBandwidthKbps = in.readInt(); - netCap.mNetworkSpecifier = in.readString(); + netCap.mNetworkSpecifier = in.readParcelable(null); netCap.mSignalStrength = in.readInt(); return netCap; } diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index cb780090c46a..95a8bb472939 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -18,6 +18,7 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import java.util.Objects; @@ -259,10 +260,27 @@ public class NetworkRequest implements Parcelable { * networks. */ public Builder setNetworkSpecifier(String networkSpecifier) { - if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER.equals(networkSpecifier)) { - throw new IllegalArgumentException("Invalid network specifier - must not be '" - + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'"); - } + /* + * A StringNetworkSpecifier does not accept null or empty ("") strings. When network + * specifiers were strings a null string and an empty string were considered equivalent. + * Hence no meaning is attached to a null or empty ("") string. + */ + return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null + : new StringNetworkSpecifier(networkSpecifier)); + } + + /** + * Sets the optional bearer specific network specifier. + * This has no meaning if a single transport is also not specified, so calling + * this without a single transport set will generate an exception, as will + * subsequently adding or removing transports after this is set. + * </p> + * + * @param networkSpecifier A concrete, parcelable framework class that extends + * NetworkSpecifier. + */ + public Builder setNetworkSpecifier(NetworkSpecifier networkSpecifier) { + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(networkSpecifier); mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); return this; } diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java new file mode 100644 index 000000000000..87a2b05a4430 --- /dev/null +++ b/core/java/android/net/NetworkSpecifier.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +/** + * Describes specific properties of a network for use in a {@link NetworkRequest}. + * + * Applications cannot instantiate this class by themselves, but can obtain instances of + * subclasses of this class via other APIs. + */ +public abstract class NetworkSpecifier { + /** @hide */ + public NetworkSpecifier() {} + + /** + * Returns true if a request with this {@link NetworkSpecifier} is satisfied by a network + * with the given NetworkSpecifier. + * + * @hide + */ + public abstract boolean satisfiedBy(NetworkSpecifier other); +} diff --git a/core/java/android/net/StringNetworkSpecifier.java b/core/java/android/net/StringNetworkSpecifier.java new file mode 100644 index 000000000000..cb7f6bfce713 --- /dev/null +++ b/core/java/android/net/StringNetworkSpecifier.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.internal.util.Preconditions; + +import java.util.Objects; + +/** @hide */ +public final class StringNetworkSpecifier extends NetworkSpecifier implements Parcelable { + /** + * Arbitrary string used to pass (additional) information to the network factory. + */ + public final String specifier; + + public StringNetworkSpecifier(String specifier) { + Preconditions.checkStringNotEmpty(specifier); + this.specifier = specifier; + } + + @Override + public boolean satisfiedBy(NetworkSpecifier other) { + return equals(other); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof StringNetworkSpecifier)) return false; + return TextUtils.equals(specifier, ((StringNetworkSpecifier) o).specifier); + } + + @Override + public int hashCode() { + return Objects.hashCode(specifier); + } + + @Override + public String toString() { + return specifier; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(specifier); + } + + public static final Parcelable.Creator<StringNetworkSpecifier> CREATOR = + new Parcelable.Creator<StringNetworkSpecifier>() { + public StringNetworkSpecifier createFromParcel(Parcel in) { + return new StringNetworkSpecifier(in.readString()); + } + public StringNetworkSpecifier[] newArray(int size) { + return new StringNetworkSpecifier[size]; + } + }; +} diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 9dde3e2a7076..4f8ff1d3caba 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -62,6 +62,7 @@ import android.net.LinkProperties.CompareResult; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; +import android.net.MatchAllNetworkSpecifier; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; @@ -4147,11 +4148,8 @@ public class ConnectivityService extends IConnectivityManager.Stub throw new IllegalArgumentException("Bad timeout specified"); } - if (NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER - .equals(networkCapabilities.getNetworkSpecifier())) { - throw new IllegalArgumentException("Invalid network specifier - must not be '" - + NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER + "'"); - } + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( + networkCapabilities.getNetworkSpecifier()); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, nextNetworkRequestId(), type); @@ -4224,6 +4222,9 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( + networkCapabilities.getNetworkSpecifier()); + NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.REQUEST); NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); @@ -4285,6 +4286,9 @@ public class ConnectivityService extends IConnectivityManager.Stub nc.addCapability(NET_CAPABILITY_FOREGROUND); } + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( + networkCapabilities.getNetworkSpecifier()); + NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder); @@ -4302,6 +4306,9 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); } + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( + networkCapabilities.getNetworkSpecifier()); + NetworkRequest networkRequest = new NetworkRequest( new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 2f5c97d7c368..1be8d5e85660 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -48,6 +48,7 @@ import android.net.INetworkStatsService; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; +import android.net.MatchAllNetworkSpecifier; import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; @@ -57,7 +58,9 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkRequest; +import android.net.NetworkSpecifier; import android.net.RouteInfo; +import android.net.StringNetworkSpecifier; import android.net.metrics.IpConnectivityLog; import android.net.util.MultinetworkPolicyTracker; import android.os.ConditionVariable; @@ -70,12 +73,15 @@ import android.os.Message; import android.os.MessageQueue; import android.os.Messenger; import android.os.MessageQueue.IdleHandler; +import android.os.Parcel; +import android.os.Parcelable; import android.os.Process; import android.os.SystemClock; import android.provider.Settings; import android.test.AndroidTestCase; import android.test.mock.MockContentResolver; import android.test.suitebuilder.annotation.SmallTest; +import android.text.TextUtils; import android.util.Log; import android.util.LogPrinter; @@ -345,8 +351,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } - public void setNetworkSpecifier(String specifier) { - mNetworkCapabilities.setNetworkSpecifier(specifier); + public void setNetworkSpecifier(NetworkSpecifier networkSpecifier) { + mNetworkCapabilities.setNetworkSpecifier(networkSpecifier); mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); } @@ -1866,16 +1872,19 @@ public class ConnectivityServiceTest extends AndroidTestCase { @SmallTest public void testNetworkSpecifier() { - NetworkRequest.Builder b = new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI); NetworkRequest rEmpty1 = newWifiRequestBuilder().build(); - NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier(null).build(); + NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build(); NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build(); + NetworkRequest rEmpty4 = newWifiRequestBuilder().setNetworkSpecifier( + (NetworkSpecifier) null).build(); NetworkRequest rFoo = newWifiRequestBuilder().setNetworkSpecifier("foo").build(); - NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier("bar").build(); + NetworkRequest rBar = newWifiRequestBuilder().setNetworkSpecifier( + new StringNetworkSpecifier("bar")).build(); TestNetworkCallback cEmpty1 = new TestNetworkCallback(); TestNetworkCallback cEmpty2 = new TestNetworkCallback(); TestNetworkCallback cEmpty3 = new TestNetworkCallback(); + TestNetworkCallback cEmpty4 = new TestNetworkCallback(); TestNetworkCallback cFoo = new TestNetworkCallback(); TestNetworkCallback cBar = new TestNetworkCallback(); TestNetworkCallback[] emptyCallbacks = new TestNetworkCallback[] { @@ -1884,6 +1893,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.registerNetworkCallback(rEmpty1, cEmpty1); mCm.registerNetworkCallback(rEmpty2, cEmpty2); mCm.registerNetworkCallback(rEmpty3, cEmpty3); + mCm.registerNetworkCallback(rEmpty4, cEmpty4); mCm.registerNetworkCallback(rFoo, cFoo); mCm.registerNetworkCallback(rBar, cBar); @@ -1892,9 +1902,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { cEmpty1.expectAvailableCallbacks(mWiFiNetworkAgent); cEmpty2.expectAvailableCallbacks(mWiFiNetworkAgent); cEmpty3.expectAvailableCallbacks(mWiFiNetworkAgent); + cEmpty4.expectAvailableCallbacks(mWiFiNetworkAgent); assertNoCallbacks(cFoo, cBar); - mWiFiNetworkAgent.setNetworkSpecifier("foo"); + mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("foo")); cFoo.expectAvailableCallbacks(mWiFiNetworkAgent); for (TestNetworkCallback c: emptyCallbacks) { c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); @@ -1902,7 +1913,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { cFoo.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent); cFoo.assertNoCallback(); - mWiFiNetworkAgent.setNetworkSpecifier("bar"); + mWiFiNetworkAgent.setNetworkSpecifier(new StringNetworkSpecifier("bar")); cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); cBar.expectAvailableCallbacks(mWiFiNetworkAgent); for (TestNetworkCallback c: emptyCallbacks) { @@ -1922,32 +1933,63 @@ public class ConnectivityServiceTest extends AndroidTestCase { @SmallTest public void testInvalidNetworkSpecifier() { - boolean execptionCalled = true; - try { NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.setNetworkSpecifier(MATCH_ALL_REQUESTS_NETWORK_SPECIFIER); - execptionCalled = false; - } catch (IllegalArgumentException e) { - // do nothing - should get here + builder.setNetworkSpecifier(new MatchAllNetworkSpecifier()); + fail("NetworkRequest builder with MatchAllNetworkSpecifier"); + } catch (IllegalArgumentException expected) { + // expected } - assertTrue("NetworkRequest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER", - execptionCalled); - try { NetworkCapabilities networkCapabilities = new NetworkCapabilities(); networkCapabilities.addTransportType(TRANSPORT_WIFI) - .setNetworkSpecifier(NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER); + .setNetworkSpecifier(new MatchAllNetworkSpecifier()); mService.requestNetwork(networkCapabilities, null, 0, null, ConnectivityManager.TYPE_WIFI); - execptionCalled = false; - } catch (IllegalArgumentException e) { - // do nothing - should get here + fail("ConnectivityService requestNetwork with MatchAllNetworkSpecifier"); + } catch (IllegalArgumentException expected) { + // expected + } + + class NonParcelableSpecifier extends NetworkSpecifier { + public boolean satisfiedBy(NetworkSpecifier other) { return false; } + }; + class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable { + @Override public int describeContents() { return 0; } + @Override public void writeToParcel(Parcel p, int flags) {} + } + NetworkRequest.Builder builder; + + builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); + try { + builder.setNetworkSpecifier(new NonParcelableSpecifier()); + Parcel parcelW = Parcel.obtain(); + builder.build().writeToParcel(parcelW, 0); + fail("Parceling a non-parcelable specifier did not throw an exception"); + } catch (Exception e) { + // expected } - assertTrue("ConnectivityService requestNetwork with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER", - execptionCalled); + builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET); + builder.setNetworkSpecifier(new ParcelableSpecifier()); + NetworkRequest nr = builder.build(); + assertNotNull(nr); + + try { + Parcel parcelW = Parcel.obtain(); + nr.writeToParcel(parcelW, 0); + byte[] bytes = parcelW.marshall(); + parcelW.recycle(); + + Parcel parcelR = Parcel.obtain(); + parcelR.unmarshall(bytes, 0, bytes.length); + parcelR.setDataPosition(0); + NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR); + fail("Unparceling a non-framework NetworkSpecifier did not throw an exception"); + } catch (Exception e) { + // expected + } } @SmallTest |