Expose Gps Navigation Messages in the platform.
b/16405976
Change-Id: Ic982ea2467d116585780c20c2fa7e974e50f8345
diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
index 8bb6e8a..46327d7 100644
--- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -53,6 +53,7 @@
static jmethodID method_reportGeofencePauseStatus;
static jmethodID method_reportGeofenceResumeStatus;
static jmethodID method_reportMeasurementData;
+static jmethodID method_reportNavigationMessages;
static const GpsInterface* sGpsInterface = NULL;
static const GpsXtraInterface* sGpsXtraInterface = NULL;
@@ -62,6 +63,7 @@
static const AGpsRilInterface* sAGpsRilInterface = NULL;
static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL;
+static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
// temporary storage for GPS callbacks
static GpsSvStatus sGpsSvStatus;
@@ -447,6 +449,10 @@
clazz,
"reportMeasurementData",
"(Landroid/location/GpsMeasurementsEvent;)V");
+ method_reportNavigationMessages = env->GetMethodID(
+ clazz,
+ "reportNavigationMessage",
+ "(Landroid/location/GpsNavigationMessageEvent;)V");
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
if (err == 0) {
@@ -472,6 +478,9 @@
(const GpsGeofencingInterface*)sGpsInterface->get_extension(GPS_GEOFENCING_INTERFACE);
sGpsMeasurementInterface =
(const GpsMeasurementInterface*)sGpsInterface->get_extension(GPS_MEASUREMENT_INTERFACE);
+ sGpsNavigationMessageInterface =
+ (const GpsNavigationMessageInterface*)sGpsInterface->get_extension(
+ GPS_NAVIGATION_MESSAGE_INTERFACE);
}
}
@@ -1212,7 +1221,6 @@
checkAndClearExceptionFromCallback(env, __FUNCTION__);
} else {
ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%d", data->size);
- return;
}
}
@@ -1223,7 +1231,7 @@
static jboolean android_location_GpsLocationProvider_is_measurement_supported(
JNIEnv* env,
- jobject obj) {
+ jclass clazz) {
if (sGpsMeasurementInterface != NULL) {
return JNI_TRUE;
}
@@ -1259,6 +1267,110 @@
return JNI_TRUE;
}
+static jobject translate_gps_navigation_message(JNIEnv* env, GpsNavigationMessage* message) {
+ size_t dataLength = message->data_length;
+ uint8_t* data = message->data;
+ if (dataLength == 0 || data == NULL) {
+ ALOGE("Invalid Navigation Message found: data=%p, length=%d", data, dataLength);
+ return NULL;
+ }
+
+ jclass navigationMessageClass = env->FindClass("android/location/GpsNavigationMessage");
+ jmethodID navigationMessageCtor = env->GetMethodID(navigationMessageClass, "<init>", "()V");
+ jobject navigationMessageObject = env->NewObject(navigationMessageClass, navigationMessageCtor);
+
+ jmethodID setTypeMethod = env->GetMethodID(navigationMessageClass, "setType", "(B)V");
+ env->CallVoidMethod(navigationMessageObject, setTypeMethod, message->type);
+
+ jmethodID setPrnMethod = env->GetMethodID(navigationMessageClass, "setPrn", "(B)V");
+ env->CallVoidMethod(navigationMessageObject, setPrnMethod, message->prn);
+
+ jmethodID setMessageIdMethod = env->GetMethodID(navigationMessageClass, "setMessageId", "(S)V");
+ env->CallVoidMethod(navigationMessageObject, setMessageIdMethod, message->message_id);
+
+ jmethodID setSubmessageIdMethod =
+ env->GetMethodID(navigationMessageClass, "setSubmessageId", "(S)V");
+ env->CallVoidMethod(navigationMessageObject, setSubmessageIdMethod, message->submessage_id);
+
+ jbyteArray dataArray = env->NewByteArray(dataLength);
+ env->SetByteArrayRegion(dataArray, 0, dataLength, (jbyte*) data);
+ jmethodID setDataMethod = env->GetMethodID(navigationMessageClass, "setData", "([B)V");
+ env->CallVoidMethod(navigationMessageObject, setDataMethod, dataArray);
+
+ return navigationMessageObject;
+}
+
+static void navigation_message_callback(GpsNavigationMessage* message) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (message == NULL) {
+ ALOGE("Invalid Navigation Message provided to callback");
+ return;
+ }
+
+ if (message->size == sizeof(GpsNavigationMessage)) {
+ jobject navigationMessage = translate_gps_navigation_message(env, message);
+
+ jclass navigationMessageEventClass =
+ env->FindClass("android/location/GpsNavigationMessageEvent");
+ jmethodID navigationMessageEventCtor = env->GetMethodID(
+ navigationMessageEventClass,
+ "<init>",
+ "(Landroid/location/GpsNavigationMessage;)V");
+ jobject navigationMessageEvent = env->NewObject(
+ navigationMessageEventClass,
+ navigationMessageEventCtor,
+ navigationMessage);
+
+ env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessageEvent);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ } else {
+ ALOGE("Invalid GpsNavigationMessage size found: %d", message->size);
+ }
+}
+
+GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = {
+ sizeof(GpsNavigationMessageCallbacks),
+ navigation_message_callback,
+};
+
+static jboolean android_location_GpsLocationProvider_is_navigation_message_supported(
+ JNIEnv* env,
+ jclass clazz) {
+ if(sGpsNavigationMessageInterface != NULL) {
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+static jboolean android_location_GpsLocationProvider_start_navigation_message_collection(
+ JNIEnv* env,
+ jobject obj) {
+ if (sGpsNavigationMessageInterface == NULL) {
+ ALOGE("Navigation Message interface is not available.");
+ return JNI_FALSE;
+ }
+
+ int result = sGpsNavigationMessageInterface->init(&sGpsNavigationMessageCallbacks);
+ if (result != GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS) {
+ ALOGE("An error has been found in %s: %d", __FUNCTION__, result);
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
+
+static jboolean android_location_GpsLocationProvider_stop_navigation_message_collection(
+ JNIEnv* env,
+ jobject obj) {
+ if (sGpsNavigationMessageInterface == NULL) {
+ ALOGE("Navigation Message interface is not available.");
+ return JNI_FALSE;
+ }
+
+ sGpsNavigationMessageInterface->close();
+ return JNI_TRUE;
+}
+
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
@@ -1336,7 +1448,16 @@
(void*) android_location_GpsLocationProvider_start_measurement_collection},
{"native_stop_measurement_collection",
"()Z",
- (void*) android_location_GpsLocationProvider_stop_measurement_collection}
+ (void*) android_location_GpsLocationProvider_stop_measurement_collection},
+ {"native_is_navigation_message_supported",
+ "()Z",
+ (void*) android_location_GpsLocationProvider_is_navigation_message_supported},
+ {"native_start_navigation_message_collection",
+ "()Z",
+ (void*) android_location_GpsLocationProvider_start_navigation_message_collection},
+ {"native_stop_navigation_message_collection",
+ "()Z",
+ (void*) android_location_GpsLocationProvider_stop_navigation_message_collection},
};
int register_android_server_location_GpsLocationProvider(JNIEnv* env)