Loading src/java/com/android/internal/telephony/data/DataNetwork.java +75 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.telephony.LinkCapacityEstimate; import android.telephony.NetworkRegistrationInfo; import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; Loading Loading @@ -172,6 +173,9 @@ public class DataNetwork extends StateMachine { /** Event for setup data call (for handover) response from the data service. */ private static final int EVENT_HANDOVER_RESPONSE = 15; /** Event for subscription plan changed or unmetered/congested override set. */ private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16; /** The default MTU for IPv4 network. */ private static final int DEFAULT_MTU_V4 = 1280; Loading Loading @@ -602,6 +606,12 @@ public class DataNetwork extends StateMachine { mDataServiceManagers = dataServiceManagers; mAccessNetworksManager = phone.getAccessNetworksManager(); mDataNetworkController = phone.getDataNetworkController(); mDataNetworkController.registerDataNetworkControllerCallback( new DataNetworkController.DataNetworkControllerCallback(getHandler()::post) { @Override public void onSubscriptionPlanOverride() { sendMessage(EVENT_SUBSCRIPTION_PLAN_OVERRIDE); }}); mDataConfigManager = mDataNetworkController.getDataConfigManager(); mDataNetworkCallback = callback; mDataProfile = dataProfile; Loading Loading @@ -926,6 +936,9 @@ public class DataNetwork extends StateMachine { case EVENT_START_HANDOVER: onStartHandover(msg.arg1, (DataHandoverRetryEntry) msg.obj); break; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: updateMeteredAndCongested(); break; default: return NOT_HANDLED; } Loading Loading @@ -1138,12 +1151,10 @@ public class DataNetwork extends StateMachine { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } // TODO: Support NET_CAPABILITY_NOT_RESTRICTED // TODO: Support NET_CAPABILITY_NOT_CONGESTED correctly if (!mCongested) { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); } // TODO: Support NET_CAPABILITY_TEMPORARILY_NOT_METERED correctly if (mTempNotMeteredSupported && mTempNotMetered) { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); } Loading Loading @@ -1762,9 +1773,66 @@ public class DataNetwork extends StateMachine { * Update the metered and congested values from carrier configs and subscription overrides */ private void updateMeteredAndCongested() { log("updateMeteredAndCongested"); mTempNotMeteredSupported = mDataConfigManager.isTempNotMeteredSupportedByCarrier(); // TODO: set mTempNotMetered and mCongested based on SubscriptionPlans and overrides int networkType = isNrConnected() ? TelephonyManager.NETWORK_TYPE_NR : getDataNetworkType(); log("updateMeteredAndCongested: networkType=" + TelephonyManager.getNetworkTypeName(networkType)); boolean changed = false; if (mDataConfigManager.isTempNotMeteredSupportedByCarrier() != mTempNotMeteredSupported) { mTempNotMeteredSupported = !mTempNotMeteredSupported; changed = true; log("updateMeteredAndCongested: mTempNotMeteredSupported changed to " + mTempNotMeteredSupported); } if ((mDataNetworkController.getUnmeteredOverrideNetworkTypes().contains(networkType) || isNetworkTypeUnmetered(networkType)) != mTempNotMetered) { mTempNotMetered = !mTempNotMetered; changed = true; log("updateMeteredAndCongested: mTempNotMetered changed to " + mTempNotMetered); } if (mDataNetworkController.getCongestedOverrideNetworkTypes().contains(networkType) != mCongested) { mCongested = !mCongested; changed = true; log("updateMeteredAndCongested: mCongested changed to " + mCongested); } if (changed) { updateNetworkCapabilities(); } } /** * Get whether the network type is unmetered from SubscriptionPlans, from either an unmetered * general plan or specific plan for the given network type. * * @param networkType The network type to check meteredness for * @return Whether the given network type is unmetered based on SubscriptionPlans */ private boolean isNetworkTypeUnmetered(@NetworkType int networkType) { List<SubscriptionPlan> plans = mDataNetworkController.getSubscriptionPlans(); if (plans.isEmpty()) return false; boolean isGeneralUnmetered = true; Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes()) .boxed().collect(Collectors.toSet()); for (SubscriptionPlan plan : plans) { // Check if plan is general (applies to all network types) or specific if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet()) .containsAll(allNetworkTypes)) { if (plan.getDataLimitBytes() != SubscriptionPlan.BYTES_UNLIMITED) { // Metered takes precedence over unmetered for safety isGeneralUnmetered = false; } } else { // Check if plan applies to given network type if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) { for (int planNetworkType : plan.getNetworkTypes()) { if (planNetworkType == networkType) { return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED; } } } } } return isGeneralUnmetered; } /** Loading Loading @@ -2137,6 +2205,8 @@ public class DataNetwork extends StateMachine { return "EVENT_START_HANDOVER"; case EVENT_HANDOVER_RESPONSE: return "EVENT_HANDOVER_RESPONSE"; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE"; default: return "Unknown(" + event + ")"; } Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +138 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager.SubscriptionCallback; import android.net.Uri; import android.os.AsyncResult; import android.os.Handler; Loading @@ -46,6 +48,7 @@ import android.telephony.NetworkRegistrationInfo.RegistrationState; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager.DataState; import android.telephony.TelephonyManager.SimState; Loading Loading @@ -175,6 +178,12 @@ public class DataNetworkController extends Handler { /** Event for re-evaluating preferred transport. */ private static final int EVENT_REEVALUATE_PREFERRED_TRANSPORT = 21; /** Event for subscription plans changed. */ private static final int EVENT_SUBSCRIPTION_PLANS_CHANGED = 22; /** Event for unmetered or congested subscription override. */ private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23; /** The supported IMS features. This is for IMS graceful tear down support. */ private static final Collection<Integer> SUPPORTED_IMS_FEATURES = List.of(ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS); Loading @@ -197,6 +206,7 @@ public class DataNetworkController extends Handler { private final @NonNull AccessNetworksManager mAccessNetworksManager; private final @NonNull DataRetryManager mDataRetryManager; private final @NonNull ImsManager mImsManager; private final @NonNull NetworkPolicyManager mNetworkPolicyManager; private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>(); Loading @@ -208,6 +218,21 @@ public class DataNetworkController extends Handler { // is intended for detecting the delta. private @NonNull ServiceState mServiceState; /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */ private @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); /** * The set of network types an unmetered override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); /** * The set of network types a congested override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); /** * The list of all network requests. */ Loading Loading @@ -477,6 +502,12 @@ public class DataNetworkController extends Handler { * disconnected. */ public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {} /** * Called when {@link SubscriptionPlan}s change or an unmetered or congested subscription * override is set. */ public void onSubscriptionPlanOverride() {} } /** Loading Loading @@ -718,6 +749,7 @@ public class DataNetworkController extends Handler { } }); mImsManager = mPhone.getContext().getSystemService(ImsManager.class); mNetworkPolicyManager = mPhone.getContext().getSystemService(NetworkPolicyManager.class); // Use the raw one from ServiceStateTracker instead of the combined one from // mPhone.getServiceState(). Loading @@ -744,6 +776,23 @@ public class DataNetworkController extends Handler { } }); mNetworkPolicyManager.registerSubscriptionCallback(new SubscriptionCallback() { @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { if (mSubId != subId) return; obtainMessage(EVENT_SUBSCRIPTION_PLANS_CHANGED, plans).sendToTarget(); } @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, int[] networkTypes) { if (mSubId != subId) return; obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE, overrideMask, overrideValue, networkTypes).sendToTarget(); } }); updateSubscriptionPlans(); mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( AccessNetworkConstants.TRANSPORT_TYPE_WWAN, this, EVENT_SERVICE_STATE_CHANGED, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); Loading Loading @@ -771,6 +820,7 @@ public class DataNetworkController extends Handler { sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED); } }, this::post); // Register for call ended event for voice/data concurrent not supported case. It is // intended to only listen for events from the same phone as most of the telephony modules // are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the frameworks relies Loading Loading @@ -861,6 +911,50 @@ public class DataNetworkController extends Handler { case EVENT_REEVALUATE_PREFERRED_TRANSPORT: onReevaluatePreferredTransport(msg.arg1); break; case EVENT_SUBSCRIPTION_PLANS_CHANGED: SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; log("Subscription plans changed: " + Arrays.toString(plans)); mSubscriptionPlans = Arrays.asList(plans); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); break; case EVENT_SUBSCRIPTION_OVERRIDE: int overrideMask = msg.arg1; boolean override = msg.arg2 != 0; int[] networkTypes = (int[]) msg.obj; if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED) { log("Unmetered subscription override: override=" + override + ", networkTypes=" + Arrays.stream(networkTypes) .mapToObj(TelephonyManager::getNetworkTypeName) .collect(Collectors.joining(","))); for (int networkType : networkTypes) { if (override) { mUnmeteredOverrideNetworkTypes.add(networkType); } else { mUnmeteredOverrideNetworkTypes.remove(networkType); } } mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) { log("Congested subscription override: override=" + override + ", networkTypes=" + Arrays.stream(networkTypes) .mapToObj(TelephonyManager::getNetworkTypeName) .collect(Collectors.joining(","))); for (int networkType : networkTypes) { if (override) { mCongestedOverrideNetworkTypes.add(networkType); } else { mCongestedOverrideNetworkTypes.remove(networkType); } } mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); } else { loge("Unknown override mask: " + overrideMask); } break; default: loge("Unexpected event " + msg.what); } Loading Loading @@ -1531,6 +1625,7 @@ public class DataNetworkController extends Handler { } } mSubId = mPhone.getSubId(); updateSubscriptionPlans(); } } Loading Loading @@ -2083,6 +2178,17 @@ public class DataNetworkController extends Handler { } } /** * Update {@link SubscriptionPlan}s from {@link NetworkPolicyManager}. */ private void updateSubscriptionPlans() { mSubscriptionPlans = Arrays.asList(mNetworkPolicyManager.getSubscriptionPlans( mSubId, mPhone.getContext().getOpPackageName())); mCongestedOverrideNetworkTypes.clear(); mUnmeteredOverrideNetworkTypes.clear(); log("Subscription plans initialized: " + mSubscriptionPlans); } /** * Check if needed to re-evaluate the existing data networks. * Loading Loading @@ -2264,6 +2370,30 @@ public class DataNetworkController extends Handler { return mDataRetryManager; } /** * @return The list of SubscriptionPlans */ @VisibleForTesting public @NonNull List<SubscriptionPlan> getSubscriptionPlans() { return mSubscriptionPlans; } /** * @return The set of network types an unmetered override applies to */ @VisibleForTesting public @NonNull @NetworkType Set<Integer> getUnmeteredOverrideNetworkTypes() { return mUnmeteredOverrideNetworkTypes; } /** * @return The set of network types a congested override applies to */ @VisibleForTesting public @NonNull @NetworkType Set<Integer> getCongestedOverrideNetworkTypes() { return mCongestedOverrideNetworkTypes; } /** * Get data network type based on transport. * Loading Loading @@ -2536,6 +2666,14 @@ public class DataNetworkController extends Handler { pw.println("mDataServiceBound=" + mDataServiceBound); pw.println("mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState)); pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks); pw.println("Subscription plans:"); pw.increaseIndent(); mSubscriptionPlans.forEach(pw::println); pw.decreaseIndent(); pw.println("Unmetered override network types=" + mUnmeteredOverrideNetworkTypes.stream() .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); pw.println("Congested override network types=" + mCongestedOverrideNetworkTypes.stream() .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); pw.println("Local logs:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); Loading tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.database.MatrixCursor; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkPolicyManager; import android.net.Uri; import android.net.vcn.VcnManager; import android.net.wifi.WifiManager; Loading Loading @@ -287,6 +288,8 @@ public class ContextFixture implements TestFixture<Context> { return mPowerWhitelistManager; case Context.LOCATION_SERVICE: return mLocationManager; case Context.NETWORK_POLICY_SERVICE: return mNetworkPolicyManager; default: return null; } Loading Loading @@ -326,6 +329,8 @@ public class ContextFixture implements TestFixture<Context> { return Context.TELEPHONY_IMS_SERVICE; } else if (serviceClass == TelephonyRegistryManager.class) { return Context.TELEPHONY_REGISTRY_SERVICE; } else if (serviceClass == NetworkPolicyManager.class) { return Context.NETWORK_POLICY_SERVICE; } return super.getSystemServiceName(serviceClass); } Loading Loading @@ -698,6 +703,7 @@ public class ContextFixture implements TestFixture<Context> { private final LocationManager mLocationManager = mock(LocationManager.class); private final KeyguardManager mKeyguardManager = mock(KeyguardManager.class); private final VcnManager mVcnManager = mock(VcnManager.class); private final NetworkPolicyManager mNetworkPolicyManager = mock(NetworkPolicyManager.class); private final ContentProvider mContentProvider = spy(new FakeContentProvider()); Loading tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.PackageManager; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.vcn.VcnManager; import android.net.vcn.VcnNetworkPolicyResult; import android.net.wifi.WifiInfo; Loading Loading @@ -370,6 +371,7 @@ public abstract class TelephonyTest { protected UserManager mUserManager; protected KeyguardManager mKeyguardManager; protected VcnManager mVcnManager; protected NetworkPolicyManager mNetworkPolicyManager; protected SimulatedCommands mSimulatedCommands; protected ContextFixture mContextFixture; protected Context mContext; Loading Loading @@ -515,6 +517,7 @@ public abstract class TelephonyTest { mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mVcnManager = mContext.getSystemService(VcnManager.class); mNetworkPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); //mTelephonyComponentFactory Loading tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +146 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/data/DataNetwork.java +75 −5 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ import android.telephony.LinkCapacityEstimate; import android.telephony.NetworkRegistrationInfo; import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; Loading Loading @@ -172,6 +173,9 @@ public class DataNetwork extends StateMachine { /** Event for setup data call (for handover) response from the data service. */ private static final int EVENT_HANDOVER_RESPONSE = 15; /** Event for subscription plan changed or unmetered/congested override set. */ private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16; /** The default MTU for IPv4 network. */ private static final int DEFAULT_MTU_V4 = 1280; Loading Loading @@ -602,6 +606,12 @@ public class DataNetwork extends StateMachine { mDataServiceManagers = dataServiceManagers; mAccessNetworksManager = phone.getAccessNetworksManager(); mDataNetworkController = phone.getDataNetworkController(); mDataNetworkController.registerDataNetworkControllerCallback( new DataNetworkController.DataNetworkControllerCallback(getHandler()::post) { @Override public void onSubscriptionPlanOverride() { sendMessage(EVENT_SUBSCRIPTION_PLAN_OVERRIDE); }}); mDataConfigManager = mDataNetworkController.getDataConfigManager(); mDataNetworkCallback = callback; mDataProfile = dataProfile; Loading Loading @@ -926,6 +936,9 @@ public class DataNetwork extends StateMachine { case EVENT_START_HANDOVER: onStartHandover(msg.arg1, (DataHandoverRetryEntry) msg.obj); break; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: updateMeteredAndCongested(); break; default: return NOT_HANDLED; } Loading Loading @@ -1138,12 +1151,10 @@ public class DataNetwork extends StateMachine { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } // TODO: Support NET_CAPABILITY_NOT_RESTRICTED // TODO: Support NET_CAPABILITY_NOT_CONGESTED correctly if (!mCongested) { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); } // TODO: Support NET_CAPABILITY_TEMPORARILY_NOT_METERED correctly if (mTempNotMeteredSupported && mTempNotMetered) { builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); } Loading Loading @@ -1762,9 +1773,66 @@ public class DataNetwork extends StateMachine { * Update the metered and congested values from carrier configs and subscription overrides */ private void updateMeteredAndCongested() { log("updateMeteredAndCongested"); mTempNotMeteredSupported = mDataConfigManager.isTempNotMeteredSupportedByCarrier(); // TODO: set mTempNotMetered and mCongested based on SubscriptionPlans and overrides int networkType = isNrConnected() ? TelephonyManager.NETWORK_TYPE_NR : getDataNetworkType(); log("updateMeteredAndCongested: networkType=" + TelephonyManager.getNetworkTypeName(networkType)); boolean changed = false; if (mDataConfigManager.isTempNotMeteredSupportedByCarrier() != mTempNotMeteredSupported) { mTempNotMeteredSupported = !mTempNotMeteredSupported; changed = true; log("updateMeteredAndCongested: mTempNotMeteredSupported changed to " + mTempNotMeteredSupported); } if ((mDataNetworkController.getUnmeteredOverrideNetworkTypes().contains(networkType) || isNetworkTypeUnmetered(networkType)) != mTempNotMetered) { mTempNotMetered = !mTempNotMetered; changed = true; log("updateMeteredAndCongested: mTempNotMetered changed to " + mTempNotMetered); } if (mDataNetworkController.getCongestedOverrideNetworkTypes().contains(networkType) != mCongested) { mCongested = !mCongested; changed = true; log("updateMeteredAndCongested: mCongested changed to " + mCongested); } if (changed) { updateNetworkCapabilities(); } } /** * Get whether the network type is unmetered from SubscriptionPlans, from either an unmetered * general plan or specific plan for the given network type. * * @param networkType The network type to check meteredness for * @return Whether the given network type is unmetered based on SubscriptionPlans */ private boolean isNetworkTypeUnmetered(@NetworkType int networkType) { List<SubscriptionPlan> plans = mDataNetworkController.getSubscriptionPlans(); if (plans.isEmpty()) return false; boolean isGeneralUnmetered = true; Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes()) .boxed().collect(Collectors.toSet()); for (SubscriptionPlan plan : plans) { // Check if plan is general (applies to all network types) or specific if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet()) .containsAll(allNetworkTypes)) { if (plan.getDataLimitBytes() != SubscriptionPlan.BYTES_UNLIMITED) { // Metered takes precedence over unmetered for safety isGeneralUnmetered = false; } } else { // Check if plan applies to given network type if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) { for (int planNetworkType : plan.getNetworkTypes()) { if (planNetworkType == networkType) { return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED; } } } } } return isGeneralUnmetered; } /** Loading Loading @@ -2137,6 +2205,8 @@ public class DataNetwork extends StateMachine { return "EVENT_START_HANDOVER"; case EVENT_HANDOVER_RESPONSE: return "EVENT_HANDOVER_RESPONSE"; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE"; default: return "Unknown(" + event + ")"; } Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +138 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.NetworkPolicyManager.SubscriptionCallback; import android.net.Uri; import android.os.AsyncResult; import android.os.Handler; Loading @@ -46,6 +48,7 @@ import android.telephony.NetworkRegistrationInfo.RegistrationState; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager.DataState; import android.telephony.TelephonyManager.SimState; Loading Loading @@ -175,6 +178,12 @@ public class DataNetworkController extends Handler { /** Event for re-evaluating preferred transport. */ private static final int EVENT_REEVALUATE_PREFERRED_TRANSPORT = 21; /** Event for subscription plans changed. */ private static final int EVENT_SUBSCRIPTION_PLANS_CHANGED = 22; /** Event for unmetered or congested subscription override. */ private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23; /** The supported IMS features. This is for IMS graceful tear down support. */ private static final Collection<Integer> SUPPORTED_IMS_FEATURES = List.of(ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS); Loading @@ -197,6 +206,7 @@ public class DataNetworkController extends Handler { private final @NonNull AccessNetworksManager mAccessNetworksManager; private final @NonNull DataRetryManager mDataRetryManager; private final @NonNull ImsManager mImsManager; private final @NonNull NetworkPolicyManager mNetworkPolicyManager; private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>(); Loading @@ -208,6 +218,21 @@ public class DataNetworkController extends Handler { // is intended for detecting the delta. private @NonNull ServiceState mServiceState; /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */ private @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); /** * The set of network types an unmetered override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); /** * The set of network types a congested override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); /** * The list of all network requests. */ Loading Loading @@ -477,6 +502,12 @@ public class DataNetworkController extends Handler { * disconnected. */ public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {} /** * Called when {@link SubscriptionPlan}s change or an unmetered or congested subscription * override is set. */ public void onSubscriptionPlanOverride() {} } /** Loading Loading @@ -718,6 +749,7 @@ public class DataNetworkController extends Handler { } }); mImsManager = mPhone.getContext().getSystemService(ImsManager.class); mNetworkPolicyManager = mPhone.getContext().getSystemService(NetworkPolicyManager.class); // Use the raw one from ServiceStateTracker instead of the combined one from // mPhone.getServiceState(). Loading @@ -744,6 +776,23 @@ public class DataNetworkController extends Handler { } }); mNetworkPolicyManager.registerSubscriptionCallback(new SubscriptionCallback() { @Override public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) { if (mSubId != subId) return; obtainMessage(EVENT_SUBSCRIPTION_PLANS_CHANGED, plans).sendToTarget(); } @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, int[] networkTypes) { if (mSubId != subId) return; obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE, overrideMask, overrideValue, networkTypes).sendToTarget(); } }); updateSubscriptionPlans(); mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( AccessNetworkConstants.TRANSPORT_TYPE_WWAN, this, EVENT_SERVICE_STATE_CHANGED, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); Loading Loading @@ -771,6 +820,7 @@ public class DataNetworkController extends Handler { sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED); } }, this::post); // Register for call ended event for voice/data concurrent not supported case. It is // intended to only listen for events from the same phone as most of the telephony modules // are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the frameworks relies Loading Loading @@ -861,6 +911,50 @@ public class DataNetworkController extends Handler { case EVENT_REEVALUATE_PREFERRED_TRANSPORT: onReevaluatePreferredTransport(msg.arg1); break; case EVENT_SUBSCRIPTION_PLANS_CHANGED: SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; log("Subscription plans changed: " + Arrays.toString(plans)); mSubscriptionPlans = Arrays.asList(plans); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); break; case EVENT_SUBSCRIPTION_OVERRIDE: int overrideMask = msg.arg1; boolean override = msg.arg2 != 0; int[] networkTypes = (int[]) msg.obj; if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED) { log("Unmetered subscription override: override=" + override + ", networkTypes=" + Arrays.stream(networkTypes) .mapToObj(TelephonyManager::getNetworkTypeName) .collect(Collectors.joining(","))); for (int networkType : networkTypes) { if (override) { mUnmeteredOverrideNetworkTypes.add(networkType); } else { mUnmeteredOverrideNetworkTypes.remove(networkType); } } mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) { log("Congested subscription override: override=" + override + ", networkTypes=" + Arrays.stream(networkTypes) .mapToObj(TelephonyManager::getNetworkTypeName) .collect(Collectors.joining(","))); for (int networkType : networkTypes) { if (override) { mCongestedOverrideNetworkTypes.add(networkType); } else { mCongestedOverrideNetworkTypes.remove(networkType); } } mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); } else { loge("Unknown override mask: " + overrideMask); } break; default: loge("Unexpected event " + msg.what); } Loading Loading @@ -1531,6 +1625,7 @@ public class DataNetworkController extends Handler { } } mSubId = mPhone.getSubId(); updateSubscriptionPlans(); } } Loading Loading @@ -2083,6 +2178,17 @@ public class DataNetworkController extends Handler { } } /** * Update {@link SubscriptionPlan}s from {@link NetworkPolicyManager}. */ private void updateSubscriptionPlans() { mSubscriptionPlans = Arrays.asList(mNetworkPolicyManager.getSubscriptionPlans( mSubId, mPhone.getContext().getOpPackageName())); mCongestedOverrideNetworkTypes.clear(); mUnmeteredOverrideNetworkTypes.clear(); log("Subscription plans initialized: " + mSubscriptionPlans); } /** * Check if needed to re-evaluate the existing data networks. * Loading Loading @@ -2264,6 +2370,30 @@ public class DataNetworkController extends Handler { return mDataRetryManager; } /** * @return The list of SubscriptionPlans */ @VisibleForTesting public @NonNull List<SubscriptionPlan> getSubscriptionPlans() { return mSubscriptionPlans; } /** * @return The set of network types an unmetered override applies to */ @VisibleForTesting public @NonNull @NetworkType Set<Integer> getUnmeteredOverrideNetworkTypes() { return mUnmeteredOverrideNetworkTypes; } /** * @return The set of network types a congested override applies to */ @VisibleForTesting public @NonNull @NetworkType Set<Integer> getCongestedOverrideNetworkTypes() { return mCongestedOverrideNetworkTypes; } /** * Get data network type based on transport. * Loading Loading @@ -2536,6 +2666,14 @@ public class DataNetworkController extends Handler { pw.println("mDataServiceBound=" + mDataServiceBound); pw.println("mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState)); pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks); pw.println("Subscription plans:"); pw.increaseIndent(); mSubscriptionPlans.forEach(pw::println); pw.decreaseIndent(); pw.println("Unmetered override network types=" + mUnmeteredOverrideNetworkTypes.stream() .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); pw.println("Congested override network types=" + mCongestedOverrideNetworkTypes.stream() .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(","))); pw.println("Local logs:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); Loading
tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java +6 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import android.database.MatrixCursor; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkPolicyManager; import android.net.Uri; import android.net.vcn.VcnManager; import android.net.wifi.WifiManager; Loading Loading @@ -287,6 +288,8 @@ public class ContextFixture implements TestFixture<Context> { return mPowerWhitelistManager; case Context.LOCATION_SERVICE: return mLocationManager; case Context.NETWORK_POLICY_SERVICE: return mNetworkPolicyManager; default: return null; } Loading Loading @@ -326,6 +329,8 @@ public class ContextFixture implements TestFixture<Context> { return Context.TELEPHONY_IMS_SERVICE; } else if (serviceClass == TelephonyRegistryManager.class) { return Context.TELEPHONY_REGISTRY_SERVICE; } else if (serviceClass == NetworkPolicyManager.class) { return Context.NETWORK_POLICY_SERVICE; } return super.getSystemServiceName(serviceClass); } Loading Loading @@ -698,6 +703,7 @@ public class ContextFixture implements TestFixture<Context> { private final LocationManager mLocationManager = mock(LocationManager.class); private final KeyguardManager mKeyguardManager = mock(KeyguardManager.class); private final VcnManager mVcnManager = mock(VcnManager.class); private final NetworkPolicyManager mNetworkPolicyManager = mock(NetworkPolicyManager.class); private final ContentProvider mContentProvider = spy(new FakeContentProvider()); Loading
tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.content.pm.PackageManager; import android.location.LocationManager; import android.net.ConnectivityManager; import android.net.NetworkCapabilities; import android.net.NetworkPolicyManager; import android.net.vcn.VcnManager; import android.net.vcn.VcnNetworkPolicyResult; import android.net.wifi.WifiInfo; Loading Loading @@ -370,6 +371,7 @@ public abstract class TelephonyTest { protected UserManager mUserManager; protected KeyguardManager mKeyguardManager; protected VcnManager mVcnManager; protected NetworkPolicyManager mNetworkPolicyManager; protected SimulatedCommands mSimulatedCommands; protected ContextFixture mContextFixture; protected Context mContext; Loading Loading @@ -515,6 +517,7 @@ public abstract class TelephonyTest { mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); mVcnManager = mContext.getSystemService(VcnManager.class); mNetworkPolicyManager = mContext.getSystemService(NetworkPolicyManager.class); mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); //mTelephonyComponentFactory Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java +146 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes