Merge "Add CarrierConfig to TelephonySubscriptionSnapshot" am: 59aeaf29c0
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2063410 Change-Id: I5e09fea770734d71241008395045dd9ddddc0ca6 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -104,6 +104,14 @@ public class VcnManager {
|
|||||||
|
|
||||||
// TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz
|
// TODO: Add separate signal strength thresholds for 2.4 GHz and 5GHz
|
||||||
|
|
||||||
|
/** List of Carrier Config options to extract from Carrier Config bundles. @hide */
|
||||||
|
@NonNull
|
||||||
|
public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
|
||||||
|
new String[] {
|
||||||
|
VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
||||||
|
VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY
|
||||||
|
};
|
||||||
|
|
||||||
private static final Map<
|
private static final Map<
|
||||||
VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
|
VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder>
|
||||||
REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
|
REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.net.vcn.VcnManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerExecutor;
|
import android.os.HandlerExecutor;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
@@ -47,6 +48,8 @@ import android.util.Slog;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
import com.android.server.vcn.util.PersistableBundleUtils;
|
||||||
|
import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -95,6 +98,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
// TODO (Android T+): Add ability to handle multiple subIds per slot.
|
// TODO (Android T+): Add ability to handle multiple subIds per slot.
|
||||||
@NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
|
@NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap = new HashMap<>();
|
||||||
|
|
||||||
@NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
|
@NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -250,7 +257,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
final TelephonySubscriptionSnapshot newSnapshot =
|
final TelephonySubscriptionSnapshot newSnapshot =
|
||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
mDeps.getActiveDataSubscriptionId(), newSubIdToInfoMap, privilegedPackages);
|
mDeps.getActiveDataSubscriptionId(),
|
||||||
|
newSubIdToInfoMap,
|
||||||
|
mSubIdToCarrierConfigMap,
|
||||||
|
privilegedPackages);
|
||||||
|
|
||||||
// If snapshot was meaningfully updated, fire the callback
|
// If snapshot was meaningfully updated, fire the callback
|
||||||
if (!newSnapshot.equals(mCurrentSnapshot)) {
|
if (!newSnapshot.equals(mCurrentSnapshot)) {
|
||||||
@@ -311,47 +321,77 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SubscriptionManager.isValidSubscriptionId(subId)) {
|
if (SubscriptionManager.isValidSubscriptionId(subId)) {
|
||||||
final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
|
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
|
||||||
if (mDeps.isConfigForIdentifiedCarrier(carrierConfigs)) {
|
if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
|
||||||
mReadySubIdsBySlotId.put(slotId, subId);
|
mReadySubIdsBySlotId.put(slotId, subId);
|
||||||
|
|
||||||
|
final PersistableBundle minimized =
|
||||||
|
PersistableBundleUtils.minimizeBundle(
|
||||||
|
carrierConfig, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
|
||||||
|
if (minimized != null) {
|
||||||
|
mSubIdToCarrierConfigMap.put(subId, new PersistableBundleWrapper(minimized));
|
||||||
|
}
|
||||||
handleSubscriptionsChanged();
|
handleSubscriptionsChanged();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mReadySubIdsBySlotId.remove(slotId);
|
final Integer oldSubid = mReadySubIdsBySlotId.remove(slotId);
|
||||||
|
if (oldSubid != null) {
|
||||||
|
mSubIdToCarrierConfigMap.remove(oldSubid);
|
||||||
|
}
|
||||||
handleSubscriptionsChanged();
|
handleSubscriptionsChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
void setReadySubIdsBySlotId(Map<Integer, Integer> readySubIdsBySlotId) {
|
void setReadySubIdsBySlotId(Map<Integer, Integer> readySubIdsBySlotId) {
|
||||||
|
mReadySubIdsBySlotId.clear();
|
||||||
mReadySubIdsBySlotId.putAll(readySubIdsBySlotId);
|
mReadySubIdsBySlotId.putAll(readySubIdsBySlotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
void setSubIdToCarrierConfigMap(
|
||||||
|
Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap) {
|
||||||
|
mSubIdToCarrierConfigMap.clear();
|
||||||
|
mSubIdToCarrierConfigMap.putAll(subIdToCarrierConfigMap);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
Map<Integer, Integer> getReadySubIdsBySlotId() {
|
Map<Integer, Integer> getReadySubIdsBySlotId() {
|
||||||
return Collections.unmodifiableMap(mReadySubIdsBySlotId);
|
return Collections.unmodifiableMap(mReadySubIdsBySlotId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
|
Map<Integer, PersistableBundleWrapper> getSubIdToCarrierConfigMap() {
|
||||||
|
return Collections.unmodifiableMap(mSubIdToCarrierConfigMap);
|
||||||
|
}
|
||||||
|
|
||||||
/** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
|
/** TelephonySubscriptionSnapshot is a class containing info about active subscriptions */
|
||||||
public static class TelephonySubscriptionSnapshot {
|
public static class TelephonySubscriptionSnapshot {
|
||||||
private final int mActiveDataSubId;
|
private final int mActiveDataSubId;
|
||||||
private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
|
private final Map<Integer, SubscriptionInfo> mSubIdToInfoMap;
|
||||||
|
private final Map<Integer, PersistableBundleWrapper> mSubIdToCarrierConfigMap;
|
||||||
private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;
|
private final Map<ParcelUuid, Set<String>> mPrivilegedPackages;
|
||||||
|
|
||||||
public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
|
public static final TelephonySubscriptionSnapshot EMPTY_SNAPSHOT =
|
||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
INVALID_SUBSCRIPTION_ID, Collections.emptyMap(), Collections.emptyMap());
|
INVALID_SUBSCRIPTION_ID,
|
||||||
|
Collections.emptyMap(),
|
||||||
|
Collections.emptyMap(),
|
||||||
|
Collections.emptyMap());
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
TelephonySubscriptionSnapshot(
|
TelephonySubscriptionSnapshot(
|
||||||
int activeDataSubId,
|
int activeDataSubId,
|
||||||
@NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
@NonNull Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
|
@NonNull Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap,
|
||||||
@NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
|
@NonNull Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
mActiveDataSubId = activeDataSubId;
|
mActiveDataSubId = activeDataSubId;
|
||||||
Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
|
Objects.requireNonNull(subIdToInfoMap, "subIdToInfoMap was null");
|
||||||
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
|
Objects.requireNonNull(privilegedPackages, "privilegedPackages was null");
|
||||||
|
Objects.requireNonNull(subIdToCarrierConfigMap, "subIdToCarrierConfigMap was null");
|
||||||
|
|
||||||
mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
|
mSubIdToInfoMap = Collections.unmodifiableMap(subIdToInfoMap);
|
||||||
|
mSubIdToCarrierConfigMap = Collections.unmodifiableMap(subIdToCarrierConfigMap);
|
||||||
|
|
||||||
final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
|
final Map<ParcelUuid, Set<String>> unmodifiableInnerSets = new ArrayMap<>();
|
||||||
for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
|
for (Entry<ParcelUuid, Set<String>> entry : privilegedPackages.entrySet()) {
|
||||||
@@ -423,9 +463,40 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a carrier config for a subscription in the provided group.
|
||||||
|
*
|
||||||
|
* <p>This method will prioritize non-opportunistic subscriptions, but will use the a
|
||||||
|
* carrier config for an opportunistic subscription if no other subscriptions are found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public PersistableBundleWrapper getCarrierConfigForSubGrp(@NonNull ParcelUuid subGrp) {
|
||||||
|
PersistableBundleWrapper result = null;
|
||||||
|
|
||||||
|
for (int subId : getAllSubIdsInGroup(subGrp)) {
|
||||||
|
final PersistableBundleWrapper config = mSubIdToCarrierConfigMap.get(subId);
|
||||||
|
if (config != null) {
|
||||||
|
result = config;
|
||||||
|
|
||||||
|
// Attempt to use (any) non-opportunistic subscription. If this subscription is
|
||||||
|
// opportunistic, continue and try to find a non-opportunistic subscription,
|
||||||
|
// using the opportunistic ones as a last resort.
|
||||||
|
if (!isOpportunistic(subId)) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mActiveDataSubId, mSubIdToInfoMap, mPrivilegedPackages);
|
return Objects.hash(
|
||||||
|
mActiveDataSubId,
|
||||||
|
mSubIdToInfoMap,
|
||||||
|
mSubIdToCarrierConfigMap,
|
||||||
|
mPrivilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -438,6 +509,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
return mActiveDataSubId == other.mActiveDataSubId
|
return mActiveDataSubId == other.mActiveDataSubId
|
||||||
&& mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
|
&& mSubIdToInfoMap.equals(other.mSubIdToInfoMap)
|
||||||
|
&& mSubIdToCarrierConfigMap.equals(other.mSubIdToCarrierConfigMap)
|
||||||
&& mPrivilegedPackages.equals(other.mPrivilegedPackages);
|
&& mPrivilegedPackages.equals(other.mPrivilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +520,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
|
|
||||||
pw.println("mActiveDataSubId: " + mActiveDataSubId);
|
pw.println("mActiveDataSubId: " + mActiveDataSubId);
|
||||||
pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
|
pw.println("mSubIdToInfoMap: " + mSubIdToInfoMap);
|
||||||
|
pw.println("mSubIdToCarrierConfigMap: " + mSubIdToCarrierConfigMap);
|
||||||
pw.println("mPrivilegedPackages: " + mPrivilegedPackages);
|
pw.println("mPrivilegedPackages: " + mPrivilegedPackages);
|
||||||
|
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
@@ -458,6 +531,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
|||||||
return "TelephonySubscriptionSnapshot{ "
|
return "TelephonySubscriptionSnapshot{ "
|
||||||
+ "mActiveDataSubId=" + mActiveDataSubId
|
+ "mActiveDataSubId=" + mActiveDataSubId
|
||||||
+ ", mSubIdToInfoMap=" + mSubIdToInfoMap
|
+ ", mSubIdToInfoMap=" + mSubIdToInfoMap
|
||||||
|
+ ", mSubIdToCarrierConfigMap=" + mSubIdToCarrierConfigMap
|
||||||
+ ", mPrivilegedPackages=" + mPrivilegedPackages
|
+ ", mPrivilegedPackages=" + mPrivilegedPackages
|
||||||
+ " }";
|
+ " }";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
|
|||||||
import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
|
import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
|
||||||
|
|
||||||
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -34,7 +35,6 @@ import android.net.vcn.VcnManager;
|
|||||||
import android.net.vcn.VcnUnderlyingNetworkTemplate;
|
import android.net.vcn.VcnUnderlyingNetworkTemplate;
|
||||||
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
|
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -81,7 +81,7 @@ class NetworkPriorityClassifier {
|
|||||||
ParcelUuid subscriptionGroup,
|
ParcelUuid subscriptionGroup,
|
||||||
TelephonySubscriptionSnapshot snapshot,
|
TelephonySubscriptionSnapshot snapshot,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
// mRouteSelectionNetworkRequest requires a network be both VALIDATED and NOT_SUSPENDED
|
// mRouteSelectionNetworkRequest requires a network be both VALIDATED and NOT_SUSPENDED
|
||||||
|
|
||||||
if (networkRecord.isBlocked) {
|
if (networkRecord.isBlocked) {
|
||||||
@@ -119,7 +119,7 @@ class NetworkPriorityClassifier {
|
|||||||
ParcelUuid subscriptionGroup,
|
ParcelUuid subscriptionGroup,
|
||||||
TelephonySubscriptionSnapshot snapshot,
|
TelephonySubscriptionSnapshot snapshot,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
||||||
final boolean isSelectedUnderlyingNetwork =
|
final boolean isSelectedUnderlyingNetwork =
|
||||||
currentlySelected != null
|
currentlySelected != null
|
||||||
@@ -181,7 +181,7 @@ class NetworkPriorityClassifier {
|
|||||||
VcnWifiUnderlyingNetworkTemplate networkPriority,
|
VcnWifiUnderlyingNetworkTemplate networkPriority,
|
||||||
UnderlyingNetworkRecord networkRecord,
|
UnderlyingNetworkRecord networkRecord,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
||||||
|
|
||||||
if (!caps.hasTransport(TRANSPORT_WIFI)) {
|
if (!caps.hasTransport(TRANSPORT_WIFI)) {
|
||||||
@@ -204,7 +204,7 @@ class NetworkPriorityClassifier {
|
|||||||
private static boolean isWifiRssiAcceptable(
|
private static boolean isWifiRssiAcceptable(
|
||||||
UnderlyingNetworkRecord networkRecord,
|
UnderlyingNetworkRecord networkRecord,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
final NetworkCapabilities caps = networkRecord.networkCapabilities;
|
||||||
final boolean isSelectedNetwork =
|
final boolean isSelectedNetwork =
|
||||||
currentlySelected != null
|
currentlySelected != null
|
||||||
@@ -314,7 +314,7 @@ class NetworkPriorityClassifier {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getWifiEntryRssiThreshold(@Nullable PersistableBundle carrierConfig) {
|
static int getWifiEntryRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
|
||||||
if (carrierConfig != null) {
|
if (carrierConfig != null) {
|
||||||
return carrierConfig.getInt(
|
return carrierConfig.getInt(
|
||||||
VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
||||||
@@ -323,7 +323,7 @@ class NetworkPriorityClassifier {
|
|||||||
return WIFI_ENTRY_RSSI_THRESHOLD_DEFAULT;
|
return WIFI_ENTRY_RSSI_THRESHOLD_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getWifiExitRssiThreshold(@Nullable PersistableBundle carrierConfig) {
|
static int getWifiExitRssiThreshold(@Nullable PersistableBundleWrapper carrierConfig) {
|
||||||
if (carrierConfig != null) {
|
if (carrierConfig != null) {
|
||||||
return carrierConfig.getInt(
|
return carrierConfig.getInt(
|
||||||
VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListen
|
|||||||
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
||||||
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiEntryRssiThreshold;
|
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiEntryRssiThreshold;
|
||||||
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiExitRssiThreshold;
|
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.getWifiExitRssiThreshold;
|
||||||
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.isOpportunistic;
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -37,8 +37,6 @@ import android.net.vcn.VcnUnderlyingNetworkTemplate;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerExecutor;
|
import android.os.HandlerExecutor;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.telephony.CarrierConfigManager;
|
|
||||||
import android.telephony.TelephonyCallback;
|
import android.telephony.TelephonyCallback;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -51,7 +49,6 @@ import com.android.server.vcn.VcnContext;
|
|||||||
import com.android.server.vcn.util.LogUtils;
|
import com.android.server.vcn.util.LogUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -87,7 +84,7 @@ public class UnderlyingNetworkController {
|
|||||||
@Nullable private UnderlyingNetworkListener mRouteSelectionCallback;
|
@Nullable private UnderlyingNetworkListener mRouteSelectionCallback;
|
||||||
|
|
||||||
@NonNull private TelephonySubscriptionSnapshot mLastSnapshot;
|
@NonNull private TelephonySubscriptionSnapshot mLastSnapshot;
|
||||||
@Nullable private PersistableBundle mCarrierConfig;
|
@Nullable private PersistableBundleWrapper mCarrierConfig;
|
||||||
private boolean mIsQuitting = false;
|
private boolean mIsQuitting = false;
|
||||||
|
|
||||||
@Nullable private UnderlyingNetworkRecord mCurrentRecord;
|
@Nullable private UnderlyingNetworkRecord mCurrentRecord;
|
||||||
@@ -124,25 +121,7 @@ public class UnderlyingNetworkController {
|
|||||||
.getSystemService(TelephonyManager.class)
|
.getSystemService(TelephonyManager.class)
|
||||||
.registerTelephonyCallback(new HandlerExecutor(mHandler), mActiveDataSubIdListener);
|
.registerTelephonyCallback(new HandlerExecutor(mHandler), mActiveDataSubIdListener);
|
||||||
|
|
||||||
// TODO: Listen for changes in carrier config that affect this.
|
mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);
|
||||||
for (int subId : mLastSnapshot.getAllSubIdsInGroup(mSubscriptionGroup)) {
|
|
||||||
PersistableBundle config =
|
|
||||||
mVcnContext
|
|
||||||
.getContext()
|
|
||||||
.getSystemService(CarrierConfigManager.class)
|
|
||||||
.getConfigForSubId(subId);
|
|
||||||
|
|
||||||
if (config != null) {
|
|
||||||
mCarrierConfig = config;
|
|
||||||
|
|
||||||
// Attempt to use (any) non-opportunistic subscription. If this subscription is
|
|
||||||
// opportunistic, continue and try to find a non-opportunistic subscription, using
|
|
||||||
// the opportunistic ones as a last resort.
|
|
||||||
if (!isOpportunistic(mLastSnapshot, Collections.singleton(subId))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
registerOrUpdateNetworkRequests();
|
registerOrUpdateNetworkRequests();
|
||||||
}
|
}
|
||||||
@@ -334,6 +313,9 @@ public class UnderlyingNetworkController {
|
|||||||
final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
|
final TelephonySubscriptionSnapshot oldSnapshot = mLastSnapshot;
|
||||||
mLastSnapshot = newSnapshot;
|
mLastSnapshot = newSnapshot;
|
||||||
|
|
||||||
|
// Update carrier config
|
||||||
|
mCarrierConfig = mLastSnapshot.getCarrierConfigForSubGrp(mSubscriptionGroup);
|
||||||
|
|
||||||
// Only trigger re-registration if subIds in this group have changed
|
// Only trigger re-registration if subIds in this group have changed
|
||||||
if (oldSnapshot
|
if (oldSnapshot
|
||||||
.getAllSubIdsInGroup(mSubscriptionGroup)
|
.getAllSubIdsInGroup(mSubscriptionGroup)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.vcn.routeselection;
|
package com.android.server.vcn.routeselection;
|
||||||
|
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -23,7 +25,6 @@ import android.net.Network;
|
|||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.vcn.VcnUnderlyingNetworkTemplate;
|
import android.net.vcn.VcnUnderlyingNetworkTemplate;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
import android.os.PersistableBundle;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||||
@@ -68,7 +69,7 @@ public class UnderlyingNetworkRecord {
|
|||||||
ParcelUuid subscriptionGroup,
|
ParcelUuid subscriptionGroup,
|
||||||
TelephonySubscriptionSnapshot snapshot,
|
TelephonySubscriptionSnapshot snapshot,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
// Never changes after the underlying network record is created.
|
// Never changes after the underlying network record is created.
|
||||||
if (mPriorityClass == PRIORITY_CLASS_INVALID) {
|
if (mPriorityClass == PRIORITY_CLASS_INVALID) {
|
||||||
mPriorityClass =
|
mPriorityClass =
|
||||||
@@ -113,7 +114,7 @@ public class UnderlyingNetworkRecord {
|
|||||||
ParcelUuid subscriptionGroup,
|
ParcelUuid subscriptionGroup,
|
||||||
TelephonySubscriptionSnapshot snapshot,
|
TelephonySubscriptionSnapshot snapshot,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
return (left, right) -> {
|
return (left, right) -> {
|
||||||
final int leftIndex =
|
final int leftIndex =
|
||||||
left.getOrCalculatePriorityClass(
|
left.getOrCalculatePriorityClass(
|
||||||
@@ -167,7 +168,7 @@ public class UnderlyingNetworkRecord {
|
|||||||
ParcelUuid subscriptionGroup,
|
ParcelUuid subscriptionGroup,
|
||||||
TelephonySubscriptionSnapshot snapshot,
|
TelephonySubscriptionSnapshot snapshot,
|
||||||
UnderlyingNetworkRecord currentlySelected,
|
UnderlyingNetworkRecord currentlySelected,
|
||||||
PersistableBundle carrierConfig) {
|
PersistableBundleWrapper carrierConfig) {
|
||||||
pw.println("UnderlyingNetworkRecord:");
|
pw.println("UnderlyingNetworkRecord:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,13 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
@@ -354,4 +356,182 @@ public class PersistableBundleUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of the persistable bundle with only the specified keys
|
||||||
|
*
|
||||||
|
* <p>This allows for holding minimized copies for memory-saving purposes.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static PersistableBundle minimizeBundle(
|
||||||
|
@NonNull PersistableBundle bundle, String... keys) {
|
||||||
|
final PersistableBundle minimized = new PersistableBundle();
|
||||||
|
|
||||||
|
if (bundle == null) {
|
||||||
|
return minimized;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : keys) {
|
||||||
|
if (bundle.containsKey(key)) {
|
||||||
|
final Object value = bundle.get(key);
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value instanceof Boolean) {
|
||||||
|
minimized.putBoolean(key, (Boolean) value);
|
||||||
|
} else if (value instanceof boolean[]) {
|
||||||
|
minimized.putBooleanArray(key, (boolean[]) value);
|
||||||
|
} else if (value instanceof Double) {
|
||||||
|
minimized.putDouble(key, (Double) value);
|
||||||
|
} else if (value instanceof double[]) {
|
||||||
|
minimized.putDoubleArray(key, (double[]) value);
|
||||||
|
} else if (value instanceof Integer) {
|
||||||
|
minimized.putInt(key, (Integer) value);
|
||||||
|
} else if (value instanceof int[]) {
|
||||||
|
minimized.putIntArray(key, (int[]) value);
|
||||||
|
} else if (value instanceof Long) {
|
||||||
|
minimized.putLong(key, (Long) value);
|
||||||
|
} else if (value instanceof long[]) {
|
||||||
|
minimized.putLongArray(key, (long[]) value);
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
minimized.putString(key, (String) value);
|
||||||
|
} else if (value instanceof String[]) {
|
||||||
|
minimized.putStringArray(key, (String[]) value);
|
||||||
|
} else if (value instanceof PersistableBundle) {
|
||||||
|
minimized.putPersistableBundle(key, (PersistableBundle) value);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minimized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Builds a stable hashcode */
|
||||||
|
public static int getHashCode(@Nullable PersistableBundle bundle) {
|
||||||
|
if (bundle == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iterativeHashcode = 0;
|
||||||
|
TreeSet<String> treeSet = new TreeSet<>(bundle.keySet());
|
||||||
|
for (String key : treeSet) {
|
||||||
|
Object val = bundle.get(key);
|
||||||
|
if (val instanceof PersistableBundle) {
|
||||||
|
iterativeHashcode =
|
||||||
|
Objects.hash(iterativeHashcode, key, getHashCode((PersistableBundle) val));
|
||||||
|
} else {
|
||||||
|
iterativeHashcode = Objects.hash(iterativeHashcode, key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterativeHashcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks for persistable bundle equality */
|
||||||
|
public static boolean isEqual(
|
||||||
|
@Nullable PersistableBundle left, @Nullable PersistableBundle right) {
|
||||||
|
// Check for pointer equality & null equality
|
||||||
|
if (Objects.equals(left, right)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If only one of the two is null, but not the other, not equal by definition.
|
||||||
|
if (Objects.isNull(left) != Objects.isNull(right)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!left.keySet().equals(right.keySet())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : left.keySet()) {
|
||||||
|
Object leftVal = left.get(key);
|
||||||
|
Object rightVal = right.get(key);
|
||||||
|
|
||||||
|
// Check for equality
|
||||||
|
if (Objects.equals(leftVal, rightVal)) {
|
||||||
|
continue;
|
||||||
|
} else if (Objects.isNull(leftVal) != Objects.isNull(rightVal)) {
|
||||||
|
// If only one of the two is null, but not the other, not equal by definition.
|
||||||
|
return false;
|
||||||
|
} else if (!Objects.equals(leftVal.getClass(), rightVal.getClass())) {
|
||||||
|
// If classes are different, not equal by definition.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (leftVal instanceof PersistableBundle) {
|
||||||
|
if (!isEqual((PersistableBundle) leftVal, (PersistableBundle) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (leftVal.getClass().isArray()) {
|
||||||
|
if (leftVal instanceof boolean[]) {
|
||||||
|
if (!Arrays.equals((boolean[]) leftVal, (boolean[]) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (leftVal instanceof double[]) {
|
||||||
|
if (!Arrays.equals((double[]) leftVal, (double[]) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (leftVal instanceof int[]) {
|
||||||
|
if (!Arrays.equals((int[]) leftVal, (int[]) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (leftVal instanceof long[]) {
|
||||||
|
if (!Arrays.equals((long[]) leftVal, (long[]) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!Arrays.equals((Object[]) leftVal, (Object[]) rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!Objects.equals(leftVal, rightVal)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper class around PersistableBundles to allow equality comparisons
|
||||||
|
*
|
||||||
|
* <p>This class exposes the minimal getters to retrieve values.
|
||||||
|
*/
|
||||||
|
public static class PersistableBundleWrapper {
|
||||||
|
@NonNull private final PersistableBundle mBundle;
|
||||||
|
|
||||||
|
public PersistableBundleWrapper(@NonNull PersistableBundle bundle) {
|
||||||
|
mBundle = Objects.requireNonNull(bundle, "Bundle was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the integer associated with the provided key.
|
||||||
|
*
|
||||||
|
* @param key the string key to query
|
||||||
|
* @param defaultValue the value to return if key does not exist
|
||||||
|
* @return the int value, or the default
|
||||||
|
*/
|
||||||
|
public int getInt(String key, int defaultValue) {
|
||||||
|
return mBundle.getInt(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getHashCode(mBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof PersistableBundleWrapper)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final PersistableBundleWrapper other = (PersistableBundleWrapper) obj;
|
||||||
|
|
||||||
|
return isEqual(mBundle, other.mBundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED
|
|||||||
|
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -50,9 +51,11 @@ import android.annotation.NonNull;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.net.vcn.VcnManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerExecutor;
|
import android.os.HandlerExecutor;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.os.test.TestLooper;
|
import android.os.test.TestLooper;
|
||||||
import android.telephony.CarrierConfigManager;
|
import android.telephony.CarrierConfigManager;
|
||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
@@ -104,6 +107,26 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
TEST_SUBID_TO_INFO_MAP = Collections.unmodifiableMap(subIdToGroupMap);
|
TEST_SUBID_TO_INFO_MAP = Collections.unmodifiableMap(subIdToGroupMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String TEST_CARRIER_CONFIG_KEY_1 = "TEST_CARRIER_CONFIG_KEY_1";
|
||||||
|
private static final String TEST_CARRIER_CONFIG_KEY_2 = "TEST_CARRIER_CONFIG_KEY_2";
|
||||||
|
private static final PersistableBundle TEST_CARRIER_CONFIG = new PersistableBundle();
|
||||||
|
private static final PersistableBundleWrapper TEST_CARRIER_CONFIG_WRAPPER;
|
||||||
|
private static final Map<Integer, PersistableBundleWrapper> TEST_SUBID_TO_CARRIER_CONFIG_MAP;
|
||||||
|
|
||||||
|
static {
|
||||||
|
TEST_CARRIER_CONFIG.putString(
|
||||||
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
||||||
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY);
|
||||||
|
TEST_CARRIER_CONFIG.putString(
|
||||||
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
||||||
|
VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY);
|
||||||
|
TEST_CARRIER_CONFIG_WRAPPER = new PersistableBundleWrapper(TEST_CARRIER_CONFIG);
|
||||||
|
|
||||||
|
final Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
|
||||||
|
subIdToCarrierConfigMap.put(TEST_SUBSCRIPTION_ID_1, TEST_CARRIER_CONFIG_WRAPPER);
|
||||||
|
TEST_SUBID_TO_CARRIER_CONFIG_MAP = Collections.unmodifiableMap(subIdToCarrierConfigMap);
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull private final Context mContext;
|
@NonNull private final Context mContext;
|
||||||
@NonNull private final TestLooper mTestLooper;
|
@NonNull private final TestLooper mTestLooper;
|
||||||
@NonNull private final Handler mHandler;
|
@NonNull private final Handler mHandler;
|
||||||
@@ -144,6 +167,9 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
doReturn(mCarrierConfigManager)
|
doReturn(mCarrierConfigManager)
|
||||||
.when(mContext)
|
.when(mContext)
|
||||||
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
.getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
||||||
|
doReturn(TEST_CARRIER_CONFIG)
|
||||||
|
.when(mCarrierConfigManager)
|
||||||
|
.getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
|
||||||
|
|
||||||
// subId 1, 2 are in same subGrp, only subId 1 is active
|
// subId 1, 2 are in same subGrp, only subId 1 is active
|
||||||
doReturn(TEST_PARCEL_UUID).when(TEST_SUBINFO_1).getGroupUuid();
|
doReturn(TEST_PARCEL_UUID).when(TEST_SUBINFO_1).getGroupUuid();
|
||||||
@@ -227,14 +253,24 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
||||||
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
return new TelephonySubscriptionSnapshot(0, subIdToInfoMap, privilegedPackages);
|
return buildExpectedSnapshot(0, subIdToInfoMap, privilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
||||||
int activeSubId,
|
int activeSubId,
|
||||||
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
return new TelephonySubscriptionSnapshot(activeSubId, subIdToInfoMap, privilegedPackages);
|
return buildExpectedSnapshot(
|
||||||
|
activeSubId, subIdToInfoMap, TEST_SUBID_TO_CARRIER_CONFIG_MAP, privilegedPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TelephonySubscriptionSnapshot buildExpectedSnapshot(
|
||||||
|
int activeSubId,
|
||||||
|
Map<Integer, SubscriptionInfo> subIdToInfoMap,
|
||||||
|
Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap,
|
||||||
|
Map<ParcelUuid, Set<String>> privilegedPackages) {
|
||||||
|
return new TelephonySubscriptionSnapshot(
|
||||||
|
activeSubId, subIdToInfoMap, subIdToCarrierConfigMap, privilegedPackages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyNoActiveSubscriptions() {
|
private void verifyNoActiveSubscriptions() {
|
||||||
@@ -245,6 +281,8 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
private void setupReadySubIds() {
|
private void setupReadySubIds() {
|
||||||
mTelephonySubscriptionTracker.setReadySubIdsBySlotId(
|
mTelephonySubscriptionTracker.setReadySubIdsBySlotId(
|
||||||
Collections.singletonMap(TEST_SIM_SLOT_INDEX, TEST_SUBSCRIPTION_ID_1));
|
Collections.singletonMap(TEST_SIM_SLOT_INDEX, TEST_SUBSCRIPTION_ID_1));
|
||||||
|
mTelephonySubscriptionTracker.setSubIdToCarrierConfigMap(
|
||||||
|
Collections.singletonMap(TEST_SUBSCRIPTION_ID_1, TEST_CARRIER_CONFIG_WRAPPER));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPrivilegedPackagesForMock(@NonNull List<String> privilegedPackages) {
|
private void setPrivilegedPackagesForMock(@NonNull List<String> privilegedPackages) {
|
||||||
@@ -300,6 +338,7 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
readySubIdsBySlotId.put(TEST_SIM_SLOT_INDEX + 1, TEST_SUBSCRIPTION_ID_1);
|
readySubIdsBySlotId.put(TEST_SIM_SLOT_INDEX + 1, TEST_SUBSCRIPTION_ID_1);
|
||||||
|
|
||||||
mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId);
|
mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId);
|
||||||
|
mTelephonySubscriptionTracker.setSubIdToCarrierConfigMap(TEST_SUBID_TO_CARRIER_CONFIG_MAP);
|
||||||
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
||||||
|
|
||||||
List<CarrierPrivilegesCallback> carrierPrivilegesCallbacks =
|
List<CarrierPrivilegesCallback> carrierPrivilegesCallbacks =
|
||||||
@@ -464,8 +503,16 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
|
|
||||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
|
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(emptyMap())));
|
verify(mCallback)
|
||||||
|
.onNewSnapshot(
|
||||||
|
eq(
|
||||||
|
buildExpectedSnapshot(
|
||||||
|
0, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap())));
|
||||||
assertNull(mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
|
assertNull(mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
|
||||||
|
assertNull(
|
||||||
|
mTelephonySubscriptionTracker
|
||||||
|
.getSubIdToCarrierConfigMap()
|
||||||
|
.get(TEST_SUBSCRIPTION_ID_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -493,7 +540,7 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
public void testTelephonySubscriptionSnapshotGetGroupForSubId() throws Exception {
|
public void testTelephonySubscriptionSnapshotGetGroupForSubId() throws Exception {
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
|
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap());
|
||||||
|
|
||||||
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_1));
|
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_1));
|
||||||
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_2));
|
assertEquals(TEST_PARCEL_UUID, snapshot.getGroupForSubId(TEST_SUBSCRIPTION_ID_2));
|
||||||
@@ -503,7 +550,7 @@ public class TelephonySubscriptionTrackerTest {
|
|||||||
public void testTelephonySubscriptionSnapshotGetAllSubIdsInGroup() throws Exception {
|
public void testTelephonySubscriptionSnapshotGetAllSubIdsInGroup() throws Exception {
|
||||||
final TelephonySubscriptionSnapshot snapshot =
|
final TelephonySubscriptionSnapshot snapshot =
|
||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap());
|
TEST_SUBSCRIPTION_ID_1, TEST_SUBID_TO_INFO_MAP, emptyMap(), emptyMap());
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
|
new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ public class VcnGatewayConnectionTestBase {
|
|||||||
new TelephonySubscriptionSnapshot(
|
new TelephonySubscriptionSnapshot(
|
||||||
TEST_SUB_ID,
|
TEST_SUB_ID,
|
||||||
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO),
|
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO),
|
||||||
|
Collections.EMPTY_MAP,
|
||||||
Collections.EMPTY_MAP);
|
Collections.EMPTY_MAP);
|
||||||
|
|
||||||
@NonNull protected final Context mContext;
|
@NonNull protected final Context mContext;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.ch
|
|||||||
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesPriorityRule;
|
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesPriorityRule;
|
||||||
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesWifiPriorityRule;
|
import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesWifiPriorityRule;
|
||||||
import static com.android.server.vcn.routeselection.UnderlyingNetworkControllerTest.getLinkPropertiesWithName;
|
import static com.android.server.vcn.routeselection.UnderlyingNetworkControllerTest.getLinkPropertiesWithName;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
@@ -309,7 +310,9 @@ public class NetworkPriorityClassifierTest {
|
|||||||
wifiNetworkPriority,
|
wifiNetworkPriority,
|
||||||
mWifiNetworkRecord,
|
mWifiNetworkRecord,
|
||||||
selectedNetworkRecord,
|
selectedNetworkRecord,
|
||||||
carrierConfig));
|
carrierConfig == null
|
||||||
|
? null
|
||||||
|
: new PersistableBundleWrapper(carrierConfig)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.android.server.vcn.util;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
|
|
||||||
@@ -211,4 +213,84 @@ public class PersistableBundleUtilsTest {
|
|||||||
|
|
||||||
assertEquals(testInt, result);
|
assertEquals(testInt, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PersistableBundle getTestBundle() {
|
||||||
|
final PersistableBundle bundle = new PersistableBundle();
|
||||||
|
|
||||||
|
bundle.putBoolean(TEST_KEY + "Boolean", true);
|
||||||
|
bundle.putBooleanArray(TEST_KEY + "BooleanArray", new boolean[] {true, false});
|
||||||
|
bundle.putDouble(TEST_KEY + "Double", 0.1);
|
||||||
|
bundle.putDoubleArray(TEST_KEY + "DoubleArray", new double[] {0.1, 0.2, 0.3});
|
||||||
|
bundle.putInt(TEST_KEY + "Int", 1);
|
||||||
|
bundle.putIntArray(TEST_KEY + "IntArray", new int[] {1, 2});
|
||||||
|
bundle.putLong(TEST_KEY + "Long", 5L);
|
||||||
|
bundle.putLongArray(TEST_KEY + "LongArray", new long[] {0L, -1L, -2L});
|
||||||
|
bundle.putString(TEST_KEY + "String", "TEST");
|
||||||
|
bundle.putStringArray(TEST_KEY + "StringArray", new String[] {"foo", "bar", "bas"});
|
||||||
|
bundle.putPersistableBundle(
|
||||||
|
TEST_KEY + "PersistableBundle",
|
||||||
|
new TestClass(1, TEST_INT_ARRAY, TEST_STRING_PREFIX, new PersistableBundle())
|
||||||
|
.toPersistableBundle());
|
||||||
|
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMinimizeBundle() throws Exception {
|
||||||
|
final String[] minimizedKeys =
|
||||||
|
new String[] {
|
||||||
|
TEST_KEY + "Boolean",
|
||||||
|
TEST_KEY + "BooleanArray",
|
||||||
|
TEST_KEY + "Double",
|
||||||
|
TEST_KEY + "DoubleArray",
|
||||||
|
TEST_KEY + "Int",
|
||||||
|
TEST_KEY + "IntArray",
|
||||||
|
TEST_KEY + "Long",
|
||||||
|
TEST_KEY + "LongArray",
|
||||||
|
TEST_KEY + "String",
|
||||||
|
TEST_KEY + "StringArray",
|
||||||
|
TEST_KEY + "PersistableBundle"
|
||||||
|
};
|
||||||
|
|
||||||
|
final PersistableBundle testBundle = getTestBundle();
|
||||||
|
testBundle.putBoolean(TEST_KEY + "Boolean2", true);
|
||||||
|
|
||||||
|
final PersistableBundle minimized =
|
||||||
|
PersistableBundleUtils.minimizeBundle(testBundle, minimizedKeys);
|
||||||
|
|
||||||
|
// Verify that the minimized bundle is NOT the same in size OR values due to the extra
|
||||||
|
// Boolean2 key
|
||||||
|
assertFalse(PersistableBundleUtils.isEqual(testBundle, minimized));
|
||||||
|
|
||||||
|
// Verify that removing the extra key from the source bundle results in equality.
|
||||||
|
testBundle.remove(TEST_KEY + "Boolean2");
|
||||||
|
assertTrue(PersistableBundleUtils.isEqual(testBundle, minimized));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquality_identical() throws Exception {
|
||||||
|
final PersistableBundle left = getTestBundle();
|
||||||
|
final PersistableBundle right = getTestBundle();
|
||||||
|
|
||||||
|
assertTrue(PersistableBundleUtils.isEqual(left, right));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquality_different() throws Exception {
|
||||||
|
final PersistableBundle left = getTestBundle();
|
||||||
|
final PersistableBundle right = getTestBundle();
|
||||||
|
|
||||||
|
left.putBoolean(TEST_KEY + "Boolean2", true);
|
||||||
|
assertFalse(PersistableBundleUtils.isEqual(left, right));
|
||||||
|
|
||||||
|
left.remove(TEST_KEY + "Boolean2");
|
||||||
|
assertTrue(PersistableBundleUtils.isEqual(left, right));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquality_null() throws Exception {
|
||||||
|
assertFalse(PersistableBundleUtils.isEqual(getTestBundle(), null));
|
||||||
|
assertFalse(PersistableBundleUtils.isEqual(null, getTestBundle()));
|
||||||
|
assertTrue(PersistableBundleUtils.isEqual(null, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user