Merge changes Ic5551c94,I0207f7f7 into gingerbread

* changes:
  GPS: Clean up GPS API extension initialization in JNI code.
  GPS: Add support for AGpsRilInterface.
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 39ce0b6..e9eb4f0 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -46,6 +46,10 @@
 import android.os.SystemClock;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.provider.Telephony.Sms.Intents;
+import android.telephony.TelephonyManager;
+import android.telephony.gsm.GsmCellLocation;
+import android.telephony.SmsMessage;
 import android.util.Log;
 import android.util.SparseIntArray;
 
@@ -53,6 +57,9 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
+import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.util.HexDump;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -153,6 +160,24 @@
     private static final int REMOVE_LISTENER = 9;
     private static final int REQUEST_SINGLE_SHOT = 10;
 
+    // Request setid
+    private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
+    private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
+
+    // Request ref location
+    private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1;
+    private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2;
+
+    // ref. location info
+    private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
+    private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
+    private static final int AGPS_REG_LOCATION_TYPE_MAC        = 3;
+
+    // set id info
+    private static final int AGPS_SETID_TYPE_NONE = 0;
+    private static final int AGPS_SETID_TYPE_IMSI = 1;
+    private static final int AGPS_SETID_TYPE_MSISDN = 2;
+
     private static final String PROPERTIES_FILE = "/etc/gps.conf";
 
     private int mLocationFlags = LOCATION_INVALID;
@@ -328,10 +353,27 @@
             } else if (action.equals(ALARM_TIMEOUT)) {
                 if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT");
                 hibernate();
-            }
+            } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) {
+                checkSmsSuplInit(intent);
+            } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
+                checkWapSuplInit(intent);
+             }
         }
     };
 
+    private void checkSmsSuplInit(Intent intent) {
+        SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
+        for (int i=0; i <messages.length; i++) {
+            byte[] supl_init = messages[i].getUserData();
+            native_agps_ni_message(supl_init,supl_init.length);
+        }
+    }
+
+    private void checkWapSuplInit(Intent intent) {
+        byte[] supl_init = (byte[]) intent.getExtra("data");
+        native_agps_ni_message(supl_init,supl_init.length);
+    }
+
     public static boolean isSupported() {
         return native_is_supported();
     }
@@ -352,6 +394,21 @@
         mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
         mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
 
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
+        intentFilter.addDataScheme("sms");
+        intentFilter.addDataAuthority("localhost","7275");
+        context.registerReceiver(mBroadcastReciever, intentFilter);
+
+        intentFilter = new IntentFilter();
+        intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
+        try {
+            intentFilter.addDataType("application/vnd.omaloc-supl-init");
+        } catch (IntentFilter.MalformedMimeTypeException e) {
+            Log.w(TAG, "Malformed SUPL init mime type");
+        }
+        context.registerReceiver(mBroadcastReciever, intentFilter);
+
         mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
         // Battery statistics service to be notified when GPS turns on or off
@@ -1255,22 +1312,20 @@
 
     //=============================================================
     // NI Client support
-	//=============================================================
+    //=============================================================
     private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
-    	// Sends a response for an NI reqeust to HAL.
-    	public boolean sendNiResponse(int notificationId, int userResponse)
-    	{
-        	// TODO Add Permission check
-    		
-    		StringBuilder extrasBuf = new StringBuilder();
+        // Sends a response for an NI reqeust to HAL.
+        public boolean sendNiResponse(int notificationId, int userResponse)
+        {
+            // TODO Add Permission check
 
-    		if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
-    				", response: " + userResponse);
-    		
-    		native_send_ni_response(notificationId, userResponse);
-    		
-    		return true;
-    	}        
+            StringBuilder extrasBuf = new StringBuilder();
+
+            if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
+                    ", response: " + userResponse);
+            native_send_ni_response(notificationId, userResponse);
+            return true;
+        }
     };
         
     public INetInitiatedListener getNetInitiatedListener() {
@@ -1278,70 +1333,132 @@
     }
 
     // Called by JNI function to report an NI request.
-	@SuppressWarnings("deprecation")
-	public void reportNiNotification(
-        	int notificationId,
-        	int niType,
-        	int notifyFlags,
-        	int timeout,
-        	int defaultResponse,
-        	String requestorId,
-        	String text,
-        	int requestorIdEncoding,
-        	int textEncoding,
-        	String extras  // Encoded extra data
+    public void reportNiNotification(
+            int notificationId,
+            int niType,
+            int notifyFlags,
+            int timeout,
+            int defaultResponse,
+            String requestorId,
+            String text,
+            int requestorIdEncoding,
+            int textEncoding,
+            String extras  // Encoded extra data
         )
-	{
-		Log.i(TAG, "reportNiNotification: entered");
-		Log.i(TAG, "notificationId: " + notificationId +
-				", niType: " + niType +
-				", notifyFlags: " + notifyFlags +
-				", timeout: " + timeout +
-				", defaultResponse: " + defaultResponse);
-		
-		Log.i(TAG, "requestorId: " + requestorId +
-				", text: " + text +
-				", requestorIdEncoding: " + requestorIdEncoding +
-				", textEncoding: " + textEncoding);
-		
-		GpsNiNotification notification = new GpsNiNotification();
-		
-		notification.notificationId = notificationId;
-		notification.niType = niType;
-		notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
-		notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
-		notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
-		notification.timeout = timeout;
-		notification.defaultResponse = defaultResponse;
-		notification.requestorId = requestorId;
-		notification.text = text;
-		notification.requestorIdEncoding = requestorIdEncoding;
-		notification.textEncoding = textEncoding;
-		
-		// Process extras, assuming the format is
-		// one of more lines of "key = value"
-		Bundle bundle = new Bundle();
-		
-		if (extras == null) extras = "";
-		Properties extraProp = new Properties();
-		
-		try {
-			extraProp.load(new StringBufferInputStream(extras));
-		}
-		catch (IOException e)
-		{
-			Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
-		}
-		
-		for (Entry<Object, Object> ent : extraProp.entrySet())
-		{
-			bundle.putString((String) ent.getKey(), (String) ent.getValue());
-		}		
-		
-		notification.extras = bundle;
-		
-		mNIHandler.handleNiNotification(notification);		
-	}
+    {
+        Log.i(TAG, "reportNiNotification: entered");
+        Log.i(TAG, "notificationId: " + notificationId +
+                ", niType: " + niType +
+                ", notifyFlags: " + notifyFlags +
+                ", timeout: " + timeout +
+                ", defaultResponse: " + defaultResponse);
+
+        Log.i(TAG, "requestorId: " + requestorId +
+                ", text: " + text +
+                ", requestorIdEncoding: " + requestorIdEncoding +
+                ", textEncoding: " + textEncoding);
+
+        GpsNiNotification notification = new GpsNiNotification();
+
+        notification.notificationId = notificationId;
+        notification.niType = niType;
+        notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
+        notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
+        notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
+        notification.timeout = timeout;
+        notification.defaultResponse = defaultResponse;
+        notification.requestorId = requestorId;
+        notification.text = text;
+        notification.requestorIdEncoding = requestorIdEncoding;
+        notification.textEncoding = textEncoding;
+
+        // Process extras, assuming the format is
+        // one of more lines of "key = value"
+        Bundle bundle = new Bundle();
+
+        if (extras == null) extras = "";
+        Properties extraProp = new Properties();
+
+        try {
+            extraProp.load(new StringBufferInputStream(extras));
+        }
+        catch (IOException e)
+        {
+            Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
+        }
+
+        for (Entry<Object, Object> ent : extraProp.entrySet())
+        {
+            bundle.putString((String) ent.getKey(), (String) ent.getValue());
+        }
+
+        notification.extras = bundle;
+
+        mNIHandler.handleNiNotification(notification);
+    }
+
+    /**
+     * Called from native code to request set id info.
+     * We should be careful about receiving null string from the TelephonyManager,
+     * because sending null String to JNI function would cause a crash.
+     */
+
+    private void requestSetID(int flags) {
+        TelephonyManager phone = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        int    type = AGPS_SETID_TYPE_NONE;
+        String data = "";
+
+        if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
+            String data_temp = phone.getSubscriberId();
+            if (data_temp == null) {
+                // This means the framework does not have the SIM card ready.
+            } else {
+                // This means the framework has the SIM card.
+                data = data_temp;
+                type = AGPS_SETID_TYPE_IMSI;
+            }
+        }
+        else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
+            String data_temp = phone.getLine1Number();
+            if (data_temp == null) {
+                // This means the framework does not have the SIM card ready.
+            } else {
+                // This means the framework has the SIM card.
+                data = data_temp;
+                type = AGPS_SETID_TYPE_MSISDN;
+            }
+        }
+        native_agps_set_id(type, data);
+    }
+
+    /**
+     * Called from native code to request reference location info
+     */
+
+    private void requestRefLocation(int flags) {
+        TelephonyManager phone = (TelephonyManager)
+                mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
+            GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
+            if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM)
+                    && (phone.getNetworkOperator().length() > 3)) {
+                int type;
+                int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3));
+                int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
+                if (phone.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)
+                    type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
+                else
+                    type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
+                native_agps_set_ref_location_cellid(type, mcc, mnc,
+                        gsm_cell.getLac(), gsm_cell.getCid());
+            }
+            else
+                Log.e(TAG,"Error getting cell location info.");
+        }
+        else
+            Log.e(TAG,"CDMA not supported.");
+    }
 
     private void sendMessage(int message, int arg, Object obj) {
         // hold a wake lock while messages are pending
@@ -1472,8 +1589,14 @@
     private native void native_agps_data_conn_open(String apn);
     private native void native_agps_data_conn_closed();
     private native void native_agps_data_conn_failed();
+    private native void native_agps_ni_message(byte [] msg, int length);
     private native void native_set_agps_server(int type, String hostname, int port);
 
     // Network-initiated (NI) Support
     private native void native_send_ni_response(int notificationId, int userResponse);
+
+    // AGPS ril suport
+    private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
+            int lac, int cid);
+    private native void native_agps_set_id(int type, String setid);
 }
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 59d7cde..71c7aba 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -40,12 +40,15 @@
 static jmethodID method_setEngineCapabilities;
 static jmethodID method_xtraDownloadRequest;
 static jmethodID method_reportNiNotification;
+static jmethodID method_requestRefLocation;
+static jmethodID method_requestSetID;
 
 static const GpsInterface* sGpsInterface = NULL;
 static const GpsXtraInterface* sGpsXtraInterface = NULL;
 static const AGpsInterface* sAGpsInterface = NULL;
 static const GpsNiInterface* sGpsNiInterface = NULL;
 static const GpsDebugInterface* sGpsDebugInterface = NULL;
+static const AGpsRilInterface* sAGpsRilInterface = NULL;
 
 // temporary storage for GPS callbacks
 static GpsSvStatus  sGpsSvStatus;
@@ -193,17 +196,30 @@
     create_thread_callback,
 };
 
-static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
-    method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
-    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
-    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
-    method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
-    method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
-    method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
-    method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
-    method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
+static void agps_request_set_id(uint32_t flags)
+{
+    LOGD("agps_request_set_id: flags (%d)", flags);
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
 
+static void agps_request_ref_location(uint32_t flags)
+{
+    LOGD("agps_ref_location: flags (%d)", flags);
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+AGpsRilCallbacks sAGpsRilCallbacks = {
+    agps_request_set_id,
+    agps_request_ref_location,
+    create_thread_callback,
+};
+
 static const GpsInterface* get_gps_interface() {
     int err;
     hw_module_t* module;
@@ -222,6 +238,64 @@
     return interface;
 }
 
+static const AGpsInterface* GetAGpsInterface()
+{
+    if (!sGpsInterface)
+        sGpsInterface = get_gps_interface();
+    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+        return NULL;
+
+    if (!sAGpsInterface) {
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+        if (sAGpsInterface)
+            sAGpsInterface->init(&sAGpsCallbacks);
+    }
+    return sAGpsInterface;
+}
+
+static const GpsNiInterface* GetNiInterface()
+{
+    if (!sGpsInterface)
+        sGpsInterface = get_gps_interface();
+    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+        return NULL;
+
+    if (!sGpsNiInterface) {
+       sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
+        if (sGpsNiInterface)
+           sGpsNiInterface->init(&sGpsNiCallbacks);
+    }
+    return sGpsNiInterface;
+}
+
+static const AGpsRilInterface* GetAGpsRilInterface()
+{
+    if (!sGpsInterface)
+        sGpsInterface = get_gps_interface();
+    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
+        return NULL;
+
+    if (!sAGpsRilInterface) {
+       sAGpsRilInterface = (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
+        if (sAGpsRilInterface)
+            sAGpsRilInterface->init(&sAGpsRilCallbacks);
+    }
+    return sAGpsRilInterface;
+}
+
+static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
+    method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
+    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
+    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
+    method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
+    method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
+    method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
+    method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
+    method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
+    method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
+    method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
+}
+
 static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
     if (!sGpsInterface)
         sGpsInterface = get_gps_interface();
@@ -239,16 +313,6 @@
     if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
         return false;
 
-    if (!sAGpsInterface)
-        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
-    if (sAGpsInterface)
-        sAGpsInterface->init(&sAGpsCallbacks);
-
-    if (!sGpsNiInterface)
-       sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
-    if (sGpsNiInterface)
-       sGpsNiInterface->init(&sGpsNiCallbacks);
-
     if (!sGpsDebugInterface)
        sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
 
@@ -313,6 +377,64 @@
     return num_svs;
 }
 
+static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env,
+        jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid)
+{
+    AGpsRefLocation location;
+    const AGpsRilInterface* interface = GetAGpsRilInterface();
+    if (!interface) {
+        LOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
+        return;
+    }
+
+    switch(type) {
+        case AGPS_REF_LOCATION_TYPE_GSM_CELLID:
+        case AGPS_REF_LOCATION_TYPE_UMTS_CELLID:
+            location.type = type;
+            location.u.cellID.mcc = mcc;
+            location.u.cellID.mnc = mnc;
+            location.u.cellID.lac = lac;
+            location.u.cellID.cid = cid;
+            break;
+        default:
+            LOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__);
+            return;
+            break;
+    }
+    interface->set_ref_location(&location, sizeof(location));
+}
+
+static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env,
+        jobject obj, jbyteArray ni_msg, jint size)
+{
+    size_t sz;
+    const AGpsRilInterface* interface = GetAGpsRilInterface();
+    if (!interface) {
+        LOGE("no AGPS RIL interface in send_ni_message");
+        return;
+    }
+    if (size < 0)
+        return;
+    sz = (size_t)size;
+    jbyte* b = env->GetByteArrayElements(ni_msg, 0);
+    interface->ni_message((uint8_t *)b,sz);
+    env->ReleaseByteArrayElements(ni_msg,b,0);
+}
+
+static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env,
+        jobject obj, jint type, jstring  setid_string)
+{
+    const AGpsRilInterface* interface = GetAGpsRilInterface();
+    if (!interface) {
+        LOGE("no AGPS RIL interface in agps_set_id");
+        return;
+    }
+
+    const char *setid = env->GetStringUTFChars(setid_string, NULL);
+    interface->set_set_id(type, setid);
+    env->ReleaseStringUTFChars(setid_string, setid);
+}
+
 static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject obj,
                                             jbyteArray nmeaArray, jint buffer_size)
 {
@@ -363,62 +485,63 @@
 
 static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
 {
-    if (!sAGpsInterface) {
-        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+    const AGpsInterface* interface = GetAGpsInterface();
+    if (!interface) {
+        LOGE("no AGPS interface in agps_data_conn_open");
+        return;
     }
-    if (sAGpsInterface) {
-        if (apn == NULL) {
-            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-            return;
-        }
-        const char *apnStr = env->GetStringUTFChars(apn, NULL);
-        sAGpsInterface->data_conn_open(apnStr);
-        env->ReleaseStringUTFChars(apn, apnStr);
+    if (apn == NULL) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+        return;
     }
+    const char *apnStr = env->GetStringUTFChars(apn, NULL);
+    interface->data_conn_open(apnStr);
+    env->ReleaseStringUTFChars(apn, apnStr);
 }
 
 static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
 {
-    if (!sAGpsInterface) {
-        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+    const AGpsInterface* interface = GetAGpsInterface();
+    if (!interface) {
+        LOGE("no AGPS interface in agps_data_conn_open");
+        return;
     }
-    if (sAGpsInterface) {
-        sAGpsInterface->data_conn_closed();
-    }
+    interface->data_conn_closed();
 }
 
 static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
 {
-    if (!sAGpsInterface) {
-        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+    const AGpsInterface* interface = GetAGpsInterface();
+    if (!interface) {
+        LOGE("no AGPS interface in agps_data_conn_open");
+        return;
     }
-    if (sAGpsInterface) {
-        sAGpsInterface->data_conn_failed();
-    }
+    interface->data_conn_failed();
 }
 
 static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
         jint type, jstring hostname, jint port)
 {
-    if (!sAGpsInterface) {
-        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+    const AGpsInterface* interface = GetAGpsInterface();
+    if (!interface) {
+        LOGE("no AGPS interface in agps_data_conn_open");
+        return;
     }
-    if (sAGpsInterface) {
-        const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
-        sAGpsInterface->set_server(type, c_hostname, port);
-        env->ReleaseStringUTFChars(hostname, c_hostname);
-    }
+    const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
+    interface->set_server(type, c_hostname, port);
+    env->ReleaseStringUTFChars(hostname, c_hostname);
 }
 
 static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
       jint notifId, jint response)
 {
-    if (!sGpsNiInterface) {
-        sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
+    const GpsNiInterface* interface = GetNiInterface();
+    if (!interface) {
+        LOGE("no NI interface in send_ni_response");
+        return;
     }
-    if (sGpsNiInterface) {
-        sGpsNiInterface->respond(notifId, response);
-    }
+
+    interface->respond(notifId, response);
 }
 
 static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
@@ -454,8 +577,11 @@
     {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
     {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed},
     {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
+    {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id},
+    {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid},
     {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server},
     {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response},
+    {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message},
     {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
 };
 
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index a636a4b..168b63b 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -132,6 +132,9 @@
                 case WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF:
                     mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF;
                     break;
+                case WspTypeDecoder.CONTENT_TYPE_B_SUPL_INIT:
+                    mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_SUPL_INIT;
+                    break;
                 default:
                     if (Config.LOGD) {
                         Log.w(LOG_TAG,
@@ -154,6 +157,8 @@
                 binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
             } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF)) {
                 binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF;
+            } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_SUPL_INIT)) {
+                binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_SUPL_INIT;
             } else {
                 if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
                 return Intents.RESULT_SMS_HANDLED;
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 336bc82..5dc89f0 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -40,6 +40,7 @@
     public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
     public static final int CONTENT_TYPE_B_MMS = 0x3e;
     public static final int CONTENT_TYPE_B_VND_DOCOMO_PF = 0x0310;
+    public static final int CONTENT_TYPE_B_SUPL_INIT = 0x312;
 
     public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
             "application/vnd.oma.drm.rights+xml";
@@ -50,6 +51,7 @@
     public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
     public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
     public static final String CONTENT_MIME_TYPE_B_VND_DOCOMO_PF = "application/vnd.docomo.pf";
+    public static final String CONTENT_MIME_TYPE_B_SUPL_INIT = "application/vnd.omaloc-supl-init";
 
     public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;