diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index 10667aecd1287..106b7be5c8d31 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -22,5 +22,5 @@ oneway interface INetworkPolicyListener { void onMeteredIfacesChanged(in String[] meteredIfaces); void onRestrictBackgroundChanged(boolean restrictBackground); void onUidPoliciesChanged(int uid, int uidPolicies); - void onSubscriptionOverride(int subId, int overrideMask, int overrideValue); + void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask); } diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl index 385cb1d68b57f..90327663e34bc 100644 --- a/core/java/android/net/INetworkPolicyManager.aidl +++ b/core/java/android/net/INetworkPolicyManager.aidl @@ -76,7 +76,7 @@ interface INetworkPolicyManager { SubscriptionPlan[] getSubscriptionPlans(int subId, String callingPackage); void setSubscriptionPlans(int subId, in SubscriptionPlan[] plans, String callingPackage); String getSubscriptionPlansOwner(int subId); - void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long timeoutMillis, String callingPackage); + void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, long networkTypeMask, long timeoutMillis, String callingPackage); void factoryReset(String subscriber); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index ca4caf63f23cf..53854c23baac1 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -380,6 +380,7 @@ public class NetworkPolicyManager { @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { } @Override public void onRestrictBackgroundChanged(boolean restrictBackground) { } @Override public void onUidPoliciesChanged(int uid, int uidPolicies) { } - @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue) { } + @Override public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue, + long networkTypeMask) { } } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index e3e6d9d808270..877c40f946968 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -222,6 +222,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.RoSystemProperties; +import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; @@ -3309,7 +3310,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { @Override public void setSubscriptionOverride(int subId, int overrideMask, int overrideValue, - long timeoutMillis, String callingPackage) { + long networkTypeMask, long timeoutMillis, String callingPackage) { enforceSubscriptionPlanAccess(subId, Binder.getCallingUid(), callingPackage); // We can only override when carrier told us about plans @@ -3327,11 +3328,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(), NETPOLICY_OVERRIDE_ENABLED, 1) != 0; if (overrideEnabled || overrideValue == 0) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, - overrideMask, overrideValue, subId)); + SomeArgs args = SomeArgs.obtain(); + args.arg1 = subId; + args.arg2 = overrideMask; + args.arg3 = overrideValue; + args.arg4 = networkTypeMask; + mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args)); if (timeoutMillis > 0) { - mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, - overrideMask, 0, subId), timeoutMillis); + args.arg3 = 0; + mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE, args), + timeoutMillis); } } } @@ -4467,10 +4473,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } private void dispatchSubscriptionOverride(INetworkPolicyListener listener, int subId, - int overrideMask, int overrideValue) { + int overrideMask, int overrideValue, long networkTypeMask) { if (listener != null) { try { - listener.onSubscriptionOverride(subId, overrideMask, overrideValue); + listener.onSubscriptionOverride(subId, overrideMask, overrideValue, + networkTypeMask); } catch (RemoteException ignored) { } } @@ -4571,13 +4578,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { return true; } case MSG_SUBSCRIPTION_OVERRIDE: { - final int overrideMask = msg.arg1; - final int overrideValue = msg.arg2; - final int subId = (int) msg.obj; + final SomeArgs args = (SomeArgs) msg.obj; + final int subId = (int) args.arg1; + final int overrideMask = (int) args.arg2; + final int overrideValue = (int) args.arg3; + final long networkTypeMask = (long) args.arg4; final int length = mListeners.beginBroadcast(); for (int i = 0; i < length; i++) { final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); - dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue); + dispatchSubscriptionOverride(listener, subId, overrideMask, overrideValue, + networkTypeMask); } mListeners.finishBroadcast(); return true; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 236a209e6f58e..2f37c2a3af5ae 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3017,6 +3017,13 @@ public class CarrierConfigManager { public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL = "ping_test_before_data_switch_bool"; + /** + * Controls time in milli seconds until DcTracker reevaluates 5G connection state. + * @hide + */ + public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = + "5g_watchdog_time_long"; + /** * Indicates zero or more emergency number prefix(es), because some carrier requires * if users dial an emergency number address with a specific prefix, the combination of the @@ -3841,6 +3848,8 @@ public class CarrierConfigManager { /* Default value is 3 seconds. */ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000); sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true); + /* Default value is 1 hour. */ + sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000); sDefaults.putAll(Gps.getDefaults()); sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY, new int[] { diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 29d5463459f40..71ea3a3e7198c 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -54,6 +54,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Telephony.SimInfo; +import android.telephony.Annotation.NetworkType; import android.telephony.euicc.EuiccManager; import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; @@ -2546,10 +2547,51 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long timeoutMillis) { + setSubscriptionOverrideUnmetered(subId, null, overrideUnmetered, timeoutMillis); + } + + /** + * Temporarily override the billing relationship between a carrier and + * a specific subscriber to be considered unmetered for the given network + * types. This will be reflected to apps via + * {@link NetworkCapabilities#NET_CAPABILITY_NOT_METERED}. + * This method is only accessible to the following narrow set of apps: + * + * + * @param subId the subscriber this override applies to. + * @param networkTypes all network types to set an override for. A null + * network type means to apply the override to all network types. + * Any unspecified network types will default to metered. + * @param overrideUnmetered set if the billing relationship should be + * considered unmetered. + * @param timeoutMillis the timeout after which the requested override will + * be automatically cleared, or {@code 0} to leave in the + * requested state until explicitly cleared, or the next reboot, + * whichever happens first. + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. + * {@hide} + */ + public void setSubscriptionOverrideUnmetered(int subId, + @Nullable @NetworkType int[] networkTypes, boolean overrideUnmetered, + @DurationMillisLong long timeoutMillis) { try { + long networkTypeMask = 0; + if (networkTypes != null) { + for (int networkType : networkTypes) { + networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); + } + } else { + networkTypeMask = ~0; + } final int overrideValue = overrideUnmetered ? OVERRIDE_UNMETERED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_UNMETERED, overrideValue, - timeoutMillis, mContext.getOpPackageName()); + networkTypeMask, timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2581,10 +2623,52 @@ public class SubscriptionManager { */ public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long timeoutMillis) { + setSubscriptionOverrideCongested(subId, null, overrideCongested, timeoutMillis); + } + + /** + * Temporarily override the billing relationship plan between a carrier and + * a specific subscriber to be considered congested. This will cause the + * device to delay certain network requests when possible, such as developer + * jobs that are willing to run in a flexible time window. + *

+ * This method is only accessible to the following narrow set of apps: + *

+ * + * @param subId the subscriber this override applies to. + * @param networkTypes all network types to set an override for. A null + * network type means to apply the override to all network types. + * Any unspecified network types will default to not congested. + * @param overrideCongested set if the subscription should be considered + * congested. + * @param timeoutMillis the timeout after which the requested override will + * be automatically cleared, or {@code 0} to leave in the + * requested state until explicitly cleared, or the next reboot, + * whichever happens first. + * @throws SecurityException if the caller doesn't meet the requirements + * outlined above. + * @hide + */ + public void setSubscriptionOverrideCongested(int subId, + @Nullable @NetworkType int[] networkTypes, boolean overrideCongested, + @DurationMillisLong long timeoutMillis) { try { + long networkTypeMask = 0; + if (networkTypes != null) { + for (int networkType : networkTypes) { + networkTypeMask |= TelephonyManager.getBitMaskForNetworkType(networkType); + } + } else { + networkTypeMask = ~0; + } final int overrideValue = overrideCongested ? OVERRIDE_CONGESTED : 0; getNetworkPolicy().setSubscriptionOverride(subId, OVERRIDE_CONGESTED, overrideValue, - timeoutMillis, mContext.getOpPackageName()); + networkTypeMask, timeoutMillis, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e3f2787f1c8c6..cfb8fb4dd4c4d 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2799,6 +2799,55 @@ public class TelephonyManager { } } + /** + * Returns the bitmask for a given technology (network type) + * @param networkType for which bitmask is returned + * @return the network type bitmask + * {@hide} + */ + public static @NetworkTypeBitMask long getBitMaskForNetworkType(@NetworkType int networkType) { + switch(networkType) { + case NETWORK_TYPE_GSM: + return NETWORK_TYPE_BITMASK_GSM; + case NETWORK_TYPE_GPRS: + return NETWORK_TYPE_BITMASK_GPRS; + case NETWORK_TYPE_EDGE: + return NETWORK_TYPE_BITMASK_EDGE; + case NETWORK_TYPE_CDMA: + return NETWORK_TYPE_BITMASK_CDMA; + case NETWORK_TYPE_1xRTT: + return NETWORK_TYPE_BITMASK_1xRTT; + case NETWORK_TYPE_EVDO_0: + return NETWORK_TYPE_BITMASK_EVDO_0; + case NETWORK_TYPE_EVDO_A: + return NETWORK_TYPE_BITMASK_EVDO_A; + case NETWORK_TYPE_EVDO_B: + return NETWORK_TYPE_BITMASK_EVDO_B; + case NETWORK_TYPE_EHRPD: + return NETWORK_TYPE_BITMASK_EHRPD; + case NETWORK_TYPE_HSUPA: + return NETWORK_TYPE_BITMASK_HSUPA; + case NETWORK_TYPE_HSDPA: + return NETWORK_TYPE_BITMASK_HSDPA; + case NETWORK_TYPE_HSPA: + return NETWORK_TYPE_BITMASK_HSPA; + case NETWORK_TYPE_HSPAP: + return NETWORK_TYPE_BITMASK_HSPAP; + case NETWORK_TYPE_UMTS: + return NETWORK_TYPE_BITMASK_UMTS; + case NETWORK_TYPE_TD_SCDMA: + return NETWORK_TYPE_BITMASK_TD_SCDMA; + case NETWORK_TYPE_LTE: + return NETWORK_TYPE_BITMASK_LTE; + case NETWORK_TYPE_LTE_CA: + return NETWORK_TYPE_BITMASK_LTE_CA; + case NETWORK_TYPE_NR: + return NETWORK_TYPE_BITMASK_NR; + default: + return NETWORK_TYPE_BITMASK_UNKNOWN; + } + } + // // // SIM Card diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index e1113eba006f1..668a6af081455 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -111,6 +111,9 @@ public class DctConstants { public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49; public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50; public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51; + public static final int EVENT_5G_NETWORK_CHANGED = BASE + 52; + public static final int EVENT_5G_TIMER_HYSTERESIS = BASE + 53; + public static final int EVENT_5G_TIMER_WATCHDOG = BASE + 54; /***** Constants *****/