Replace StringNetworkSpecifier & subId with TelephonyNetworkSpecifer
StringNetworkSpecifier is widely used to specify subscription id for
the NetworkRequest. The raw string field introduce ambiguity and leave
large space for bugs. With TelephonyNetworkSpecifer, we are able to
settle down the type and value of the fields (although currently only
one) and introduce validation to detect the bug in the beginning.
Bug: 145993724
Test: atest FrameworksNetTests FrameworksTelephonyTests &
make offline-sdk-docs
Change-Id: Iefbad9b1deb3de2c0b262d9ce5ae0704a50d08a6
This commit is contained in:
@@ -300,23 +300,35 @@ public class NetworkRequest implements Parcelable {
|
|||||||
* this without a single transport set will generate an exception, as will
|
* this without a single transport set will generate an exception, as will
|
||||||
* subsequently adding or removing transports after this is set.
|
* subsequently adding or removing transports after this is set.
|
||||||
* </p>
|
* </p>
|
||||||
* The interpretation of this {@code String} is bearer specific and bearers that use
|
* If the {@code networkSpecifier} is provided, it shall be interpreted as follows:
|
||||||
* it should document their particulars. For example, Bluetooth may use some sort of
|
* <ul>
|
||||||
* device id while WiFi could used ssid and/or bssid. Cellular may use carrier spn.
|
* <li>If the specifier can be parsed as an integer, it will be treated as a
|
||||||
|
* {@link android.net TelephonyNetworkSpecifier}, and the provided integer will be
|
||||||
|
* interpreted as a SubscriptionId.
|
||||||
|
* <li>If the value is an ethernet interface name, it will be treated as such.
|
||||||
|
* <li>For all other cases, the behavior is undefined.
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param networkSpecifier An {@code String} of opaque format used to specify the bearer
|
* @param networkSpecifier A {@code String} of either a SubscriptionId in cellular
|
||||||
* specific network specifier where the bearer has a choice of
|
* network request or an ethernet interface name in ethernet
|
||||||
* networks.
|
* network request.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #setNetworkSpecifier(NetworkSpecifier)} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setNetworkSpecifier(String networkSpecifier) {
|
public Builder setNetworkSpecifier(String networkSpecifier) {
|
||||||
/*
|
try {
|
||||||
* A StringNetworkSpecifier does not accept null or empty ("") strings. When network
|
int subId = Integer.parseInt(networkSpecifier);
|
||||||
* specifiers were strings a null string and an empty string were considered equivalent.
|
return setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
|
||||||
* Hence no meaning is attached to a null or empty ("") string.
|
.setSubscriptionId(subId).build());
|
||||||
*/
|
} catch (NumberFormatException nfe) {
|
||||||
|
// 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
|
return setNetworkSpecifier(TextUtils.isEmpty(networkSpecifier) ? null
|
||||||
: new StringNetworkSpecifier(networkSpecifier));
|
: new StringNetworkSpecifier(networkSpecifier));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the optional bearer specific network specifier.
|
* Sets the optional bearer specific network specifier.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.NetworkSpecifier;
|
import android.net.NetworkSpecifier;
|
||||||
import android.net.StringNetworkSpecifier;
|
import android.net.TelephonyNetworkSpecifier;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
@@ -223,14 +223,8 @@ public class NetworkNotificationManager {
|
|||||||
// name has been added to it
|
// name has been added to it
|
||||||
NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
|
NetworkSpecifier specifier = nai.networkCapabilities.getNetworkSpecifier();
|
||||||
int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
|
int subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
|
||||||
if (specifier instanceof StringNetworkSpecifier) {
|
if (specifier instanceof TelephonyNetworkSpecifier) {
|
||||||
try {
|
subId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
|
||||||
subId = Integer.parseInt(
|
|
||||||
((StringNetworkSpecifier) specifier).specifier);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Slog.e(TAG, "NumberFormatException on "
|
|
||||||
+ ((StringNetworkSpecifier) specifier).specifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
details = mTelephonyManager.createForSubscriptionId(subId)
|
details = mTelephonyManager.createForSubscriptionId(subId)
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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 static com.android.testutils.ParcelUtilsKt.assertParcelSane;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for {@link android.net.TelephonyNetworkSpecifier}.
|
||||||
|
*/
|
||||||
|
@SmallTest
|
||||||
|
public class TelephonyNetworkSpecifierTest {
|
||||||
|
private static final int TEST_SUBID = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that IllegalArgumentException will be thrown if build TelephonyNetworkSpecifier
|
||||||
|
* without calling {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testBuilderBuildWithDefault() {
|
||||||
|
try {
|
||||||
|
new TelephonyNetworkSpecifier.Builder().build();
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
// expected, test pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that no exception will be thrown even if pass invalid subscription id to
|
||||||
|
* {@link TelephonyNetworkSpecifier.Builder#setSubscriptionId(int)}.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testBuilderBuildWithInvalidSubId() {
|
||||||
|
TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder()
|
||||||
|
.setSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
|
||||||
|
.build();
|
||||||
|
assertEquals(specifier.getSubscriptionId(), SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the correctness of TelephonyNetworkSpecifier when provide valid subId.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testBuilderBuildWithValidSubId() {
|
||||||
|
final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder()
|
||||||
|
.setSubscriptionId(TEST_SUBID)
|
||||||
|
.build();
|
||||||
|
assertEquals(TEST_SUBID, specifier.getSubscriptionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that parcel marshalling/unmarshalling works.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testParcel() {
|
||||||
|
TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier.Builder()
|
||||||
|
.setSubscriptionId(TEST_SUBID)
|
||||||
|
.build();
|
||||||
|
assertParcelSane(specifier, 1 /* fieldCount */);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,7 @@ import android.net.NetworkPolicy;
|
|||||||
import android.net.NetworkPolicyManager;
|
import android.net.NetworkPolicyManager;
|
||||||
import android.net.NetworkTemplate;
|
import android.net.NetworkTemplate;
|
||||||
import android.net.StringNetworkSpecifier;
|
import android.net.StringNetworkSpecifier;
|
||||||
|
import android.net.TelephonyNetworkSpecifier;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
@@ -229,7 +230,7 @@ public class MultipathPolicyTrackerTest {
|
|||||||
verify(mCM).registerNetworkCallback(any(), networkCallback.capture(), any());
|
verify(mCM).registerNetworkCallback(any(), networkCallback.capture(), any());
|
||||||
|
|
||||||
// Simulate callback after capability changes
|
// Simulate callback after capability changes
|
||||||
final NetworkCapabilities capabilities = new NetworkCapabilities()
|
NetworkCapabilities capabilities = new NetworkCapabilities()
|
||||||
.addCapability(NET_CAPABILITY_INTERNET)
|
.addCapability(NET_CAPABILITY_INTERNET)
|
||||||
.addTransportType(TRANSPORT_CELLULAR)
|
.addTransportType(TRANSPORT_CELLULAR)
|
||||||
.setNetworkSpecifier(new StringNetworkSpecifier("234"));
|
.setNetworkSpecifier(new StringNetworkSpecifier("234"));
|
||||||
@@ -239,6 +240,19 @@ public class MultipathPolicyTrackerTest {
|
|||||||
networkCallback.getValue().onCapabilitiesChanged(
|
networkCallback.getValue().onCapabilitiesChanged(
|
||||||
TEST_NETWORK,
|
TEST_NETWORK,
|
||||||
capabilities);
|
capabilities);
|
||||||
|
|
||||||
|
// make sure it also works with the new introduced TelephonyNetworkSpecifier
|
||||||
|
capabilities = new NetworkCapabilities()
|
||||||
|
.addCapability(NET_CAPABILITY_INTERNET)
|
||||||
|
.addTransportType(TRANSPORT_CELLULAR)
|
||||||
|
.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
|
||||||
|
.setSubscriptionId(234).build());
|
||||||
|
if (!roaming) {
|
||||||
|
capabilities.addCapability(NET_CAPABILITY_NOT_ROAMING);
|
||||||
|
}
|
||||||
|
networkCallback.getValue().onCapabilitiesChanged(
|
||||||
|
TEST_NETWORK,
|
||||||
|
capabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user