diff options
Diffstat (limited to 'core/jni/android_location_GpsLocationProvider.cpp')
-rwxr-xr-x | core/jni/android_location_GpsLocationProvider.cpp | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp index 90a0487..c329602 100755 --- a/core/jni/android_location_GpsLocationProvider.cpp +++ b/core/jni/android_location_GpsLocationProvider.cpp @@ -16,16 +16,18 @@ #define LOG_TAG "GpsLocationProvider" +//#define LOG_NDDEBUG 0 + #include "JNIHelp.h" #include "jni.h" #include "hardware_legacy/gps.h" +#include "hardware_legacy/gps_ni.h" #include "utils/Log.h" #include "utils/misc.h" #include <string.h> #include <pthread.h> - static pthread_mutex_t sEventMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t sEventCond = PTHREAD_COND_INITIALIZER; static jmethodID method_reportLocation; @@ -34,16 +36,19 @@ static jmethodID method_reportSvStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_reportNmea; static jmethodID method_xtraDownloadRequest; +static jmethodID method_reportNiNotification; static const GpsInterface* sGpsInterface = NULL; static const GpsXtraInterface* sGpsXtraInterface = NULL; static const AGpsInterface* sAGpsInterface = NULL; +static const GpsNiInterface* sGpsNiInterface = NULL; // data written to by GPS callbacks static GpsLocation sGpsLocation; static GpsStatus sGpsStatus; static GpsSvStatus sGpsSvStatus; static AGpsStatus sAGpsStatus; +static GpsNiNotification sGpsNiNotification; // buffer for NMEA data #define NMEA_SENTENCE_LENGTH 100 @@ -62,6 +67,7 @@ static GpsStatus sGpsStatusCopy; static GpsSvStatus sGpsSvStatusCopy; static AGpsStatus sAGpsStatusCopy; static NmeaSentence sNmeaBufferCopy[NMEA_SENTENCE_LENGTH]; +static GpsNiNotification sGpsNiNotificationCopy; enum CallbackType { kLocation = 1, @@ -71,6 +77,7 @@ enum CallbackType { kXtraDownloadRequest = 16, kDisableRequest = 32, kNmeaAvailable = 64, + kNiNotification = 128, }; static int sPendingCallbacks; @@ -160,6 +167,20 @@ download_request_callback() pthread_mutex_unlock(&sEventMutex); } +static void +gps_ni_notify_callback(GpsNiNotification *notification) +{ + LOGD("gps_ni_notify_callback: notif=%d", notification->notification_id); + + pthread_mutex_lock(&sEventMutex); + + sPendingCallbacks |= kNiNotification; + memcpy(&sGpsNiNotification, notification, sizeof(GpsNiNotification)); + + pthread_cond_signal(&sEventCond); + pthread_mutex_unlock(&sEventMutex); +} + GpsXtraCallbacks sGpsXtraCallbacks = { download_request_callback, }; @@ -168,6 +189,10 @@ AGpsCallbacks sAGpsCallbacks = { agps_status_callback, }; +GpsNiCallbacks sGpsNiCallbacks = { + gps_ni_notify_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"); @@ -175,6 +200,7 @@ static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(IJ)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 jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) { @@ -194,6 +220,12 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o 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); + return true; } @@ -210,7 +242,7 @@ static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject ob sGpsInterface->cleanup(); } -static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode, +static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj, jint positionMode, jboolean singleFix, jint fixFrequency) { int result = sGpsInterface->set_position_mode(positionMode, (singleFix ? 0 : fixFrequency)); @@ -235,7 +267,7 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job { pthread_mutex_lock(&sEventMutex); pthread_cond_wait(&sEventCond, &sEventMutex); - + // copy and clear the callback flags int pendingCallbacks = sPendingCallbacks; sPendingCallbacks = 0; @@ -254,18 +286,20 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy)); if (pendingCallbacks & kNmeaAvailable) memcpy(&sNmeaBufferCopy, &sNmeaBuffer, nmeaSentenceCount * sizeof(sNmeaBuffer[0])); + if (pendingCallbacks & kNiNotification) + memcpy(&sGpsNiNotificationCopy, &sGpsNiNotification, sizeof(sGpsNiNotificationCopy)); pthread_mutex_unlock(&sEventMutex); - if (pendingCallbacks & kLocation) { + if (pendingCallbacks & kLocation) { env->CallVoidMethod(obj, method_reportLocation, sGpsLocationCopy.flags, (jdouble)sGpsLocationCopy.latitude, (jdouble)sGpsLocationCopy.longitude, - (jdouble)sGpsLocationCopy.altitude, - (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing, + (jdouble)sGpsLocationCopy.altitude, + (jfloat)sGpsLocationCopy.speed, (jfloat)sGpsLocationCopy.bearing, (jfloat)sGpsLocationCopy.accuracy, (jlong)sGpsLocationCopy.timestamp); } if (pendingCallbacks & kStatus) { env->CallVoidMethod(obj, method_reportStatus, sGpsStatusCopy.status); - } + } if (pendingCallbacks & kSvStatus) { env->CallVoidMethod(obj, method_reportSvStatus); } @@ -277,16 +311,34 @@ static void android_location_GpsLocationProvider_wait_for_event(JNIEnv* env, job env->CallVoidMethod(obj, method_reportNmea, i, sNmeaBuffer[i].timestamp); } } - if (pendingCallbacks & kXtraDownloadRequest) { + if (pendingCallbacks & kXtraDownloadRequest) { env->CallVoidMethod(obj, method_xtraDownloadRequest); } if (pendingCallbacks & kDisableRequest) { // don't need to do anything - we are just poking so wait_for_event will return. } + if (pendingCallbacks & kNiNotification) { + LOGD("android_location_GpsLocationProvider_wait_for_event: sent notification callback."); + jstring reqId = env->NewStringUTF(sGpsNiNotificationCopy.requestor_id); + jstring text = env->NewStringUTF(sGpsNiNotificationCopy.text); + jstring extras = env->NewStringUTF(sGpsNiNotificationCopy.extras); + env->CallVoidMethod(obj, method_reportNiNotification, + sGpsNiNotificationCopy.notification_id, + sGpsNiNotificationCopy.ni_type, + sGpsNiNotificationCopy.notify_flags, + sGpsNiNotificationCopy.timeout, + sGpsNiNotificationCopy.default_response, + reqId, + text, + sGpsNiNotificationCopy.requestor_id_encoding, + sGpsNiNotificationCopy.text_encoding, + extras + ); + } } -static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, - jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, +static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj, + jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, jintArray maskArray) { // this should only be called from within a call to reportStatus, so we don't need to lock here @@ -358,7 +410,7 @@ static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, return (sGpsXtraInterface != NULL); } -static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, +static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj, jbyteArray data, jint length) { jbyte* bytes = env->GetByteArrayElements(data, 0); @@ -415,6 +467,16 @@ static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jo } } +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); + } +} + static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, @@ -436,6 +498,7 @@ static JNINativeMethod sMethods[] = { {"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", "(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}, }; int register_android_location_GpsLocationProvider(JNIEnv* env) |