Merge changes from topic "128616035"

* changes:
  Adding @hide API to return whether an APN is metered or not.
  Add API to set alwaysAllowMms
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 586c815..58c05aa 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -294,6 +294,19 @@
     public static final String SUBSCRIPTION_TYPE = "subscription_type";
 
     /**
+     * TelephonyProvider column name white_listed_apn_data.
+     * It's a bitmask of APN types that will be allowed on this subscription even if it's metered
+     * and mobile data is turned off by the user.
+     * <P>Type: INTEGER (int)</P> For example, if TYPE_MMS is is true, Telephony will allow MMS
+     * data connection to setup even if MMS is metered and mobile_data is turned off on that
+     * subscription.
+     *
+     * Default value is 0.
+     */
+    /** @hide */
+    public static final String WHITE_LISTED_APN_DATA = "white_listed_apn_data";
+
+    /**
      * This constant is to designate a subscription as a Local-SIM Subscription.
      * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
      * device.
@@ -3087,6 +3100,31 @@
         return subId;
     }
 
+    /**
+     * Set whether a subscription always allows MMS connection. If true, MMS network
+     * request will be accepted by telephony even if user turns "mobile data" off
+     * on this subscription.
+     *
+     * @param subId which subscription it's setting to.
+     * @param alwaysAllow whether Mms data is always allowed.
+     * @return whether operation is successful.
+     *
+     * @hide
+     */
+    public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                return iSub.setAlwaysAllowMmsData(subId, alwaysAllow);
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
+
     private interface CallISubMethodHelper {
         int callMethod(ISub iSub) throws RemoteException;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e1425b9..82cc1df 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -64,6 +64,7 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.VisualVoicemailService.VisualVoicemailTask;
+import android.telephony.data.ApnSetting;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
 import android.telephony.ims.aidl.IImsConfig;
@@ -10888,4 +10889,58 @@
         }
         return new Pair<Integer, Integer>(-1, -1);
     }
+
+    /**
+     * Return whether data is enabled for certain APN type. This will tell if framework will accept
+     * corresponding network requests on a subId.
+     *
+     * {@link #isDataEnabled()} is directly associated with users' Mobile data toggle on / off. If
+     * {@link #isDataEnabled()} returns false, it means in general all meter-ed data are disabled.
+     *
+     * This per APN type API gives a better idea whether data is allowed on a specific APN type.
+     * It will return true if:
+     *
+     *  1) User data is turned on, or
+     *  2) APN is un-metered for this subscription, or
+     *  3) APN type is whitelisted. E.g. MMS is whitelisted if
+     *  {@link SubscriptionManager#setAlwaysAllowMmsData} is turned on.
+     *
+     * @return whether data is enabled for a apn type.
+     *
+     * @hide
+     */
+    public boolean isDataEnabledForApn(@ApnSetting.ApnType int apnType) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.isDataEnabledForApn(apnType, getSubId(), pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Whether an APN type is metered or not. It will be evaluated with the subId associated
+     * with the TelephonyManager instance.
+     *
+     * @hide
+     */
+    public boolean isApnMetered(@ApnSetting.ApnType int apnType) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.isApnMetered(apnType, getSubId());
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 6e8d038..bb5c251 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -94,6 +94,7 @@
     public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
     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_APN_WHITE_LIST_CHANGE = BASE + 51;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 118f5e2..f248893 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -283,4 +283,6 @@
     int getSimStateForSlotIndex(int slotIndex);
 
     boolean isActiveSubId(int subId, String callingPackage);
+
+    boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d173cc9..0ad6096 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1958,4 +1958,8 @@
     int getRadioHalVersion();
 
     boolean isModemEnabledForSlot(int slotIndex, String callingPackage);
+
+    boolean isDataEnabledForApn(int apnType, int subId, String callingPackage);
+
+    boolean isApnMetered(int apnType, int subId);
 }