Loading core/jni/android_location_GpsLocationProvider.cpp +55 −62 Original line number Diff line number Diff line Loading @@ -31,31 +31,31 @@ static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; static jmethodID method_reportLocation; static jmethodID method_reportStatus; static jmethodID method_reportSvStatus; static jmethodID method_reportSuplStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_xtraDownloadRequest; static const GpsInterface* sGpsInterface = NULL; static const GpsXtraInterface* sGpsXtraInterface = NULL; static const GpsSuplInterface* sGpsSuplInterface = NULL; static const AGpsInterface* sAGpsInterface = NULL; // data written to by GPS callbacks static GpsLocation sGpsLocation; static GpsStatus sGpsStatus; static GpsSvStatus sGpsSvStatus; static GpsSuplStatus sGpsSuplStatus; static AGpsStatus sAGpsStatus; // a copy of the data shared by android_location_GpsLocationProvider_wait_for_event // and android_location_GpsLocationProvider_read_status static GpsLocation sGpsLocationCopy; static GpsStatus sGpsStatusCopy; static GpsSvStatus sGpsSvStatusCopy; static GpsSuplStatus sGpsSuplStatusCopy; static AGpsStatus sAGpsStatusCopy; enum CallbackType { kLocation = 1, kStatus = 2, kSvStatus = 4, kSuplStatus = 8, kAGpsStatus = 8, kXtraDownloadRequest = 16, kDisableRequest = 32, }; Loading Loading @@ -96,12 +96,12 @@ static void sv_status_callback(GpsSvStatus* sv_status) pthread_mutex_unlock(&sEventMutex); } static void supl_status_callback(GpsSuplStatus* supl_status) static void agps_status_callback(AGpsStatus* agps_status) { pthread_mutex_lock(&sEventMutex); sPendingCallbacks |= kSuplStatus; memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus)); sPendingCallbacks |= kAGpsStatus; memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus)); pthread_cond_signal(&sEventCond); pthread_mutex_unlock(&sEventMutex); Loading @@ -126,15 +126,15 @@ GpsXtraCallbacks sGpsXtraCallbacks = { download_request_callback, }; GpsSuplCallbacks sGpsSuplCallbacks = { supl_status_callback, AGpsCallbacks sAGpsCallbacks = { agps_status_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_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); } Loading @@ -151,10 +151,10 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) return false; if (!sGpsSuplInterface) sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (sGpsSuplInterface) sGpsSuplInterface->init(&sGpsSuplCallbacks); if (!sAGpsInterface) sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); if (sAGpsInterface) sAGpsInterface->init(&sAGpsCallbacks); return true; } Loading Loading @@ -187,12 +187,6 @@ static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject o return (sGpsInterface->stop() == 0); } static void android_location_GpsLocationProvider_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency) { if (sGpsInterface->set_fix_frequency) sGpsInterface->set_fix_frequency(fixFrequency); } static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) { sGpsInterface->delete_aiding_data(flags); Loading @@ -212,7 +206,7 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy)); memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy)); pthread_mutex_unlock(&sEventMutex); if (pendingCallbacks & kLocation) { Loading @@ -228,8 +222,8 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job if (pendingCallbacks & kSvStatus) { env->CallVoidMethod(obj, method_reportSvStatus); } if (pendingCallbacks & kSuplStatus) { env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status); if (pendingCallbacks & kAGpsStatus) { env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status); } if (pendingCallbacks & kXtraDownloadRequest) { env->CallVoidMethod(obj, method_xtraDownloadRequest); Loading Loading @@ -299,50 +293,50 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j env->ReleaseByteArrayElements(data, bytes, 0); } static void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn) static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { if (sAGpsInterface) { if (apn == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } const char *apnStr = env->GetStringUTFChars(apn, NULL); sGpsSuplInterface->data_conn_open(apnStr); sAGpsInterface->data_conn_open(apnStr); env->ReleaseStringUTFChars(apn, apnStr); } } static void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj) static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->data_conn_closed(); if (sAGpsInterface) { sAGpsInterface->data_conn_closed(); } } static void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj) static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->data_conn_failed(); if (sAGpsInterface) { sAGpsInterface->data_conn_failed(); } } static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj, jint addr, jint port) static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, jint type, jint addr, jint port) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->set_server(addr, port); if (sAGpsInterface) { sAGpsInterface->set_server(type, addr, port); } } Loading @@ -355,17 +349,16 @@ static JNINativeMethod sMethods[] = { {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start}, {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, {"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency}, {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event}, {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, {"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open}, {"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed}, {"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed}, {"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server}, {"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_set_agps_server", "(III)V", (void*)android_location_GpsLocationProvider_set_agps_server}, }; int register_android_location_GpsLocationProvider(JNIEnv* env) Loading location/java/com/android/internal/location/GpsLocationProvider.java +100 −67 Original line number Diff line number Diff line Loading @@ -109,13 +109,13 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int GPS_STATUS_ENGINE_ON = 3; private static final int GPS_STATUS_ENGINE_OFF = 4; // these need to match GpsSuplStatusValue defines in gps.h /** SUPL status event values. */ private static final int GPS_REQUEST_SUPL_DATA_CONN = 1; private static final int GPS_RELEASE_SUPL_DATA_CONN = 2; private static final int GPS_SUPL_DATA_CONNECTED = 3; private static final int GPS_SUPL_DATA_CONN_DONE = 4; private static final int GPS_SUPL_DATA_CONN_FAILED = 5; // these need to match GpsApgsStatusValue defines in gps.h /** AGPS status event values. */ private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; private static final int GPS_AGPS_DATA_CONNECTED = 3; private static final int GPS_AGPS_DATA_CONN_DONE = 4; private static final int GPS_AGPS_DATA_CONN_FAILED = 5; // these need to match GpsLocationFlags enum in gps.h private static final int LOCATION_INVALID = 0; Loading @@ -125,7 +125,7 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int LOCATION_HAS_BEARING = 8; private static final int LOCATION_HAS_ACCURACY = 16; // IMPORTANT - the GPS_DELETE_* symbols here must match constants in GpsLocationProvider.java // IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h private static final int GPS_DELETE_EPHEMERIS = 0x0001; private static final int GPS_DELETE_ALMANAC = 0x0002; private static final int GPS_DELETE_POSITION = 0x0004; Loading @@ -140,10 +140,14 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int GPS_DELETE_CELLDB_INFO = 0x8000; private static final int GPS_DELETE_ALL = 0xFFFF; // for mSuplDataConnectionState private static final int SUPL_DATA_CONNECTION_CLOSED = 0; private static final int SUPL_DATA_CONNECTION_OPENING = 1; private static final int SUPL_DATA_CONNECTION_OPEN = 2; // these need to match AGpsType enum in gps.h private static final int AGPS_TYPE_SUPL = 1; private static final int AGPS_TYPE_C2K = 2; // for mAGpsDataConnectionState private static final int AGPS_DATA_CONNECTION_CLOSED = 0; private static final int AGPS_DATA_CONNECTION_OPENING = 1; private static final int AGPS_DATA_CONNECTION_OPEN = 2; private static final String PROPERTIES_FILE = "/etc/gps.conf"; Loading Loading @@ -203,9 +207,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private String mSuplHost; private int mSuplPort; private String mC2KHost; private int mC2KPort; private boolean mSetSuplServer; private String mSuplApn; private int mSuplDataConnectionState; private boolean mSetC2KServer; private String mAGpsApn; private int mAGpsDataConnectionState; private final ConnectivityManager mConnMgr; // Wakelocks Loading Loading @@ -293,11 +300,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub { if (Config.LOGD) { Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); } // FIXME - might not have an APN on CDMA if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) { mSuplApn = apnName; if (mSuplDataConnectionState == SUPL_DATA_CONNECTION_OPENING) { native_supl_data_conn_open(mSuplApn); mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; mAGpsApn = apnName; if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { native_agps_data_conn_open(mAGpsApn); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } } } Loading Loading @@ -336,14 +344,26 @@ public class GpsLocationProvider extends ILocationProvider.Stub { mProperties.load(stream); stream.close(); mNtpServer = mProperties.getProperty("NTP_SERVER", null); mSuplHost = mProperties.getProperty("SUPL_HOST"); String suplPortString = mProperties.getProperty("SUPL_PORT"); if (mSuplHost != null && suplPortString != null) { String portString = mProperties.getProperty("SUPL_PORT"); if (mSuplHost != null && portString != null) { try { mSuplPort = Integer.parseInt(suplPortString); mSuplPort = Integer.parseInt(portString); mSetSuplServer = true; } catch (NumberFormatException e) { Log.e(TAG, "unable to parse SUPL_PORT: " + suplPortString); Log.e(TAG, "unable to parse SUPL_PORT: " + portString); } } mC2KHost = mProperties.getProperty("C2K_HOST"); portString = mProperties.getProperty("C2K_PORT"); if (mC2KHost != null && portString != null) { try { mC2KPort = Integer.parseInt(portString); mSetC2KServer = true; } catch (NumberFormatException e) { Log.e(TAG, "unable to parse C2K_PORT: " + portString); } } } catch (IOException e) { Loading @@ -358,7 +378,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub { public boolean requiresNetwork() { // We want updateNetworkState() to get called when the network state changes // for XTRA and NTP time injection support. return (mNtpServer != null || native_supports_xtra() || mSuplHost != null); return (mNtpServer != null || native_supports_xtra() || mSuplHost != null || mC2KHost != null); } public void updateNetworkState(int state) { Loading Loading @@ -561,7 +582,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub { interval = 1; } mFixInterval = interval; native_set_fix_frequency(mFixInterval); } } Loading Loading @@ -871,38 +891,38 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } /** * called from native code to update SUPL status * called from native code to update AGPS status */ private void reportSuplStatus(int status) { private void reportAGpsStatus(int type, int status) { switch (status) { case GPS_REQUEST_SUPL_DATA_CONN: case GPS_REQUEST_AGPS_DATA_CONN: int result = mConnMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); if (result == Phone.APN_ALREADY_ACTIVE) { native_supl_data_conn_open(mSuplApn); mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; native_agps_data_conn_open(mAGpsApn); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } else if (result == Phone.APN_REQUEST_STARTED) { mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPENING; mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; } else { native_supl_data_conn_failed(); native_agps_data_conn_failed(); } break; case GPS_RELEASE_SUPL_DATA_CONN: if (mSuplDataConnectionState != SUPL_DATA_CONNECTION_CLOSED) { case GPS_RELEASE_AGPS_DATA_CONN: if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { mConnMgr.stopUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); native_supl_data_conn_closed(); mSuplDataConnectionState = SUPL_DATA_CONNECTION_CLOSED; native_agps_data_conn_closed(); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; } break; case GPS_SUPL_DATA_CONNECTED: // Log.d(TAG, "GPS_SUPL_DATA_CONNECTED"); case GPS_AGPS_DATA_CONNECTED: // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); break; case GPS_SUPL_DATA_CONN_DONE: // Log.d(TAG, "GPS_SUPL_DATA_CONN_DONE"); case GPS_AGPS_DATA_CONN_DONE: // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); break; case GPS_SUPL_DATA_CONN_FAILED: // Log.d(TAG, "GPS_SUPL_DATA_CONN_FAILED"); case GPS_AGPS_DATA_CONN_FAILED: // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); break; } } Loading @@ -914,6 +934,29 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } private boolean setAGpsServer(int type, String host, int port) { try { InetAddress inetAddress = InetAddress.getByName(host); if (inetAddress != null) { byte[] addrBytes = inetAddress.getAddress(); long addr = 0; for (int i = 0; i < addrBytes.length; i++) { int temp = addrBytes[i]; // signed -> unsigned if (temp < 0) temp = 256 + temp; addr = addr * 256 + temp; } // use MS-Based position mode if SUPL support is enabled mPositionMode = GPS_POSITION_MODE_MS_BASED; native_set_agps_server(type, (int)addr, port); } } catch (UnknownHostException e) { Log.e(TAG, "unknown host for server " + host); return false; } return true; } private class GpsEventThread extends Thread { public GpsEventThread() { Loading Loading @@ -985,7 +1028,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } waitTime = getWaitTime(); } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && waitTime > 0) } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && !mSetC2KServer && waitTime > 0) || !mNetworkAvailable)); if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); Loading @@ -1012,26 +1056,15 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } // Set the SUPL server address if we have not yet // Set the AGPS server addresses if we have not yet if (mSetSuplServer) { try { InetAddress inetAddress = InetAddress.getByName(mSuplHost); if (inetAddress != null) { byte[] addrBytes = inetAddress.getAddress(); long addr = 0; for (int i = 0; i < addrBytes.length; i++) { int temp = addrBytes[i]; // signed -> unsigned if (temp < 0) temp = 256 + temp; addr = addr * 256 + temp; } // use MS-Based position mode if SUPL support is enabled mPositionMode = GPS_POSITION_MODE_MS_BASED; native_set_supl_server((int)addr, mSuplPort); if (setAGpsServer(AGPS_TYPE_SUPL, mSuplHost, mSuplPort)) { mSetSuplServer = false; } } catch (UnknownHostException e) { Log.e(TAG, "unknown host for SUPL server " + mSuplHost); } if (mSetC2KServer) { if (setAGpsServer(AGPS_TYPE_C2K, mC2KHost, mC2KPort)) { mSetC2KServer = false; } } Loading Loading @@ -1125,9 +1158,9 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private native boolean native_supports_xtra(); private native void native_inject_xtra_data(byte[] data, int length); // SUPL Support private native void native_supl_data_conn_open(String apn); private native void native_supl_data_conn_closed(); private native void native_supl_data_conn_failed(); private native void native_set_supl_server(int addr, int port); // AGPS Support 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_set_agps_server(int type, int addr, int port); } Loading
core/jni/android_location_GpsLocationProvider.cpp +55 −62 Original line number Diff line number Diff line Loading @@ -31,31 +31,31 @@ static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; static jmethodID method_reportLocation; static jmethodID method_reportStatus; static jmethodID method_reportSvStatus; static jmethodID method_reportSuplStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_xtraDownloadRequest; static const GpsInterface* sGpsInterface = NULL; static const GpsXtraInterface* sGpsXtraInterface = NULL; static const GpsSuplInterface* sGpsSuplInterface = NULL; static const AGpsInterface* sAGpsInterface = NULL; // data written to by GPS callbacks static GpsLocation sGpsLocation; static GpsStatus sGpsStatus; static GpsSvStatus sGpsSvStatus; static GpsSuplStatus sGpsSuplStatus; static AGpsStatus sAGpsStatus; // a copy of the data shared by android_location_GpsLocationProvider_wait_for_event // and android_location_GpsLocationProvider_read_status static GpsLocation sGpsLocationCopy; static GpsStatus sGpsStatusCopy; static GpsSvStatus sGpsSvStatusCopy; static GpsSuplStatus sGpsSuplStatusCopy; static AGpsStatus sAGpsStatusCopy; enum CallbackType { kLocation = 1, kStatus = 2, kSvStatus = 4, kSuplStatus = 8, kAGpsStatus = 8, kXtraDownloadRequest = 16, kDisableRequest = 32, }; Loading Loading @@ -96,12 +96,12 @@ static void sv_status_callback(GpsSvStatus* sv_status) pthread_mutex_unlock(&sEventMutex); } static void supl_status_callback(GpsSuplStatus* supl_status) static void agps_status_callback(AGpsStatus* agps_status) { pthread_mutex_lock(&sEventMutex); sPendingCallbacks |= kSuplStatus; memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus)); sPendingCallbacks |= kAGpsStatus; memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus)); pthread_cond_signal(&sEventCond); pthread_mutex_unlock(&sEventMutex); Loading @@ -126,15 +126,15 @@ GpsXtraCallbacks sGpsXtraCallbacks = { download_request_callback, }; GpsSuplCallbacks sGpsSuplCallbacks = { supl_status_callback, AGpsCallbacks sAGpsCallbacks = { agps_status_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_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); } Loading @@ -151,10 +151,10 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) return false; if (!sGpsSuplInterface) sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (sGpsSuplInterface) sGpsSuplInterface->init(&sGpsSuplCallbacks); if (!sAGpsInterface) sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); if (sAGpsInterface) sAGpsInterface->init(&sAGpsCallbacks); return true; } Loading Loading @@ -187,12 +187,6 @@ static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject o return (sGpsInterface->stop() == 0); } static void android_location_GpsLocationProvider_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency) { if (sGpsInterface->set_fix_frequency) sGpsInterface->set_fix_frequency(fixFrequency); } static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags) { sGpsInterface->delete_aiding_data(flags); Loading @@ -212,7 +206,7 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy)); memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy)); memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy)); memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy)); memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy)); pthread_mutex_unlock(&sEventMutex); if (pendingCallbacks & kLocation) { Loading @@ -228,8 +222,8 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job if (pendingCallbacks & kSvStatus) { env->CallVoidMethod(obj, method_reportSvStatus); } if (pendingCallbacks & kSuplStatus) { env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status); if (pendingCallbacks & kAGpsStatus) { env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status); } if (pendingCallbacks & kXtraDownloadRequest) { env->CallVoidMethod(obj, method_xtraDownloadRequest); Loading Loading @@ -299,50 +293,50 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j env->ReleaseByteArrayElements(data, bytes, 0); } static void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn) static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { if (sAGpsInterface) { if (apn == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return; } const char *apnStr = env->GetStringUTFChars(apn, NULL); sGpsSuplInterface->data_conn_open(apnStr); sAGpsInterface->data_conn_open(apnStr); env->ReleaseStringUTFChars(apn, apnStr); } } static void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj) static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->data_conn_closed(); if (sAGpsInterface) { sAGpsInterface->data_conn_closed(); } } static void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj) static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->data_conn_failed(); if (sAGpsInterface) { sAGpsInterface->data_conn_failed(); } } static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj, jint addr, jint port) static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj, jint type, jint addr, jint port) { if (!sGpsSuplInterface) { sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE); if (!sAGpsInterface) { sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE); } if (sGpsSuplInterface) { sGpsSuplInterface->set_server(addr, port); if (sAGpsInterface) { sAGpsInterface->set_server(type, addr, port); } } Loading @@ -355,17 +349,16 @@ static JNINativeMethod sMethods[] = { {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start}, {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, {"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency}, {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data}, {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event}, {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status}, {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data}, {"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open}, {"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed}, {"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed}, {"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server}, {"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_set_agps_server", "(III)V", (void*)android_location_GpsLocationProvider_set_agps_server}, }; int register_android_location_GpsLocationProvider(JNIEnv* env) Loading
location/java/com/android/internal/location/GpsLocationProvider.java +100 −67 Original line number Diff line number Diff line Loading @@ -109,13 +109,13 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int GPS_STATUS_ENGINE_ON = 3; private static final int GPS_STATUS_ENGINE_OFF = 4; // these need to match GpsSuplStatusValue defines in gps.h /** SUPL status event values. */ private static final int GPS_REQUEST_SUPL_DATA_CONN = 1; private static final int GPS_RELEASE_SUPL_DATA_CONN = 2; private static final int GPS_SUPL_DATA_CONNECTED = 3; private static final int GPS_SUPL_DATA_CONN_DONE = 4; private static final int GPS_SUPL_DATA_CONN_FAILED = 5; // these need to match GpsApgsStatusValue defines in gps.h /** AGPS status event values. */ private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; private static final int GPS_AGPS_DATA_CONNECTED = 3; private static final int GPS_AGPS_DATA_CONN_DONE = 4; private static final int GPS_AGPS_DATA_CONN_FAILED = 5; // these need to match GpsLocationFlags enum in gps.h private static final int LOCATION_INVALID = 0; Loading @@ -125,7 +125,7 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int LOCATION_HAS_BEARING = 8; private static final int LOCATION_HAS_ACCURACY = 16; // IMPORTANT - the GPS_DELETE_* symbols here must match constants in GpsLocationProvider.java // IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h private static final int GPS_DELETE_EPHEMERIS = 0x0001; private static final int GPS_DELETE_ALMANAC = 0x0002; private static final int GPS_DELETE_POSITION = 0x0004; Loading @@ -140,10 +140,14 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private static final int GPS_DELETE_CELLDB_INFO = 0x8000; private static final int GPS_DELETE_ALL = 0xFFFF; // for mSuplDataConnectionState private static final int SUPL_DATA_CONNECTION_CLOSED = 0; private static final int SUPL_DATA_CONNECTION_OPENING = 1; private static final int SUPL_DATA_CONNECTION_OPEN = 2; // these need to match AGpsType enum in gps.h private static final int AGPS_TYPE_SUPL = 1; private static final int AGPS_TYPE_C2K = 2; // for mAGpsDataConnectionState private static final int AGPS_DATA_CONNECTION_CLOSED = 0; private static final int AGPS_DATA_CONNECTION_OPENING = 1; private static final int AGPS_DATA_CONNECTION_OPEN = 2; private static final String PROPERTIES_FILE = "/etc/gps.conf"; Loading Loading @@ -203,9 +207,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private String mSuplHost; private int mSuplPort; private String mC2KHost; private int mC2KPort; private boolean mSetSuplServer; private String mSuplApn; private int mSuplDataConnectionState; private boolean mSetC2KServer; private String mAGpsApn; private int mAGpsDataConnectionState; private final ConnectivityManager mConnMgr; // Wakelocks Loading Loading @@ -293,11 +300,12 @@ public class GpsLocationProvider extends ILocationProvider.Stub { if (Config.LOGD) { Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); } // FIXME - might not have an APN on CDMA if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) { mSuplApn = apnName; if (mSuplDataConnectionState == SUPL_DATA_CONNECTION_OPENING) { native_supl_data_conn_open(mSuplApn); mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; mAGpsApn = apnName; if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { native_agps_data_conn_open(mAGpsApn); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } } } Loading Loading @@ -336,14 +344,26 @@ public class GpsLocationProvider extends ILocationProvider.Stub { mProperties.load(stream); stream.close(); mNtpServer = mProperties.getProperty("NTP_SERVER", null); mSuplHost = mProperties.getProperty("SUPL_HOST"); String suplPortString = mProperties.getProperty("SUPL_PORT"); if (mSuplHost != null && suplPortString != null) { String portString = mProperties.getProperty("SUPL_PORT"); if (mSuplHost != null && portString != null) { try { mSuplPort = Integer.parseInt(suplPortString); mSuplPort = Integer.parseInt(portString); mSetSuplServer = true; } catch (NumberFormatException e) { Log.e(TAG, "unable to parse SUPL_PORT: " + suplPortString); Log.e(TAG, "unable to parse SUPL_PORT: " + portString); } } mC2KHost = mProperties.getProperty("C2K_HOST"); portString = mProperties.getProperty("C2K_PORT"); if (mC2KHost != null && portString != null) { try { mC2KPort = Integer.parseInt(portString); mSetC2KServer = true; } catch (NumberFormatException e) { Log.e(TAG, "unable to parse C2K_PORT: " + portString); } } } catch (IOException e) { Loading @@ -358,7 +378,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub { public boolean requiresNetwork() { // We want updateNetworkState() to get called when the network state changes // for XTRA and NTP time injection support. return (mNtpServer != null || native_supports_xtra() || mSuplHost != null); return (mNtpServer != null || native_supports_xtra() || mSuplHost != null || mC2KHost != null); } public void updateNetworkState(int state) { Loading Loading @@ -561,7 +582,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub { interval = 1; } mFixInterval = interval; native_set_fix_frequency(mFixInterval); } } Loading Loading @@ -871,38 +891,38 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } /** * called from native code to update SUPL status * called from native code to update AGPS status */ private void reportSuplStatus(int status) { private void reportAGpsStatus(int type, int status) { switch (status) { case GPS_REQUEST_SUPL_DATA_CONN: case GPS_REQUEST_AGPS_DATA_CONN: int result = mConnMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); if (result == Phone.APN_ALREADY_ACTIVE) { native_supl_data_conn_open(mSuplApn); mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN; native_agps_data_conn_open(mAGpsApn); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; } else if (result == Phone.APN_REQUEST_STARTED) { mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPENING; mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; } else { native_supl_data_conn_failed(); native_agps_data_conn_failed(); } break; case GPS_RELEASE_SUPL_DATA_CONN: if (mSuplDataConnectionState != SUPL_DATA_CONNECTION_CLOSED) { case GPS_RELEASE_AGPS_DATA_CONN: if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { mConnMgr.stopUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); native_supl_data_conn_closed(); mSuplDataConnectionState = SUPL_DATA_CONNECTION_CLOSED; native_agps_data_conn_closed(); mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; } break; case GPS_SUPL_DATA_CONNECTED: // Log.d(TAG, "GPS_SUPL_DATA_CONNECTED"); case GPS_AGPS_DATA_CONNECTED: // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); break; case GPS_SUPL_DATA_CONN_DONE: // Log.d(TAG, "GPS_SUPL_DATA_CONN_DONE"); case GPS_AGPS_DATA_CONN_DONE: // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); break; case GPS_SUPL_DATA_CONN_FAILED: // Log.d(TAG, "GPS_SUPL_DATA_CONN_FAILED"); case GPS_AGPS_DATA_CONN_FAILED: // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); break; } } Loading @@ -914,6 +934,29 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } private boolean setAGpsServer(int type, String host, int port) { try { InetAddress inetAddress = InetAddress.getByName(host); if (inetAddress != null) { byte[] addrBytes = inetAddress.getAddress(); long addr = 0; for (int i = 0; i < addrBytes.length; i++) { int temp = addrBytes[i]; // signed -> unsigned if (temp < 0) temp = 256 + temp; addr = addr * 256 + temp; } // use MS-Based position mode if SUPL support is enabled mPositionMode = GPS_POSITION_MODE_MS_BASED; native_set_agps_server(type, (int)addr, port); } } catch (UnknownHostException e) { Log.e(TAG, "unknown host for server " + host); return false; } return true; } private class GpsEventThread extends Thread { public GpsEventThread() { Loading Loading @@ -985,7 +1028,8 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } waitTime = getWaitTime(); } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && waitTime > 0) } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && !mSetC2KServer && waitTime > 0) || !mNetworkAvailable)); if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); Loading @@ -1012,26 +1056,15 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } // Set the SUPL server address if we have not yet // Set the AGPS server addresses if we have not yet if (mSetSuplServer) { try { InetAddress inetAddress = InetAddress.getByName(mSuplHost); if (inetAddress != null) { byte[] addrBytes = inetAddress.getAddress(); long addr = 0; for (int i = 0; i < addrBytes.length; i++) { int temp = addrBytes[i]; // signed -> unsigned if (temp < 0) temp = 256 + temp; addr = addr * 256 + temp; } // use MS-Based position mode if SUPL support is enabled mPositionMode = GPS_POSITION_MODE_MS_BASED; native_set_supl_server((int)addr, mSuplPort); if (setAGpsServer(AGPS_TYPE_SUPL, mSuplHost, mSuplPort)) { mSetSuplServer = false; } } catch (UnknownHostException e) { Log.e(TAG, "unknown host for SUPL server " + mSuplHost); } if (mSetC2KServer) { if (setAGpsServer(AGPS_TYPE_C2K, mC2KHost, mC2KPort)) { mSetC2KServer = false; } } Loading Loading @@ -1125,9 +1158,9 @@ public class GpsLocationProvider extends ILocationProvider.Stub { private native boolean native_supports_xtra(); private native void native_inject_xtra_data(byte[] data, int length); // SUPL Support private native void native_supl_data_conn_open(String apn); private native void native_supl_data_conn_closed(); private native void native_supl_data_conn_failed(); private native void native_set_supl_server(int addr, int port); // AGPS Support 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_set_agps_server(int type, int addr, int port); }