Loading services/java/com/android/server/location/GpsLocationProvider.java +202 −79 Original line number Diff line number Diff line Loading @@ -46,6 +46,10 @@ import android.os.ServiceManager; 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; Loading @@ -53,6 +57,9 @@ import com.android.internal.app.IBatteryStats; 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; Loading Loading @@ -153,6 +160,24 @@ public class GpsLocationProvider implements LocationProviderInterface { 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; Loading Loading @@ -328,10 +353,27 @@ public class GpsLocationProvider implements LocationProviderInterface { } 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(); } Loading @@ -352,6 +394,21 @@ public class GpsLocationProvider implements LocationProviderInterface { 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 Loading Loading @@ -1266,9 +1323,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + ", response: " + userResponse); native_send_ni_response(notificationId, userResponse); return true; } }; Loading @@ -1278,7 +1333,6 @@ public class GpsLocationProvider implements LocationProviderInterface { } // Called by JNI function to report an NI request. @SuppressWarnings("deprecation") public void reportNiNotification( int notificationId, int niType, Loading Loading @@ -1343,6 +1397,69 @@ public class GpsLocationProvider implements LocationProviderInterface { 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 synchronized (mWakeLock) { Loading Loading @@ -1472,8 +1589,14 @@ public class GpsLocationProvider implements LocationProviderInterface { 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); } services/jni/com_android_server_location_GpsLocationProvider.cpp +178 −50 Original line number Diff line number Diff line Loading @@ -40,12 +40,15 @@ static jmethodID method_reportNmea; 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; Loading Loading @@ -193,17 +196,30 @@ GpsNiCallbacks sGpsNiCallbacks = { 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; Loading @@ -222,6 +238,64 @@ static const GpsInterface* get_gps_interface() { 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(); Loading @@ -239,16 +313,6 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o 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); Loading Loading @@ -313,6 +377,64 @@ static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, job 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) { Loading Loading @@ -363,60 +485,63 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j 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); 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); } if (sAGpsInterface) { sAGpsInterface->data_conn_closed(); const AGpsInterface* interface = GetAGpsInterface(); if (!interface) { LOGE("no AGPS interface in agps_data_conn_open"); return; } 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); } if (sAGpsInterface) { sAGpsInterface->data_conn_failed(); const AGpsInterface* interface = GetAGpsInterface(); if (!interface) { LOGE("no AGPS interface in agps_data_conn_open"); return; } 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); 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); if (sGpsNiInterface) sGpsNiInterface->respond(notifId, response); const GpsNiInterface* interface = GetNiInterface(); if (!interface) { LOGE("no NI interface in send_ni_response"); return; } interface->respond(notifId, response); } static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj) Loading Loading @@ -452,8 +577,11 @@ static JNINativeMethod sMethods[] = { {"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}, }; Loading Loading
services/java/com/android/server/location/GpsLocationProvider.java +202 −79 Original line number Diff line number Diff line Loading @@ -46,6 +46,10 @@ import android.os.ServiceManager; 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; Loading @@ -53,6 +57,9 @@ import com.android.internal.app.IBatteryStats; 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; Loading Loading @@ -153,6 +160,24 @@ public class GpsLocationProvider implements LocationProviderInterface { 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; Loading Loading @@ -328,10 +353,27 @@ public class GpsLocationProvider implements LocationProviderInterface { } 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(); } Loading @@ -352,6 +394,21 @@ public class GpsLocationProvider implements LocationProviderInterface { 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 Loading Loading @@ -1266,9 +1323,7 @@ public class GpsLocationProvider implements LocationProviderInterface { if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + ", response: " + userResponse); native_send_ni_response(notificationId, userResponse); return true; } }; Loading @@ -1278,7 +1333,6 @@ public class GpsLocationProvider implements LocationProviderInterface { } // Called by JNI function to report an NI request. @SuppressWarnings("deprecation") public void reportNiNotification( int notificationId, int niType, Loading Loading @@ -1343,6 +1397,69 @@ public class GpsLocationProvider implements LocationProviderInterface { 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 synchronized (mWakeLock) { Loading Loading @@ -1472,8 +1589,14 @@ public class GpsLocationProvider implements LocationProviderInterface { 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); }
services/jni/com_android_server_location_GpsLocationProvider.cpp +178 −50 Original line number Diff line number Diff line Loading @@ -40,12 +40,15 @@ static jmethodID method_reportNmea; 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; Loading Loading @@ -193,17 +196,30 @@ GpsNiCallbacks sGpsNiCallbacks = { 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; Loading @@ -222,6 +238,64 @@ static const GpsInterface* get_gps_interface() { 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(); Loading @@ -239,16 +313,6 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o 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); Loading Loading @@ -313,6 +377,64 @@ static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, job 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) { Loading Loading @@ -363,60 +485,63 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j 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); 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); } if (sAGpsInterface) { sAGpsInterface->data_conn_closed(); const AGpsInterface* interface = GetAGpsInterface(); if (!interface) { LOGE("no AGPS interface in agps_data_conn_open"); return; } 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); } if (sAGpsInterface) { sAGpsInterface->data_conn_failed(); const AGpsInterface* interface = GetAGpsInterface(); if (!interface) { LOGE("no AGPS interface in agps_data_conn_open"); return; } 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); 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); if (sGpsNiInterface) sGpsNiInterface->respond(notifId, response); const GpsNiInterface* interface = GetNiInterface(); if (!interface) { LOGE("no NI interface in send_ni_response"); return; } interface->respond(notifId, response); } static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj) Loading Loading @@ -452,8 +577,11 @@ static JNINativeMethod sMethods[] = { {"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}, }; Loading