Create VcnCellUnderlyingNetworkPriority
Create VcnCellUnderlyingNetworkPriority to allow VCN callers to configure network prioritization. Bug: 206044122 Test: atest FrameworksVcnTests(new tests) Test: atest CtsVcnTestCases Change-Id: Ia7f44c5f956ff75c39e20d9761f1bd5c987644ee
This commit is contained in:
291
core/java/android/net/vcn/VcnCellUnderlyingNetworkPriority.java
Normal file
291
core/java/android/net/vcn/VcnCellUnderlyingNetworkPriority.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.vcn;
|
||||
|
||||
import static com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||
import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_DESERIALIZER;
|
||||
import static com.android.server.vcn.util.PersistableBundleUtils.INTEGER_SERIALIZER;
|
||||
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
|
||||
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_SERIALIZER;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.PersistableBundle;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.vcn.util.PersistableBundleUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO: Add documents
|
||||
/** @hide */
|
||||
public final class VcnCellUnderlyingNetworkPriority extends VcnUnderlyingNetworkPriority {
|
||||
private static final String ALLOWED_NETWORK_PLMN_IDS_KEY = "mAllowedNetworkPlmnIds";
|
||||
@NonNull private final Set<String> mAllowedNetworkPlmnIds;
|
||||
private static final String ALLOWED_SPECIFIC_CARRIER_IDS_KEY = "mAllowedSpecificCarrierIds";
|
||||
@NonNull private final Set<Integer> mAllowedSpecificCarrierIds;
|
||||
|
||||
private static final String ALLOW_ROAMING_KEY = "mAllowRoaming";
|
||||
private final boolean mAllowRoaming;
|
||||
|
||||
private static final String REQUIRE_OPPORTUNISTIC_KEY = "mRequireOpportunistic";
|
||||
private final boolean mRequireOpportunistic;
|
||||
|
||||
private VcnCellUnderlyingNetworkPriority(
|
||||
int networkQuality,
|
||||
boolean allowMetered,
|
||||
Set<String> allowedNetworkPlmnIds,
|
||||
Set<Integer> allowedSpecificCarrierIds,
|
||||
boolean allowRoaming,
|
||||
boolean requireOpportunistic) {
|
||||
super(NETWORK_PRIORITY_TYPE_CELL, networkQuality, allowMetered);
|
||||
mAllowedNetworkPlmnIds = new ArraySet<>(allowedNetworkPlmnIds);
|
||||
mAllowedSpecificCarrierIds = new ArraySet<>(allowedSpecificCarrierIds);
|
||||
mAllowRoaming = allowRoaming;
|
||||
mRequireOpportunistic = requireOpportunistic;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
protected void validate() {
|
||||
super.validate();
|
||||
validatePlmnIds(mAllowedNetworkPlmnIds);
|
||||
Objects.requireNonNull(mAllowedSpecificCarrierIds, "allowedCarrierIds is null");
|
||||
}
|
||||
|
||||
private static void validatePlmnIds(Set<String> allowedNetworkPlmnIds) {
|
||||
Objects.requireNonNull(allowedNetworkPlmnIds, "allowedNetworkPlmnIds is null");
|
||||
|
||||
// A valid PLMN is a concatenation of MNC and MCC, and thus consists of 5 or 6 decimal
|
||||
// digits.
|
||||
for (String id : allowedNetworkPlmnIds) {
|
||||
if ((id.length() == 5 || id.length() == 6) && id.matches("[0-9]+")) {
|
||||
continue;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Found invalid PLMN ID: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@NonNull
|
||||
@VisibleForTesting(visibility = Visibility.PROTECTED)
|
||||
public static VcnCellUnderlyingNetworkPriority fromPersistableBundle(
|
||||
@NonNull PersistableBundle in) {
|
||||
Objects.requireNonNull(in, "PersistableBundle is null");
|
||||
|
||||
final int networkQuality = in.getInt(NETWORK_QUALITY_KEY);
|
||||
final boolean allowMetered = in.getBoolean(ALLOW_METERED_KEY);
|
||||
|
||||
final PersistableBundle plmnIdsBundle =
|
||||
in.getPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY);
|
||||
Objects.requireNonNull(plmnIdsBundle, "plmnIdsBundle is null");
|
||||
final Set<String> allowedNetworkPlmnIds =
|
||||
new ArraySet<String>(
|
||||
PersistableBundleUtils.toList(plmnIdsBundle, STRING_DESERIALIZER));
|
||||
|
||||
final PersistableBundle specificCarrierIdsBundle =
|
||||
in.getPersistableBundle(ALLOWED_SPECIFIC_CARRIER_IDS_KEY);
|
||||
Objects.requireNonNull(specificCarrierIdsBundle, "specificCarrierIdsBundle is null");
|
||||
final Set<Integer> allowedSpecificCarrierIds =
|
||||
new ArraySet<Integer>(
|
||||
PersistableBundleUtils.toList(
|
||||
specificCarrierIdsBundle, INTEGER_DESERIALIZER));
|
||||
|
||||
final boolean allowRoaming = in.getBoolean(ALLOW_ROAMING_KEY);
|
||||
final boolean requireOpportunistic = in.getBoolean(REQUIRE_OPPORTUNISTIC_KEY);
|
||||
|
||||
return new VcnCellUnderlyingNetworkPriority(
|
||||
networkQuality,
|
||||
allowMetered,
|
||||
allowedNetworkPlmnIds,
|
||||
allowedSpecificCarrierIds,
|
||||
allowRoaming,
|
||||
requireOpportunistic);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
@NonNull
|
||||
@VisibleForTesting(visibility = Visibility.PROTECTED)
|
||||
public PersistableBundle toPersistableBundle() {
|
||||
final PersistableBundle result = super.toPersistableBundle();
|
||||
|
||||
final PersistableBundle plmnIdsBundle =
|
||||
PersistableBundleUtils.fromList(
|
||||
new ArrayList<>(mAllowedNetworkPlmnIds), STRING_SERIALIZER);
|
||||
result.putPersistableBundle(ALLOWED_NETWORK_PLMN_IDS_KEY, plmnIdsBundle);
|
||||
|
||||
final PersistableBundle specificCarrierIdsBundle =
|
||||
PersistableBundleUtils.fromList(
|
||||
new ArrayList<>(mAllowedSpecificCarrierIds), INTEGER_SERIALIZER);
|
||||
result.putPersistableBundle(ALLOWED_SPECIFIC_CARRIER_IDS_KEY, specificCarrierIdsBundle);
|
||||
|
||||
result.putBoolean(ALLOW_ROAMING_KEY, mAllowRoaming);
|
||||
result.putBoolean(REQUIRE_OPPORTUNISTIC_KEY, mRequireOpportunistic);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Retrieve the allowed PLMN IDs, or an empty set if any PLMN ID is acceptable. */
|
||||
@NonNull
|
||||
public Set<String> getAllowedPlmnIds() {
|
||||
return Collections.unmodifiableSet(mAllowedNetworkPlmnIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the allowed specific carrier IDs, or an empty set if any specific carrier ID is
|
||||
* acceptable.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<Integer> getAllowedSpecificCarrierIds() {
|
||||
return Collections.unmodifiableSet(mAllowedSpecificCarrierIds);
|
||||
}
|
||||
|
||||
/** Return if roaming is allowed. */
|
||||
public boolean allowRoaming() {
|
||||
return mAllowRoaming;
|
||||
}
|
||||
|
||||
/** Return if requiring an opportunistic network. */
|
||||
public boolean requireOpportunistic() {
|
||||
return mRequireOpportunistic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
super.hashCode(),
|
||||
mAllowedNetworkPlmnIds,
|
||||
mAllowedSpecificCarrierIds,
|
||||
mAllowRoaming,
|
||||
mRequireOpportunistic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (!super.equals(other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(other instanceof VcnCellUnderlyingNetworkPriority)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final VcnCellUnderlyingNetworkPriority rhs = (VcnCellUnderlyingNetworkPriority) other;
|
||||
return Objects.equals(mAllowedNetworkPlmnIds, rhs.mAllowedNetworkPlmnIds)
|
||||
&& Objects.equals(mAllowedSpecificCarrierIds, rhs.mAllowedSpecificCarrierIds)
|
||||
&& mAllowRoaming == rhs.mAllowRoaming
|
||||
&& mRequireOpportunistic == rhs.mRequireOpportunistic;
|
||||
}
|
||||
|
||||
/** This class is used to incrementally build WifiNetworkPriority objects. */
|
||||
public static class Builder extends VcnUnderlyingNetworkPriority.Builder<Builder> {
|
||||
@NonNull private final Set<String> mAllowedNetworkPlmnIds = new ArraySet<>();
|
||||
@NonNull private final Set<Integer> mAllowedSpecificCarrierIds = new ArraySet<>();
|
||||
|
||||
private boolean mAllowRoaming = false;
|
||||
private boolean mRequireOpportunistic = false;
|
||||
|
||||
/** Construct a Builder object. */
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Set allowed operator PLMN IDs.
|
||||
*
|
||||
* <p>This is used to distinguish cases where roaming agreements may dictate a different
|
||||
* priority from a partner's networks.
|
||||
*
|
||||
* @param allowedNetworkPlmnIds the allowed operator PLMN IDs in String. Defaults to an
|
||||
* empty set, allowing ANY PLMN ID. A valid PLMN is a concatenation of MNC and MCC, and
|
||||
* thus consists of 5 or 6 decimal digits. See {@link SubscriptionInfo#getMccString()}
|
||||
* and {@link SubscriptionInfo#getMncString()}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAllowedPlmnIds(@NonNull Set<String> allowedNetworkPlmnIds) {
|
||||
validatePlmnIds(allowedNetworkPlmnIds);
|
||||
|
||||
mAllowedNetworkPlmnIds.clear();
|
||||
mAllowedNetworkPlmnIds.addAll(allowedNetworkPlmnIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set allowed specific carrier IDs.
|
||||
*
|
||||
* @param allowedSpecificCarrierIds the allowed specific carrier IDs. Defaults to an empty
|
||||
* set, allowing ANY carrier ID. See {@link TelephonyManager#getSimSpecificCarrierId()}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAllowedSpecificCarrierIds(
|
||||
@NonNull Set<Integer> allowedSpecificCarrierIds) {
|
||||
Objects.requireNonNull(allowedSpecificCarrierIds, "allowedCarrierIds is null");
|
||||
mAllowedSpecificCarrierIds.clear();
|
||||
mAllowedSpecificCarrierIds.addAll(allowedSpecificCarrierIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if roaming is allowed.
|
||||
*
|
||||
* @param allowRoaming the flag to indicate if roaming is allowed. Defaults to {@code
|
||||
* false}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAllowRoaming(boolean allowRoaming) {
|
||||
mAllowRoaming = allowRoaming;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if requiring an opportunistic network.
|
||||
*
|
||||
* @param requireOpportunistic the flag to indicate if caller requires an opportunistic
|
||||
* network. Defaults to {@code false}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setRequireOpportunistic(boolean requireOpportunistic) {
|
||||
mRequireOpportunistic = requireOpportunistic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Build the VcnCellUnderlyingNetworkPriority. */
|
||||
@NonNull
|
||||
public VcnCellUnderlyingNetworkPriority build() {
|
||||
return new VcnCellUnderlyingNetworkPriority(
|
||||
mNetworkQuality,
|
||||
mAllowMetered,
|
||||
mAllowedNetworkPlmnIds,
|
||||
mAllowedSpecificCarrierIds,
|
||||
mAllowRoaming,
|
||||
mRequireOpportunistic);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
Builder self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public abstract class VcnUnderlyingNetworkPriority {
|
||||
case NETWORK_PRIORITY_TYPE_WIFI:
|
||||
return VcnWifiUnderlyingNetworkPriority.fromPersistableBundle(in);
|
||||
case NETWORK_PRIORITY_TYPE_CELL:
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
return VcnCellUnderlyingNetworkPriority.fromPersistableBundle(in);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid networkPriorityType:" + networkPriorityType);
|
||||
|
||||
@@ -46,6 +46,7 @@ public class PersistableBundleUtils {
|
||||
private static final String PARCEL_UUID_KEY = "PARCEL_UUID";
|
||||
private static final String BYTE_ARRAY_KEY = "BYTE_ARRAY_KEY";
|
||||
private static final String INTEGER_KEY = "INTEGER_KEY";
|
||||
private static final String STRING_KEY = "STRING_KEY";
|
||||
|
||||
/**
|
||||
* Functional interface to convert an object of the specified type to a PersistableBundle.
|
||||
@@ -91,6 +92,21 @@ public class PersistableBundleUtils {
|
||||
return bundle.getInt(INTEGER_KEY);
|
||||
};
|
||||
|
||||
/** Serializer to convert s String to a PersistableBundle. */
|
||||
public static final Serializer<String> STRING_SERIALIZER =
|
||||
(i) -> {
|
||||
final PersistableBundle result = new PersistableBundle();
|
||||
result.putString(STRING_KEY, i);
|
||||
return result;
|
||||
};
|
||||
|
||||
/** Deserializer to convert a PersistableBundle to a String. */
|
||||
public static final Deserializer<String> STRING_DESERIALIZER =
|
||||
(bundle) -> {
|
||||
Objects.requireNonNull(bundle, "PersistableBundle is null");
|
||||
return bundle.getString(STRING_KEY);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a ParcelUuid to a PersistableBundle.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.vcn;
|
||||
|
||||
import static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_ANY;
|
||||
import static android.net.vcn.VcnUnderlyingNetworkPriority.NETWORK_QUALITY_OK;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class VcnCellUnderlyingNetworkPriorityTest {
|
||||
private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
|
||||
private static final Set<Integer> ALLOWED_CARRIER_IDS = new HashSet<>();
|
||||
|
||||
private static VcnCellUnderlyingNetworkPriority getTestNetworkPriority() {
|
||||
return new VcnCellUnderlyingNetworkPriority.Builder()
|
||||
.setNetworkQuality(NETWORK_QUALITY_OK)
|
||||
.setAllowMetered(true /* allowMetered */)
|
||||
.setAllowedPlmnIds(ALLOWED_PLMN_IDS)
|
||||
.setAllowedSpecificCarrierIds(ALLOWED_CARRIER_IDS)
|
||||
.setAllowRoaming(true /* allowRoaming */)
|
||||
.setRequireOpportunistic(true /* requireOpportunistic */)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilderAndGetters() {
|
||||
final VcnCellUnderlyingNetworkPriority networkPriority = getTestNetworkPriority();
|
||||
assertEquals(NETWORK_QUALITY_OK, networkPriority.getNetworkQuality());
|
||||
assertTrue(networkPriority.allowMetered());
|
||||
assertEquals(ALLOWED_PLMN_IDS, networkPriority.getAllowedPlmnIds());
|
||||
assertEquals(ALLOWED_CARRIER_IDS, networkPriority.getAllowedSpecificCarrierIds());
|
||||
assertTrue(networkPriority.allowRoaming());
|
||||
assertTrue(networkPriority.requireOpportunistic());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuilderAndGettersForDefaultValues() {
|
||||
final VcnCellUnderlyingNetworkPriority networkPriority =
|
||||
new VcnCellUnderlyingNetworkPriority.Builder().build();
|
||||
assertEquals(NETWORK_QUALITY_ANY, networkPriority.getNetworkQuality());
|
||||
assertFalse(networkPriority.allowMetered());
|
||||
assertEquals(new HashSet<String>(), networkPriority.getAllowedPlmnIds());
|
||||
assertEquals(new HashSet<Integer>(), networkPriority.getAllowedSpecificCarrierIds());
|
||||
assertFalse(networkPriority.allowRoaming());
|
||||
assertFalse(networkPriority.requireOpportunistic());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistableBundle() {
|
||||
final VcnCellUnderlyingNetworkPriority networkPriority = getTestNetworkPriority();
|
||||
assertEquals(
|
||||
networkPriority,
|
||||
VcnUnderlyingNetworkPriority.fromPersistableBundle(
|
||||
networkPriority.toPersistableBundle()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user