telephony: Add support for bringing up GSM data connections for GPS SUPL.

Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index ed7c056..1064fb6 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -354,9 +354,10 @@
 
     /**
      * Tells the phone sub-system that the caller wants to
-     * begin using the named feature. The only supported feature at
-     * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
-     * to specify that it wants to send and/or receive MMS data.
+     * begin using the named feature. The only supported features at
+     * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
+     * to specify that it wants to send and/or receive MMS data, and
+     * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS.
      * @param feature the name of the feature to be used
      * @param callingPid the process ID of the process that is issuing this request
      * @param callingUid the user ID of the process that is issuing this request
@@ -376,6 +377,8 @@
         if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
             mLastCallingPid = callingPid;
             return setEnableApn(Phone.APN_TYPE_MMS, true);
+        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
+            return setEnableApn(Phone.APN_TYPE_SUPL, true);
         } else {
             return -1;
         }
@@ -396,6 +399,8 @@
     public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
         if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
             return setEnableApn(Phone.APN_TYPE_MMS, false);
+        } else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
+            return setEnableApn(Phone.APN_TYPE_SUPL, false);
         } else {
             return -1;
         }
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 62949b0..3f210ca 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -113,9 +113,12 @@
     static final String APN_TYPE_DEFAULT = "default";
     /** APN type for MMS traffic */
     static final String APN_TYPE_MMS = "mms";
+    /** APN type for SUPL assisted GPS */
+    static final String APN_TYPE_SUPL = "supl";
 
     // "Features" accessible through the connectivity manager
     static final String FEATURE_ENABLE_MMS = "enableMMS";
+    static final String FEATURE_ENABLE_SUPL = "enableSUPL";
 
     /**
      * Return codes for <code>enableApnType()</code>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index ed617ef..87e8b62 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -228,6 +228,9 @@
         Log.d(LOG_TAG, "Request to enableApnType("+type+")");
         if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
             return Phone.APN_ALREADY_ACTIVE;
+        } else if (TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
+            Log.w(LOG_TAG, "Phone.APN_TYPE_SUPL not enabled for CDMA");
+            return Phone.APN_REQUEST_FAILED;
         } else {
             return Phone.APN_REQUEST_FAILED;
         }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e2da7cb..1b07add 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -131,7 +131,8 @@
 
     private static int APN_DEFAULT_ID = 0;
     private static int APN_MMS_ID = 1;
-    private static int APN_NUM_TYPES = 2;
+    private static int APN_SUPL_ID = 2;
+    private static int APN_NUM_TYPES = 3;
 
     private boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
 
@@ -322,8 +323,8 @@
 
     /**
      * Ensure that we are connected to an APN of the specified type.
-     * @param type the APN type (currently the only valid value
-     * is {@link Phone#APN_TYPE_MMS})
+     * @param type the APN type (currently the only valid values
+     * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
      * @return the result of the operation. Success is indicated by
      * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or
      * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast
@@ -331,9 +332,11 @@
      * the APN has been established.
      */
     protected int enableApnType(String type) {
-        if (!TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+        if (!TextUtils.equals(type, Phone.APN_TYPE_MMS) &&
+                !TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
             return Phone.APN_REQUEST_FAILED;
         }
+
         // If already active, return
         Log.d(LOG_TAG, "enableApnType("+type+")");
         if (isApnTypeActive(type)) {
@@ -371,7 +374,8 @@
      */
     protected int disableApnType(String type) {
         Log.d(LOG_TAG, "disableApnType("+type+")");
-        if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) {
+        if (TextUtils.equals(type, Phone.APN_TYPE_MMS) ||
+                TextUtils.equals(type, Phone.APN_TYPE_SUPL)) {
             removeMessages(EVENT_RESTORE_DEFAULT_APN);
             setEnabled(type, false);
             if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
@@ -439,6 +443,8 @@
             return dataEnabled[APN_DEFAULT_ID];
         } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) {
             return dataEnabled[APN_MMS_ID];
+        } else if (TextUtils.equals(apnType, Phone.APN_TYPE_SUPL)) {
+            return dataEnabled[APN_SUPL_ID];
         } else {
             return false;
         }
@@ -450,9 +456,12 @@
             dataEnabled[APN_DEFAULT_ID] = enable;
         } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) {
             dataEnabled[APN_MMS_ID] = enable;
+        } else if (TextUtils.equals(apnType, Phone.APN_TYPE_SUPL)) {
+            dataEnabled[APN_SUPL_ID] = enable;
         }
         Log.d(LOG_TAG, "dataEnabled[DEFAULT_APN]=" + dataEnabled[APN_DEFAULT_ID] +
-                " dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID]);
+                " dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID] +
+                " dataEnabled[SUPL_APN]=" + dataEnabled[APN_SUPL_ID]);
     }
 
     /**
@@ -476,13 +485,14 @@
             return trySetupData(Phone.REASON_DATA_ENABLED);
         } else if (!enable) {
             setEnabled(Phone.APN_TYPE_DEFAULT, false);
-            // Don't tear down if there is an active APN and it handles MMS.
+            // Don't tear down if there is an active APN and it handles MMS or SUPL.
             // TODO: This isn't very general.
-            if (!isApnTypeActive(Phone.APN_TYPE_MMS) || !isEnabled(Phone.APN_TYPE_MMS)) {
-                cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
-                return true;
+            if ((isApnTypeActive(Phone.APN_TYPE_MMS) && isEnabled(Phone.APN_TYPE_MMS)) ||
+                (isApnTypeActive(Phone.APN_TYPE_SUPL) && isEnabled(Phone.APN_TYPE_SUPL))) {
+                return false;
             }
-            return false;
+            cleanUpConnection(true, Phone.REASON_DATA_DISABLED);
+            return true;
         } else {
             // isEnabled && enable
             return true;
@@ -513,7 +523,7 @@
      * {@code true} otherwise.
      */
     public boolean getAnyDataEnabled() {
-        return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID];
+        return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID] || dataEnabled[APN_SUPL_ID];
     }
 
     /**
@@ -1316,7 +1326,7 @@
              * rather an app that inadvertantly fails to reset to the
              * default APN, or that dies before doing so.
              */
-            if (dataEnabled[APN_MMS_ID]) {
+            if (dataEnabled[APN_MMS_ID] || dataEnabled[APN_SUPL_ID]) {
                 removeMessages(EVENT_RESTORE_DEFAULT_APN);
                 sendMessageDelayed(obtainMessage(EVENT_RESTORE_DEFAULT_APN),
                         getRestoreDefaultApnDelay());