blob: f736cd554a16673b1fe810b3b035faa6fa37b0eb [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lifu Tang30f95a72016-01-07 23:20:38 -080017#define LOG_TAG "GnssLocationProvider"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwoodb8d90332010-10-18 17:59:48 -040019#define LOG_NDEBUG 0
Danke Xie22d1f9f2009-08-18 18:28:45 -040020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include "JNIHelp.h"
22#include "jni.h"
Mike Lockwoodb7ff4572010-04-05 15:24:34 -040023#include "hardware/hardware.h"
24#include "hardware/gps.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040025#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026#include "utils/Log.h"
27#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070028#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070029#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
destradaa931a37f2014-08-12 16:36:59 -070031#include <arpa/inet.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032#include <string.h>
33#include <pthread.h>
destradaa96a14702014-06-05 11:36:30 -070034#include <linux/in.h>
35#include <linux/in6.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
Mike Lockwoodf602d362010-06-20 14:28:16 -070037static jobject mCallbacksObj = NULL;
38
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039static jmethodID method_reportLocation;
40static jmethodID method_reportStatus;
41static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040042static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040043static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040044static jmethodID method_setEngineCapabilities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040046static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020047static jmethodID method_requestRefLocation;
48static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040049static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070050static jmethodID method_reportGeofenceTransition;
51static jmethodID method_reportGeofenceStatus;
52static jmethodID method_reportGeofenceAddStatus;
53static jmethodID method_reportGeofenceRemoveStatus;
54static jmethodID method_reportGeofencePauseStatus;
55static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070056static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070057static jmethodID method_reportNavigationMessages;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
59static const GpsInterface* sGpsInterface = NULL;
60static const GpsXtraInterface* sGpsXtraInterface = NULL;
Mike Lockwoode3635c92009-05-11 08:38:02 -040061static const AGpsInterface* sAGpsInterface = NULL;
Danke Xie22d1f9f2009-08-18 18:28:45 -040062static const GpsNiInterface* sGpsNiInterface = NULL;
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -060063static const GpsDebugInterface* sGpsDebugInterface = NULL;
Miguel Torroja1e84da82010-07-27 07:02:24 +020064static const AGpsRilInterface* sAGpsRilInterface = NULL;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070065static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
destradaaea8a8a62014-06-23 18:19:03 -070066static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL;
destradaa4b3e3932014-07-21 18:01:47 -070067static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
Tsuwei Chen52617bb2014-08-25 11:49:11 -070068static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Lifu Tang30f95a72016-01-07 23:20:38 -080070#define MAX_SATELLITE_COUNT 512
71
72#define PRN_SHIFT_WIDTH 3
73
Mike Lockwoodf602d362010-06-20 14:28:16 -070074// temporary storage for GPS callbacks
Lifu Tang30f95a72016-01-07 23:20:38 -080075static GnssSvInfo sGnssSvList[MAX_SATELLITE_COUNT];
76static size_t sGnssSvListSize;
Mike Lockwoodf602d362010-06-20 14:28:16 -070077static const char* sNmeaString;
78static int sNmeaStringLength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Mike Lockwood8f5a8002010-04-07 09:05:26 -040080#define WAKE_LOCK_NAME "GPS"
81
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082namespace android {
83
Mike Lockwoodf602d362010-06-20 14:28:16 -070084static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
85 if (env->ExceptionCheck()) {
Steve Block3762c312012-01-06 19:20:56 +000086 ALOGE("An exception was thrown by callback '%s'.", methodName);
Mike Lockwoodf602d362010-06-20 14:28:16 -070087 LOGE_EX(env);
88 env->ExceptionClear();
89 }
90}
91
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092static void location_callback(GpsLocation* location)
93{
Mike Lockwoodf602d362010-06-20 14:28:16 -070094 JNIEnv* env = AndroidRuntime::getJNIEnv();
95 env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
96 (jdouble)location->latitude, (jdouble)location->longitude,
97 (jdouble)location->altitude,
98 (jfloat)location->speed, (jfloat)location->bearing,
99 (jfloat)location->accuracy, (jlong)location->timestamp);
100 checkAndClearExceptionFromCallback(env, __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101}
102
103static void status_callback(GpsStatus* status)
104{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700105 JNIEnv* env = AndroidRuntime::getJNIEnv();
Mike Lockwoodf602d362010-06-20 14:28:16 -0700106 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status->status);
107 checkAndClearExceptionFromCallback(env, __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108}
109
110static void sv_status_callback(GpsSvStatus* sv_status)
111{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700112 JNIEnv* env = AndroidRuntime::getJNIEnv();
Lifu Tang30f95a72016-01-07 23:20:38 -0800113 size_t status_size = sv_status->size;
114 // Some drive doesn't set the size field correctly. Assume GpsSvStatus_v1 if
115 // it doesn't provide a valid size.
116 if (status_size == 0) {
117 status_size = sizeof(GpsSvStatus_v1);
118 }
119 if (sv_status->size == sizeof(GpsSvStatus_v2)) {
120 sGnssSvListSize = sv_status->gnss_sv_list_size;
121 // Cramp the list size
122 if (sGnssSvListSize > MAX_SATELLITE_COUNT) {
123 sGnssSvListSize = MAX_SATELLITE_COUNT;
124 }
125 // Copy GNSS SV info into sGnssSvList, if any.
126 if (sGnssSvListSize > 0 && sv_status->gnss_sv_list) {
127 memcpy(sGnssSvList, sv_status->gnss_sv_list, sizeof(GnssSvInfo) * sGnssSvListSize);
128 }
129 } else if (status_size == sizeof(GpsSvStatus_v1)) {
130 sGnssSvListSize = sv_status->num_svs;
131 uint32_t ephemeris_mask = sv_status->ephemeris_mask;
132 uint32_t almanac_mask = sv_status->almanac_mask;
133 uint32_t used_in_fix_mask = sv_status->used_in_fix_mask;
134 for (size_t i = 0; i < sGnssSvListSize; i++) {
135 GnssSvInfo& info = sGnssSvList[i];
136 info.constellation = GNSS_CONSTELLATION_GPS;
137 info.prn = sv_status->sv_list[i].prn;
138 info.snr = sv_status->sv_list[i].snr;
139 info.elevation = sv_status->sv_list[i].elevation;
140 info.azimuth = sv_status->sv_list[i].azimuth;
141 info.flags = GNSS_SV_FLAGS_NONE;
142 if ((ephemeris_mask & (1 << (info.prn - 1))) != 0) {
143 info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA;
144 }
145 if ((almanac_mask & (1 << (info.prn - 1))) != 0) {
146 info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA;
147 }
148 if ((used_in_fix_mask & (1 << (info.prn - 1))) != 0) {
149 info.flags |= GNSS_SV_FLAGS_USED_IN_FIX;
150 }
151 }
152 } else {
153 sGnssSvListSize = 0;
154 ALOGE("Invalid size of GpsSvStatus found: %zd.", status_size);
155 return;
156 }
Mike Lockwoodf602d362010-06-20 14:28:16 -0700157 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
158 checkAndClearExceptionFromCallback(env, __FUNCTION__);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159}
160
Mike Lockwoodb16e7802009-08-06 09:26:02 -0400161static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)
162{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700163 JNIEnv* env = AndroidRuntime::getJNIEnv();
164 // The Java code will call back to read these values
165 // We do this to avoid creating unnecessary String objects
166 sNmeaString = nmea;
167 sNmeaStringLength = length;
168 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
169 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwoodb16e7802009-08-06 09:26:02 -0400170}
171
Mike Lockwood04598b62010-04-14 17:17:24 -0400172static void set_capabilities_callback(uint32_t capabilities)
173{
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700174 ALOGD("set_capabilities_callback: %du\n", capabilities);
Mike Lockwoodf602d362010-06-20 14:28:16 -0700175 JNIEnv* env = AndroidRuntime::getJNIEnv();
176 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
177 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Mike Lockwood04598b62010-04-14 17:17:24 -0400178}
179
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400180static void acquire_wakelock_callback()
181{
182 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
183}
184
185static void release_wakelock_callback()
186{
187 release_wake_lock(WAKE_LOCK_NAME);
188}
189
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400190static void request_utc_time_callback()
191{
192 JNIEnv* env = AndroidRuntime::getJNIEnv();
193 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
194 checkAndClearExceptionFromCallback(env, __FUNCTION__);
195}
196
Mike Lockwoodf602d362010-06-20 14:28:16 -0700197static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg)
Mike Lockwood58bda982009-04-14 16:25:07 -0400198{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700199 return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg);
Mike Lockwood58bda982009-04-14 16:25:07 -0400200}
201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202GpsCallbacks sGpsCallbacks = {
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400203 sizeof(GpsCallbacks),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 location_callback,
205 status_callback,
206 sv_status_callback,
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400207 nmea_callback,
Mike Lockwood04598b62010-04-14 17:17:24 -0400208 set_capabilities_callback,
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400209 acquire_wakelock_callback,
210 release_wakelock_callback,
Mike Lockwoodf602d362010-06-20 14:28:16 -0700211 create_thread_callback,
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400212 request_utc_time_callback,
Lifu Tang30f95a72016-01-07 23:20:38 -0800213 NULL,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214};
215
Mike Lockwoodf602d362010-06-20 14:28:16 -0700216static void xtra_download_request_callback()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700218 JNIEnv* env = AndroidRuntime::getJNIEnv();
219 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
220 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Danke Xie22d1f9f2009-08-18 18:28:45 -0400221}
222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223GpsXtraCallbacks sGpsXtraCallbacks = {
Mike Lockwoodf602d362010-06-20 14:28:16 -0700224 xtra_download_request_callback,
225 create_thread_callback,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226};
227
destradaa96a14702014-06-05 11:36:30 -0700228static jbyteArray convert_to_ipv4(uint32_t ip, bool net_order)
229{
230 if (INADDR_NONE == ip) {
231 return NULL;
232 }
233
234 JNIEnv* env = AndroidRuntime::getJNIEnv();
235 jbyteArray byteArray = env->NewByteArray(4);
236 if (byteArray == NULL) {
237 ALOGE("Unable to allocate byte array for IPv4 address");
238 return NULL;
239 }
240
241 jbyte ipv4[4];
242 if (net_order) {
destradaa931a37f2014-08-12 16:36:59 -0700243 ALOGV("Converting IPv4 address(net_order) %x", ip);
destradaa96a14702014-06-05 11:36:30 -0700244 memcpy(ipv4, &ip, sizeof(ipv4));
245 } else {
destradaa931a37f2014-08-12 16:36:59 -0700246 ALOGV("Converting IPv4 address(host_order) %x", ip);
destradaa96a14702014-06-05 11:36:30 -0700247 //endianess transparent conversion from int to char[]
248 ipv4[0] = (jbyte) (ip & 0xFF);
249 ipv4[1] = (jbyte)((ip>>8) & 0xFF);
250 ipv4[2] = (jbyte)((ip>>16) & 0xFF);
251 ipv4[3] = (jbyte) (ip>>24);
252 }
253
254 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*) ipv4);
255 return byteArray;
256}
257
Mike Lockwoodf602d362010-06-20 14:28:16 -0700258static void agps_status_callback(AGpsStatus* agps_status)
259{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700260 JNIEnv* env = AndroidRuntime::getJNIEnv();
destradaa96a14702014-06-05 11:36:30 -0700261 jbyteArray byteArray = NULL;
262 bool isSupported = false;
Stephen Li8efd74d2011-03-01 20:56:00 -0800263
destradaa96a14702014-06-05 11:36:30 -0700264 size_t status_size = agps_status->size;
265 if (status_size == sizeof(AGpsStatus_v3)) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100266 ALOGV("AGpsStatus is V3: %zd", status_size);
destradaa96a14702014-06-05 11:36:30 -0700267 switch (agps_status->addr.ss_family)
268 {
269 case AF_INET:
270 {
271 struct sockaddr_in *in = (struct sockaddr_in*)&(agps_status->addr);
destradaace48c1c2015-05-29 13:47:39 -0700272 uint32_t ipAddr = *(uint32_t*)&(in->sin_addr);
273 byteArray = convert_to_ipv4(ipAddr, true /* net_order */);
274 if (ipAddr == INADDR_NONE || byteArray != NULL) {
destradaa96a14702014-06-05 11:36:30 -0700275 isSupported = true;
276 }
destradaa931a37f2014-08-12 16:36:59 -0700277 IF_ALOGD() {
278 // log the IP for reference in case there is a bogus value pushed by HAL
279 char str[INET_ADDRSTRLEN];
280 inet_ntop(AF_INET, &(in->sin_addr), str, INET_ADDRSTRLEN);
281 ALOGD("AGPS IP is v4: %s", str);
282 }
destradaa96a14702014-06-05 11:36:30 -0700283 }
284 break;
285 case AF_INET6:
286 {
287 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(agps_status->addr);
288 byteArray = env->NewByteArray(16);
289 if (byteArray != NULL) {
290 env->SetByteArrayRegion(byteArray, 0, 16, (const jbyte *)&(in6->sin6_addr));
291 isSupported = true;
292 } else {
293 ALOGE("Unable to allocate byte array for IPv6 address.");
294 }
destradaa931a37f2014-08-12 16:36:59 -0700295 IF_ALOGD() {
296 // log the IP for reference in case there is a bogus value pushed by HAL
297 char str[INET6_ADDRSTRLEN];
298 inet_ntop(AF_INET6, &(in6->sin6_addr), str, INET6_ADDRSTRLEN);
299 ALOGD("AGPS IP is v6: %s", str);
300 }
destradaa96a14702014-06-05 11:36:30 -0700301 }
302 break;
303 default:
304 ALOGE("Invalid ss_family found: %d", agps_status->addr.ss_family);
305 break;
306 }
307 } else if (status_size >= sizeof(AGpsStatus_v2)) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100308 ALOGV("AGpsStatus is V2+: %zd", status_size);
destradaa96a14702014-06-05 11:36:30 -0700309 // for back-compatibility reasons we check in v2 that the data structure size is greater or
310 // equal to the declared size in gps.h
311 uint32_t ipaddr = agps_status->ipaddr;
destradaa931a37f2014-08-12 16:36:59 -0700312 ALOGV("AGPS IP is v4: %x", ipaddr);
destradaa96a14702014-06-05 11:36:30 -0700313 byteArray = convert_to_ipv4(ipaddr, false /* net_order */);
314 if (ipaddr == INADDR_NONE || byteArray != NULL) {
315 isSupported = true;
316 }
317 } else if (status_size >= sizeof(AGpsStatus_v1)) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100318 ALOGV("AGpsStatus is V1+: %zd", status_size);
destradaa96a14702014-06-05 11:36:30 -0700319 // because we have to check for >= with regards to v2, we also need to relax the check here
320 // and only make sure that the size is at least what we expect
321 isSupported = true;
322 } else {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100323 ALOGE("Invalid size of AGpsStatus found: %zd.", status_size);
destradaa96a14702014-06-05 11:36:30 -0700324 }
325
326 if (isSupported) {
destradaa931a37f2014-08-12 16:36:59 -0700327 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
328 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
destradaa96a14702014-06-05 11:36:30 -0700329 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status->type,
330 agps_status->status, byteArray);
331
332 checkAndClearExceptionFromCallback(env, __FUNCTION__);
333 } else {
334 ALOGD("Skipping calling method_reportAGpsStatus.");
335 }
336
337 if (byteArray) {
338 env->DeleteLocalRef(byteArray);
339 }
Mike Lockwoodf602d362010-06-20 14:28:16 -0700340}
341
Mike Lockwoode3635c92009-05-11 08:38:02 -0400342AGpsCallbacks sAGpsCallbacks = {
343 agps_status_callback,
Mike Lockwoodf602d362010-06-20 14:28:16 -0700344 create_thread_callback,
Mike Lockwood58bda982009-04-14 16:25:07 -0400345};
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346
Mike Lockwoodf602d362010-06-20 14:28:16 -0700347static void gps_ni_notify_callback(GpsNiNotification *notification)
348{
Steve Block5baa3a62011-12-20 16:23:08 +0000349 ALOGD("gps_ni_notify_callback\n");
Mike Lockwoodf602d362010-06-20 14:28:16 -0700350 JNIEnv* env = AndroidRuntime::getJNIEnv();
351 jstring requestor_id = env->NewStringUTF(notification->requestor_id);
352 jstring text = env->NewStringUTF(notification->text);
353 jstring extras = env->NewStringUTF(notification->extras);
354
355 if (requestor_id && text && extras) {
356 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
357 notification->notification_id, notification->ni_type,
358 notification->notify_flags, notification->timeout,
359 notification->default_response, requestor_id, text,
360 notification->requestor_id_encoding,
361 notification->text_encoding, extras);
362 } else {
Steve Block3762c312012-01-06 19:20:56 +0000363 ALOGE("out of memory in gps_ni_notify_callback\n");
Mike Lockwoodf602d362010-06-20 14:28:16 -0700364 }
365
366 if (requestor_id)
367 env->DeleteLocalRef(requestor_id);
368 if (text)
369 env->DeleteLocalRef(text);
370 if (extras)
371 env->DeleteLocalRef(extras);
372 checkAndClearExceptionFromCallback(env, __FUNCTION__);
373}
374
Danke Xie22d1f9f2009-08-18 18:28:45 -0400375GpsNiCallbacks sGpsNiCallbacks = {
376 gps_ni_notify_callback,
Mike Lockwoodf602d362010-06-20 14:28:16 -0700377 create_thread_callback,
Danke Xie22d1f9f2009-08-18 18:28:45 -0400378};
379
Miguel Torroja1e84da82010-07-27 07:02:24 +0200380static void agps_request_set_id(uint32_t flags)
381{
Miguel Torroja1e84da82010-07-27 07:02:24 +0200382 JNIEnv* env = AndroidRuntime::getJNIEnv();
383 env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags);
384 checkAndClearExceptionFromCallback(env, __FUNCTION__);
385}
386
387static void agps_request_ref_location(uint32_t flags)
388{
Miguel Torroja1e84da82010-07-27 07:02:24 +0200389 JNIEnv* env = AndroidRuntime::getJNIEnv();
390 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags);
391 checkAndClearExceptionFromCallback(env, __FUNCTION__);
392}
393
394AGpsRilCallbacks sAGpsRilCallbacks = {
395 agps_request_set_id,
396 agps_request_ref_location,
397 create_thread_callback,
398};
399
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700400static void gps_geofence_transition_callback(int32_t geofence_id, GpsLocation* location,
401 int32_t transition, GpsUtcTime timestamp)
402{
403 JNIEnv* env = AndroidRuntime::getJNIEnv();
404
405 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofence_id,
406 location->flags, (jdouble)location->latitude, (jdouble)location->longitude,
407 (jdouble)location->altitude,
408 (jfloat)location->speed, (jfloat)location->bearing,
409 (jfloat)location->accuracy, (jlong)location->timestamp,
410 transition, timestamp);
411 checkAndClearExceptionFromCallback(env, __FUNCTION__);
412};
413
414static void gps_geofence_status_callback(int32_t status, GpsLocation* location)
415{
416 JNIEnv* env = AndroidRuntime::getJNIEnv();
417 jint flags = 0;
418 jdouble latitude = 0;
419 jdouble longitude = 0;
420 jdouble altitude = 0;
421 jfloat speed = 0;
422 jfloat bearing = 0;
423 jfloat accuracy = 0;
424 jlong timestamp = 0;
425 if (location != NULL) {
426 flags = location->flags;
427 latitude = location->latitude;
428 longitude = location->longitude;
429 altitude = location->altitude;
430 speed = location->speed;
431 bearing = location->bearing;
432 accuracy = location->accuracy;
433 timestamp = location->timestamp;
434 }
435
436 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
437 flags, latitude, longitude, altitude, speed, bearing, accuracy, timestamp);
438 checkAndClearExceptionFromCallback(env, __FUNCTION__);
439};
440
441static void gps_geofence_add_callback(int32_t geofence_id, int32_t status)
442{
443 JNIEnv* env = AndroidRuntime::getJNIEnv();
444 if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
445 ALOGE("Error in geofence_add_callback: %d\n", status);
446 }
447 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceAddStatus, geofence_id, status);
448 checkAndClearExceptionFromCallback(env, __FUNCTION__);
449};
450
451static void gps_geofence_remove_callback(int32_t geofence_id, int32_t status)
452{
453 JNIEnv* env = AndroidRuntime::getJNIEnv();
454 if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
455 ALOGE("Error in geofence_remove_callback: %d\n", status);
456 }
457 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceRemoveStatus, geofence_id, status);
458 checkAndClearExceptionFromCallback(env, __FUNCTION__);
459};
460
461static void gps_geofence_resume_callback(int32_t geofence_id, int32_t status)
462{
463 JNIEnv* env = AndroidRuntime::getJNIEnv();
464 if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
465 ALOGE("Error in geofence_resume_callback: %d\n", status);
466 }
467 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceResumeStatus, geofence_id, status);
468 checkAndClearExceptionFromCallback(env, __FUNCTION__);
469};
470
471static void gps_geofence_pause_callback(int32_t geofence_id, int32_t status)
472{
473 JNIEnv* env = AndroidRuntime::getJNIEnv();
474 if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
475 ALOGE("Error in geofence_pause_callback: %d\n", status);
476 }
477 env->CallVoidMethod(mCallbacksObj, method_reportGeofencePauseStatus, geofence_id, status);
478 checkAndClearExceptionFromCallback(env, __FUNCTION__);
479};
480
481GpsGeofenceCallbacks sGpsGeofenceCallbacks = {
482 gps_geofence_transition_callback,
483 gps_geofence_status_callback,
484 gps_geofence_add_callback,
485 gps_geofence_remove_callback,
486 gps_geofence_pause_callback,
487 gps_geofence_resume_callback,
488 create_thread_callback,
489};
490
Lifu Tang30f95a72016-01-07 23:20:38 -0800491static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Mike Lockwoodb7ff4572010-04-05 15:24:34 -0400492 int err;
493 hw_module_t* module;
Mike Lockwoodb7ff4572010-04-05 15:24:34 -0400494
Mike Lockwoodbea31182010-10-05 14:29:53 -0400495 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
496 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
497 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
destradaa96a14702014-06-05 11:36:30 -0700498 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400499 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
500 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
501 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800502 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
503 "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400504 method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
505 method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400506 method_requestUtcTime = env->GetMethodID(clazz,"requestUtcTime","()V");
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700507 method_reportGeofenceTransition = env->GetMethodID(clazz,"reportGeofenceTransition",
508 "(IIDDDFFFJIJ)V");
509 method_reportGeofenceStatus = env->GetMethodID(clazz,"reportGeofenceStatus",
510 "(IIDDDFFFJ)V");
511 method_reportGeofenceAddStatus = env->GetMethodID(clazz,"reportGeofenceAddStatus",
512 "(II)V");
513 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz,"reportGeofenceRemoveStatus",
514 "(II)V");
515 method_reportGeofenceResumeStatus = env->GetMethodID(clazz,"reportGeofenceResumeStatus",
516 "(II)V");
517 method_reportGeofencePauseStatus = env->GetMethodID(clazz,"reportGeofencePauseStatus",
518 "(II)V");
destradaaea8a8a62014-06-23 18:19:03 -0700519 method_reportMeasurementData = env->GetMethodID(
520 clazz,
521 "reportMeasurementData",
522 "(Landroid/location/GpsMeasurementsEvent;)V");
destradaa4b3e3932014-07-21 18:01:47 -0700523 method_reportNavigationMessages = env->GetMethodID(
524 clazz,
525 "reportNavigationMessage",
526 "(Landroid/location/GpsNavigationMessageEvent;)V");
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800527
528 err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
529 if (err == 0) {
530 hw_device_t* device;
531 err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
532 if (err == 0) {
533 gps_device_t* gps_device = (gps_device_t *)device;
534 sGpsInterface = gps_device->get_gps_interface(gps_device);
535 }
536 }
537 if (sGpsInterface) {
538 sGpsXtraInterface =
539 (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);
540 sAGpsInterface =
541 (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
542 sGpsNiInterface =
543 (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
544 sGpsDebugInterface =
545 (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
546 sAGpsRilInterface =
547 (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700548 sGpsGeofencingInterface =
549 (const GpsGeofencingInterface*)sGpsInterface->get_extension(GPS_GEOFENCING_INTERFACE);
destradaaea8a8a62014-06-23 18:19:03 -0700550 sGpsMeasurementInterface =
551 (const GpsMeasurementInterface*)sGpsInterface->get_extension(GPS_MEASUREMENT_INTERFACE);
destradaa4b3e3932014-07-21 18:01:47 -0700552 sGpsNavigationMessageInterface =
553 (const GpsNavigationMessageInterface*)sGpsInterface->get_extension(
554 GPS_NAVIGATION_MESSAGE_INTERFACE);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700555 sGnssConfigurationInterface =
556 (const GnssConfigurationInterface*)sGpsInterface->get_extension(
557 GNSS_CONFIGURATION_INTERFACE);
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800558 }
Mike Lockwoodbea31182010-10-05 14:29:53 -0400559}
560
Lifu Tang30f95a72016-01-07 23:20:38 -0800561static jboolean android_location_GnssLocationProvider_is_supported(
destradaaef752b62015-04-17 13:10:47 -0700562 JNIEnv* /* env */, jclass /* clazz */)
563{
564 return (sGpsInterface != NULL) ? JNI_TRUE : JNI_FALSE;
565}
566
Lifu Tang30f95a72016-01-07 23:20:38 -0800567static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
destradaaef752b62015-04-17 13:10:47 -0700568 JNIEnv* /* env */, jclass /* clazz */)
569{
570 return (sAGpsRilInterface != NULL) ? JNI_TRUE : JNI_FALSE;
571}
572
573static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
574 JNIEnv* /* env */, jclass /* jclazz */)
575{
576 return (sGnssConfigurationInterface != NULL) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577}
578
Lifu Tang30f95a72016-01-07 23:20:38 -0800579static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800581 // this must be set before calling into the HAL library
582 if (!mCallbacksObj)
583 mCallbacksObj = env->NewGlobalRef(obj);
584
585 // fail if the main interface fails to initialize
586 if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000587 return JNI_FALSE;
Mike Lockwood58bda982009-04-14 16:25:07 -0400588
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700589 // if XTRA initialization fails we will disable it by sGpsXtraInterface to NULL,
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800590 // but continue to allow the rest of the GPS interface to work.
591 if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0)
592 sGpsXtraInterface = NULL;
593 if (sAGpsInterface)
594 sAGpsInterface->init(&sAGpsCallbacks);
595 if (sGpsNiInterface)
596 sGpsNiInterface->init(&sGpsNiCallbacks);
597 if (sAGpsRilInterface)
598 sAGpsRilInterface->init(&sAGpsRilCallbacks);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700599 if (sGpsGeofencingInterface)
600 sGpsGeofencingInterface->init(&sGpsGeofenceCallbacks);
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -0600601
Narayan Kamath87d6cd42014-01-08 12:26:28 +0000602 return JNI_TRUE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603}
604
Lifu Tang30f95a72016-01-07 23:20:38 -0800605static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800607 if (sGpsInterface)
608 sGpsInterface->cleanup();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609}
610
Lifu Tang30f95a72016-01-07 23:20:38 -0800611static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700612 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
613 jint preferred_time)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614{
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000615 if (sGpsInterface) {
616 if (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
617 preferred_time) == 0) {
618 return JNI_TRUE;
619 } else {
620 return JNI_FALSE;
621 }
622 }
Mike Lockwood42702372010-10-10 16:04:18 -0400623 else
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000624 return JNI_FALSE;
Mike Lockwood04598b62010-04-14 17:17:24 -0400625}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626
Lifu Tang30f95a72016-01-07 23:20:38 -0800627static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */)
Mike Lockwood04598b62010-04-14 17:17:24 -0400628{
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000629 if (sGpsInterface) {
630 if (sGpsInterface->start() == 0) {
631 return JNI_TRUE;
632 } else {
633 return JNI_FALSE;
634 }
635 }
Mike Lockwood42702372010-10-10 16:04:18 -0400636 else
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000637 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638}
639
Lifu Tang30f95a72016-01-07 23:20:38 -0800640static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641{
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000642 if (sGpsInterface) {
643 if (sGpsInterface->stop() == 0) {
644 return JNI_TRUE;
645 } else {
646 return JNI_FALSE;
647 }
648 }
Mike Lockwood42702372010-10-10 16:04:18 -0400649 else
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000650 return JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651}
652
Lifu Tang30f95a72016-01-07 23:20:38 -0800653static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700654 jobject /* obj */,
655 jint flags)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800657 if (sGpsInterface)
658 sGpsInterface->delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659}
660
Lifu Tang30f95a72016-01-07 23:20:38 -0800661static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
662 jintArray prnWithFlagArray, jfloatArray snrArray, jfloatArray elevArray,
663 jfloatArray azumArray, jintArray constellationTypeArray)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700665 // this should only be called from within a call to reportSvStatus
Lifu Tang30f95a72016-01-07 23:20:38 -0800666 jint* prnWithFlags = env->GetIntArrayElements(prnWithFlagArray, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 jfloat* snrs = env->GetFloatArrayElements(snrArray, 0);
668 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
669 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
Lifu Tang30f95a72016-01-07 23:20:38 -0800670 jint* constellationTypes = env->GetIntArrayElements(constellationTypeArray, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671
Lifu Tang30f95a72016-01-07 23:20:38 -0800672 // GNSS SV info.
673 for (size_t i = 0; i < sGnssSvListSize; ++i) {
674 const GnssSvInfo& info = sGnssSvList[i];
675 constellationTypes[i] = info.constellation;
676 prnWithFlags[i] = (info.prn << PRN_SHIFT_WIDTH) | info.flags;
677 snrs[i] = info.snr;
678 elev[i] = info.elevation;
679 azim[i] = info.azimuth;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681
Lifu Tang30f95a72016-01-07 23:20:38 -0800682 env->ReleaseIntArrayElements(prnWithFlagArray, prnWithFlags, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800683 env->ReleaseFloatArrayElements(snrArray, snrs, 0);
684 env->ReleaseFloatArrayElements(elevArray, elev, 0);
685 env->ReleaseFloatArrayElements(azumArray, azim, 0);
Lifu Tang30f95a72016-01-07 23:20:38 -0800686 env->ReleaseIntArrayElements(constellationTypeArray, constellationTypes, 0);
687 return (jint) sGnssSvListSize;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688}
689
Lifu Tang30f95a72016-01-07 23:20:38 -0800690static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700691 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid)
Miguel Torroja1e84da82010-07-27 07:02:24 +0200692{
693 AGpsRefLocation location;
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800694
695 if (!sAGpsRilInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000696 ALOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
Miguel Torroja1e84da82010-07-27 07:02:24 +0200697 return;
Mike Lockwoodbea31182010-10-05 14:29:53 -0400698 }
699
Miguel Torroja1e84da82010-07-27 07:02:24 +0200700 switch(type) {
701 case AGPS_REF_LOCATION_TYPE_GSM_CELLID:
702 case AGPS_REF_LOCATION_TYPE_UMTS_CELLID:
703 location.type = type;
704 location.u.cellID.mcc = mcc;
705 location.u.cellID.mnc = mnc;
706 location.u.cellID.lac = lac;
707 location.u.cellID.cid = cid;
708 break;
709 default:
Steve Block3762c312012-01-06 19:20:56 +0000710 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__);
Miguel Torroja1e84da82010-07-27 07:02:24 +0200711 return;
712 break;
713 }
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800714 sAGpsRilInterface->set_ref_location(&location, sizeof(location));
Miguel Torroja1e84da82010-07-27 07:02:24 +0200715}
716
Lifu Tang30f95a72016-01-07 23:20:38 -0800717static void android_location_GnssLocationProvider_agps_send_ni_message(JNIEnv* env,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700718 jobject /* obj */, jbyteArray ni_msg, jint size)
Miguel Torroja1e84da82010-07-27 07:02:24 +0200719{
720 size_t sz;
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800721
722 if (!sAGpsRilInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000723 ALOGE("no AGPS RIL interface in send_ni_message");
Miguel Torroja1e84da82010-07-27 07:02:24 +0200724 return;
Mike Lockwoodbea31182010-10-05 14:29:53 -0400725 }
Miguel Torroja1e84da82010-07-27 07:02:24 +0200726 if (size < 0)
727 return;
728 sz = (size_t)size;
729 jbyte* b = env->GetByteArrayElements(ni_msg, 0);
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800730 sAGpsRilInterface->ni_message((uint8_t *)b,sz);
Miguel Torroja1e84da82010-07-27 07:02:24 +0200731 env->ReleaseByteArrayElements(ni_msg,b,0);
732}
733
Lifu Tang30f95a72016-01-07 23:20:38 -0800734static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700735 jint type, jstring setid_string)
Miguel Torroja1e84da82010-07-27 07:02:24 +0200736{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800737 if (!sAGpsRilInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000738 ALOGE("no AGPS RIL interface in agps_set_id");
Miguel Torroja1e84da82010-07-27 07:02:24 +0200739 return;
Mike Lockwoodbea31182010-10-05 14:29:53 -0400740 }
Miguel Torroja1e84da82010-07-27 07:02:24 +0200741
742 const char *setid = env->GetStringUTFChars(setid_string, NULL);
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800743 sAGpsRilInterface->set_set_id(type, setid);
Miguel Torroja1e84da82010-07-27 07:02:24 +0200744 env->ReleaseStringUTFChars(setid_string, setid);
745}
746
Lifu Tang30f95a72016-01-07 23:20:38 -0800747static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
Mike Lockwoodf602d362010-06-20 14:28:16 -0700748 jbyteArray nmeaArray, jint buffer_size)
Mike Lockwoodb16e7802009-08-06 09:26:02 -0400749{
Mike Lockwoodf602d362010-06-20 14:28:16 -0700750 // this should only be called from within a call to reportNmea
751 jbyte* nmea = (jbyte *)env->GetPrimitiveArrayCritical(nmeaArray, 0);
752 int length = sNmeaStringLength;
Mike Lockwoodb16e7802009-08-06 09:26:02 -0400753 if (length > buffer_size)
754 length = buffer_size;
Mike Lockwoodf602d362010-06-20 14:28:16 -0700755 memcpy(nmea, sNmeaString, length);
756 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000757 return (jint) length;
Mike Lockwoodb16e7802009-08-06 09:26:02 -0400758}
759
Lifu Tang30f95a72016-01-07 23:20:38 -0800760static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
Mike Lockwoodf602d362010-06-20 14:28:16 -0700761 jlong time, jlong timeReference, jint uncertainty)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800763 if (sGpsInterface)
764 sGpsInterface->inject_time(time, timeReference, uncertainty);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765}
766
Lifu Tang30f95a72016-01-07 23:20:38 -0800767static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700768 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy)
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400769{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800770 if (sGpsInterface)
771 sGpsInterface->inject_location(latitude, longitude, accuracy);
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400772}
773
Lifu Tang30f95a72016-01-07 23:20:38 -0800774static jboolean android_location_GnssLocationProvider_supports_xtra(
destradaaef752b62015-04-17 13:10:47 -0700775 JNIEnv* /* env */, jobject /* obj */)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776{
destradaaef752b62015-04-17 13:10:47 -0700777 return (sGpsXtraInterface != NULL) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778}
779
Lifu Tang30f95a72016-01-07 23:20:38 -0800780static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 jbyteArray data, jint length)
782{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800783 if (!sGpsXtraInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000784 ALOGE("no XTRA interface in inject_xtra_data");
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800785 return;
786 }
787
Mike Lockwoodf602d362010-06-20 14:28:16 -0700788 jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 sGpsXtraInterface->inject_xtra_data((char *)bytes, length);
Mike Lockwoodf602d362010-06-20 14:28:16 -0700790 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791}
792
Lifu Tang30f95a72016-01-07 23:20:38 -0800793static void android_location_GnssLocationProvider_agps_data_conn_open(
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700794 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType)
The Android Open Source Project10592532009-03-18 17:39:46 -0700795{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800796 if (!sAGpsInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000797 ALOGE("no AGPS interface in agps_data_conn_open");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400798 return;
The Android Open Source Project10592532009-03-18 17:39:46 -0700799 }
Mike Lockwoodbea31182010-10-05 14:29:53 -0400800 if (apn == NULL) {
801 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
802 return;
The Android Open Source Project10592532009-03-18 17:39:46 -0700803 }
destradaa96a14702014-06-05 11:36:30 -0700804
Mike Lockwoodbea31182010-10-05 14:29:53 -0400805 const char *apnStr = env->GetStringUTFChars(apn, NULL);
destradaa96a14702014-06-05 11:36:30 -0700806
807 size_t interface_size = sAGpsInterface->size;
808 if (interface_size == sizeof(AGpsInterface_v2)) {
809 sAGpsInterface->data_conn_open_with_apn_ip_type(apnStr, apnIpType);
810 } else if (interface_size == sizeof(AGpsInterface_v1)) {
811 sAGpsInterface->data_conn_open(apnStr);
812 } else {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100813 ALOGE("Invalid size of AGpsInterface found: %zd.", interface_size);
destradaa96a14702014-06-05 11:36:30 -0700814 }
815
Mike Lockwoodbea31182010-10-05 14:29:53 -0400816 env->ReleaseStringUTFChars(apn, apnStr);
The Android Open Source Project10592532009-03-18 17:39:46 -0700817}
818
Lifu Tang30f95a72016-01-07 23:20:38 -0800819static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700820 jobject /* obj */)
Mike Lockwood58bda982009-04-14 16:25:07 -0400821{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800822 if (!sAGpsInterface) {
Magnus Eriksson160c1ca2012-12-21 21:07:28 +0100823 ALOGE("no AGPS interface in agps_data_conn_closed");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400824 return;
Mike Lockwood58bda982009-04-14 16:25:07 -0400825 }
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800826 sAGpsInterface->data_conn_closed();
Mike Lockwood58bda982009-04-14 16:25:07 -0400827}
828
Lifu Tang30f95a72016-01-07 23:20:38 -0800829static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700830 jobject /* obj */)
Mike Lockwood58bda982009-04-14 16:25:07 -0400831{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800832 if (!sAGpsInterface) {
Magnus Eriksson160c1ca2012-12-21 21:07:28 +0100833 ALOGE("no AGPS interface in agps_data_conn_failed");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400834 return;
Mike Lockwood58bda982009-04-14 16:25:07 -0400835 }
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800836 sAGpsInterface->data_conn_failed();
Mike Lockwood58bda982009-04-14 16:25:07 -0400837}
838
Lifu Tang30f95a72016-01-07 23:20:38 -0800839static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
Mike Lockwooda9e54612009-06-19 14:54:42 -0400840 jint type, jstring hostname, jint port)
Mike Lockwood58bda982009-04-14 16:25:07 -0400841{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800842 if (!sAGpsInterface) {
Magnus Eriksson160c1ca2012-12-21 21:07:28 +0100843 ALOGE("no AGPS interface in set_agps_server");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400844 return;
Mike Lockwood58bda982009-04-14 16:25:07 -0400845 }
Mike Lockwoodbea31182010-10-05 14:29:53 -0400846 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800847 sAGpsInterface->set_server(type, c_hostname, port);
Mike Lockwoodbea31182010-10-05 14:29:53 -0400848 env->ReleaseStringUTFChars(hostname, c_hostname);
Mike Lockwood58bda982009-04-14 16:25:07 -0400849}
850
Lifu Tang30f95a72016-01-07 23:20:38 -0800851static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700852 jobject /* obj */, jint notifId, jint response)
Danke Xie22d1f9f2009-08-18 18:28:45 -0400853{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800854 if (!sGpsNiInterface) {
Steve Block3762c312012-01-06 19:20:56 +0000855 ALOGE("no NI interface in send_ni_response");
Mike Lockwoodbea31182010-10-05 14:29:53 -0400856 return;
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -0600857 }
Mike Lockwoodbea31182010-10-05 14:29:53 -0400858
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800859 sGpsNiInterface->respond(notifId, response);
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -0600860}
861
Lifu Tang30f95a72016-01-07 23:20:38 -0800862static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700863 jobject /* obj */) {
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -0600864 jstring result = NULL;
865 if (sGpsDebugInterface) {
866 const size_t maxLength = 2047;
867 char buffer[maxLength+1];
868 size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength);
869 if (length > maxLength) length = maxLength;
870 buffer[length] = 0;
871 result = env->NewStringUTF(buffer);
872 }
873 return result;
Danke Xie22d1f9f2009-08-18 18:28:45 -0400874}
875
Lifu Tang30f95a72016-01-07 23:20:38 -0800876static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */,
Ashok Bhat7e2a9dc2014-01-02 19:43:30 +0000877 jboolean connected, jint type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn)
Mike Lockwood50130bb2010-10-11 06:22:50 -0400878{
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800879
880 if (sAGpsRilInterface && sAGpsRilInterface->update_network_state) {
Mike Lockwood50130bb2010-10-11 06:22:50 -0400881 if (extraInfo) {
882 const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL);
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800883 sAGpsRilInterface->update_network_state(connected, type, roaming, extraInfoStr);
Mike Lockwood50130bb2010-10-11 06:22:50 -0400884 env->ReleaseStringUTFChars(extraInfo, extraInfoStr);
885 } else {
Mike Lockwood58ec34c2011-02-23 08:21:00 -0800886 sAGpsRilInterface->update_network_state(connected, type, roaming, NULL);
Mike Lockwood50130bb2010-10-11 06:22:50 -0400887 }
Kevin Tanga5fe6b22011-06-05 14:25:16 -0700888
889 // update_network_availability callback was not included in original AGpsRilInterface
890 if (sAGpsRilInterface->size >= sizeof(AGpsRilInterface)
891 && sAGpsRilInterface->update_network_availability) {
892 const char *c_apn = env->GetStringUTFChars(apn, NULL);
893 sAGpsRilInterface->update_network_availability(available, c_apn);
894 env->ReleaseStringUTFChars(apn, c_apn);
895 }
Mike Lockwood50130bb2010-10-11 06:22:50 -0400896 }
897}
898
Lifu Tang30f95a72016-01-07 23:20:38 -0800899static jboolean android_location_GnssLocationProvider_is_geofence_supported(
destradaaef752b62015-04-17 13:10:47 -0700900 JNIEnv* /* env */, jobject /* obj */)
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700901{
destradaaef752b62015-04-17 13:10:47 -0700902 return (sGpsGeofencingInterface != NULL) ? JNI_TRUE : JNI_FALSE;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700903}
904
Lifu Tang30f95a72016-01-07 23:20:38 -0800905static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700906 jobject /* obj */, jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius,
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700907 jint last_transition, jint monitor_transition, jint notification_responsiveness,
908 jint unknown_timer) {
909 if (sGpsGeofencingInterface != NULL) {
910 sGpsGeofencingInterface->add_geofence_area(geofence_id, latitude, longitude,
911 radius, last_transition, monitor_transition, notification_responsiveness,
912 unknown_timer);
913 return JNI_TRUE;
914 } else {
915 ALOGE("Geofence interface not available");
916 }
917 return JNI_FALSE;
918}
919
Lifu Tang30f95a72016-01-07 23:20:38 -0800920static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700921 jobject /* obj */, jint geofence_id) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700922 if (sGpsGeofencingInterface != NULL) {
923 sGpsGeofencingInterface->remove_geofence_area(geofence_id);
924 return JNI_TRUE;
925 } else {
926 ALOGE("Geofence interface not available");
927 }
928 return JNI_FALSE;
929}
930
Lifu Tang30f95a72016-01-07 23:20:38 -0800931static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700932 jobject /* obj */, jint geofence_id) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700933 if (sGpsGeofencingInterface != NULL) {
934 sGpsGeofencingInterface->pause_geofence(geofence_id);
935 return JNI_TRUE;
936 } else {
937 ALOGE("Geofence interface not available");
938 }
939 return JNI_FALSE;
940}
941
Lifu Tang30f95a72016-01-07 23:20:38 -0800942static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
Andreas Gampe184e3ed2014-09-29 15:04:06 -0700943 jobject /* obj */, jint geofence_id, jint monitor_transition) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700944 if (sGpsGeofencingInterface != NULL) {
945 sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition);
946 return JNI_TRUE;
947 } else {
948 ALOGE("Geofence interface not available");
949 }
950 return JNI_FALSE;
951}
952
destradaaea8a8a62014-06-23 18:19:03 -0700953static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) {
954 const char* doubleSignature = "(D)V";
destradaa2102dd72014-07-18 17:50:24 -0700955 const char* longSignature = "(J)V";
destradaaea8a8a62014-06-23 18:19:03 -0700956
957 jclass gpsClockClass = env->FindClass("android/location/GpsClock");
958 jmethodID gpsClockCtor = env->GetMethodID(gpsClockClass, "<init>", "()V");
959
960 jobject gpsClockObject = env->NewObject(gpsClockClass, gpsClockCtor);
961 GpsClockFlags flags = clock->flags;
962
963 if (flags & GPS_CLOCK_HAS_LEAP_SECOND) {
964 jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setLeapSecond", "(S)V");
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700965 env->CallVoidMethod(gpsClockObject, setterMethod, clock->leap_second);
destradaaea8a8a62014-06-23 18:19:03 -0700966 }
967
destradaa2102dd72014-07-18 17:50:24 -0700968 jmethodID typeSetterMethod = env->GetMethodID(gpsClockClass, "setType", "(B)V");
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700969 env->CallVoidMethod(gpsClockObject, typeSetterMethod, clock->type);
destradaa2102dd72014-07-18 17:50:24 -0700970
971 jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setTimeInNs", longSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700972 env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_ns);
destradaaea8a8a62014-06-23 18:19:03 -0700973
974 if (flags & GPS_CLOCK_HAS_TIME_UNCERTAINTY) {
destradaa2102dd72014-07-18 17:50:24 -0700975 jmethodID setterMethod =
976 env->GetMethodID(gpsClockClass, "setTimeUncertaintyInNs", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700977 env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_uncertainty_ns);
destradaaea8a8a62014-06-23 18:19:03 -0700978 }
979
destradaa2102dd72014-07-18 17:50:24 -0700980 if (flags & GPS_CLOCK_HAS_FULL_BIAS) {
981 jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setFullBiasInNs", longSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700982 env->CallVoidMethod(gpsClockObject, setterMethod, clock->full_bias_ns);
destradaa2102dd72014-07-18 17:50:24 -0700983 }
984
destradaaea8a8a62014-06-23 18:19:03 -0700985 if (flags & GPS_CLOCK_HAS_BIAS) {
986 jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setBiasInNs", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700987 env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_ns);
destradaaea8a8a62014-06-23 18:19:03 -0700988 }
989
990 if (flags & GPS_CLOCK_HAS_BIAS_UNCERTAINTY) {
destradaa2102dd72014-07-18 17:50:24 -0700991 jmethodID setterMethod =
992 env->GetMethodID(gpsClockClass, "setBiasUncertaintyInNs", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700993 env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_uncertainty_ns);
destradaaea8a8a62014-06-23 18:19:03 -0700994 }
995
996 if (flags & GPS_CLOCK_HAS_DRIFT) {
destradaa2102dd72014-07-18 17:50:24 -0700997 jmethodID setterMethod =
998 env->GetMethodID(gpsClockClass, "setDriftInNsPerSec", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700999 env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_nsps);
destradaaea8a8a62014-06-23 18:19:03 -07001000 }
1001
1002 if (flags & GPS_CLOCK_HAS_DRIFT_UNCERTAINTY) {
destradaa2102dd72014-07-18 17:50:24 -07001003 jmethodID setterMethod =
1004 env->GetMethodID(gpsClockClass, "setDriftUncertaintyInNsPerSec", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001005 env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps);
destradaaea8a8a62014-06-23 18:19:03 -07001006 }
1007
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001008 env->DeleteLocalRef(gpsClockClass);
destradaaea8a8a62014-06-23 18:19:03 -07001009 return gpsClockObject;
1010}
1011
destradaa2102dd72014-07-18 17:50:24 -07001012static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measurement) {
1013 const char* byteSignature = "(B)V";
destradaaea8a8a62014-06-23 18:19:03 -07001014 const char* shortSignature = "(S)V";
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001015 const char* intSignature = "(I)V";
destradaaea8a8a62014-06-23 18:19:03 -07001016 const char* longSignature = "(J)V";
1017 const char* floatSignature = "(F)V";
1018 const char* doubleSignature = "(D)V";
1019
1020 jclass gpsMeasurementClass = env->FindClass("android/location/GpsMeasurement");
1021 jmethodID gpsMeasurementCtor = env->GetMethodID(gpsMeasurementClass, "<init>", "()V");
1022
1023 jobject gpsMeasurementObject = env->NewObject(gpsMeasurementClass, gpsMeasurementCtor);
1024 GpsMeasurementFlags flags = measurement->flags;
1025
destradaa2102dd72014-07-18 17:50:24 -07001026 jmethodID prnSetterMethod = env->GetMethodID(gpsMeasurementClass, "setPrn", byteSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001027 env->CallVoidMethod(gpsMeasurementObject, prnSetterMethod, measurement->prn);
destradaaea8a8a62014-06-23 18:19:03 -07001028
destradaa2102dd72014-07-18 17:50:24 -07001029 jmethodID timeOffsetSetterMethod =
1030 env->GetMethodID(gpsMeasurementClass, "setTimeOffsetInNs", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001031 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001032 gpsMeasurementObject,
destradaa2102dd72014-07-18 17:50:24 -07001033 timeOffsetSetterMethod,
1034 measurement->time_offset_ns);
1035
1036 jmethodID stateSetterMethod = env->GetMethodID(gpsMeasurementClass, "setState", shortSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001037 env->CallVoidMethod(gpsMeasurementObject, stateSetterMethod, measurement->state);
destradaaea8a8a62014-06-23 18:19:03 -07001038
1039 jmethodID receivedGpsTowSetterMethod =
1040 env->GetMethodID(gpsMeasurementClass, "setReceivedGpsTowInNs", longSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001041 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001042 gpsMeasurementObject,
1043 receivedGpsTowSetterMethod,
1044 measurement->received_gps_tow_ns);
1045
destradaa81cabb82014-07-22 09:59:43 -07001046 jmethodID receivedGpsTowUncertaintySetterMethod = env->GetMethodID(
1047 gpsMeasurementClass,
1048 "setReceivedGpsTowUncertaintyInNs",
1049 longSignature);
1050 env->CallVoidMethod(
1051 gpsMeasurementObject,
1052 receivedGpsTowUncertaintySetterMethod,
1053 measurement->received_gps_tow_uncertainty_ns);
1054
destradaa2102dd72014-07-18 17:50:24 -07001055 jmethodID cn0SetterMethod =
1056 env->GetMethodID(gpsMeasurementClass, "setCn0InDbHz", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001057 env->CallVoidMethod(gpsMeasurementObject, cn0SetterMethod, measurement->c_n0_dbhz);
destradaaea8a8a62014-06-23 18:19:03 -07001058
1059 jmethodID pseudorangeRateSetterMethod = env->GetMethodID(
1060 gpsMeasurementClass,
1061 "setPseudorangeRateInMetersPerSec",
1062 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001063 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001064 gpsMeasurementObject,
1065 pseudorangeRateSetterMethod,
destradaa2102dd72014-07-18 17:50:24 -07001066 measurement->pseudorange_rate_mps);
destradaaea8a8a62014-06-23 18:19:03 -07001067
1068 jmethodID pseudorangeRateUncertaintySetterMethod = env->GetMethodID(
1069 gpsMeasurementClass,
1070 "setPseudorangeRateUncertaintyInMetersPerSec",
1071 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001072 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001073 gpsMeasurementObject,
1074 pseudorangeRateUncertaintySetterMethod,
destradaa2102dd72014-07-18 17:50:24 -07001075 measurement->pseudorange_rate_uncertainty_mps);
1076
1077 jmethodID accumulatedDeltaRangeStateSetterMethod =
1078 env->GetMethodID(gpsMeasurementClass, "setAccumulatedDeltaRangeState", shortSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001079 env->CallVoidMethod(
destradaa2102dd72014-07-18 17:50:24 -07001080 gpsMeasurementObject,
1081 accumulatedDeltaRangeStateSetterMethod,
1082 measurement->accumulated_delta_range_state);
destradaaea8a8a62014-06-23 18:19:03 -07001083
1084 jmethodID accumulatedDeltaRangeSetterMethod = env->GetMethodID(
1085 gpsMeasurementClass,
1086 "setAccumulatedDeltaRangeInMeters",
1087 doubleSignature);
1088 env->CallVoidMethod(
1089 gpsMeasurementObject,
1090 accumulatedDeltaRangeSetterMethod,
1091 measurement->accumulated_delta_range_m);
1092
1093 jmethodID accumulatedDeltaRangeUncertaintySetterMethod = env->GetMethodID(
1094 gpsMeasurementClass,
1095 "setAccumulatedDeltaRangeUncertaintyInMeters",
1096 doubleSignature);
1097 env->CallVoidMethod(
1098 gpsMeasurementObject,
1099 accumulatedDeltaRangeUncertaintySetterMethod,
1100 measurement->accumulated_delta_range_uncertainty_m);
1101
destradaaea8a8a62014-06-23 18:19:03 -07001102 if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE) {
destradaa2102dd72014-07-18 17:50:24 -07001103 jmethodID setterMethod =
1104 env->GetMethodID(gpsMeasurementClass, "setPseudorangeInMeters", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001105 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->pseudorange_m);
destradaaea8a8a62014-06-23 18:19:03 -07001106 }
1107
1108 if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY) {
1109 jmethodID setterMethod = env->GetMethodID(
1110 gpsMeasurementClass,
1111 "setPseudorangeUncertaintyInMeters",
1112 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001113 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001114 gpsMeasurementObject,
1115 setterMethod,
1116 measurement->pseudorange_uncertainty_m);
1117 }
1118
1119 if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE) {
destradaa2102dd72014-07-18 17:50:24 -07001120 jmethodID setterMethod =
1121 env->GetMethodID(gpsMeasurementClass, "setCodePhaseInChips", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001122 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->code_phase_chips);
destradaaea8a8a62014-06-23 18:19:03 -07001123 }
1124
1125 if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY) {
1126 jmethodID setterMethod = env->GetMethodID(
1127 gpsMeasurementClass,
1128 "setCodePhaseUncertaintyInChips",
1129 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001130 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001131 gpsMeasurementObject,
1132 setterMethod,
1133 measurement->code_phase_uncertainty_chips);
1134 }
1135
1136 if (flags & GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
destradaa2102dd72014-07-18 17:50:24 -07001137 jmethodID setterMethod =
1138 env->GetMethodID(gpsMeasurementClass, "setCarrierFrequencyInHz", floatSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001139 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001140 gpsMeasurementObject,
1141 setterMethod,
1142 measurement->carrier_frequency_hz);
1143 }
1144
1145 if (flags & GPS_MEASUREMENT_HAS_CARRIER_CYCLES) {
1146 jmethodID setterMethod =
1147 env->GetMethodID(gpsMeasurementClass, "setCarrierCycles", longSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001148 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->carrier_cycles);
destradaaea8a8a62014-06-23 18:19:03 -07001149 }
1150
1151 if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE) {
1152 jmethodID setterMethod =
1153 env->GetMethodID(gpsMeasurementClass, "setCarrierPhase", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001154 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->carrier_phase);
destradaaea8a8a62014-06-23 18:19:03 -07001155 }
1156
1157 if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
1158 jmethodID setterMethod = env->GetMethodID(
1159 gpsMeasurementClass,
1160 "setCarrierPhaseUncertainty",
1161 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001162 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001163 gpsMeasurementObject,
1164 setterMethod,
1165 measurement->carrier_phase_uncertainty);
1166 }
1167
1168 jmethodID lossOfLockSetterMethod =
destradaa2102dd72014-07-18 17:50:24 -07001169 env->GetMethodID(gpsMeasurementClass, "setLossOfLock", byteSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001170 env->CallVoidMethod(gpsMeasurementObject, lossOfLockSetterMethod, measurement->loss_of_lock);
destradaaea8a8a62014-06-23 18:19:03 -07001171
1172 if (flags & GPS_MEASUREMENT_HAS_BIT_NUMBER) {
destradaa2102dd72014-07-18 17:50:24 -07001173 jmethodID setterMethod =
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001174 env->GetMethodID(gpsMeasurementClass, "setBitNumber", intSignature);
1175 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->bit_number);
destradaaea8a8a62014-06-23 18:19:03 -07001176 }
1177
1178 if (flags & GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT) {
destradaa2102dd72014-07-18 17:50:24 -07001179 jmethodID setterMethod =
1180 env->GetMethodID(gpsMeasurementClass, "setTimeFromLastBitInMs", shortSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001181 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001182 gpsMeasurementObject,
1183 setterMethod,
destradaa2102dd72014-07-18 17:50:24 -07001184 measurement->time_from_last_bit_ms);
destradaaea8a8a62014-06-23 18:19:03 -07001185 }
1186
1187 if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT) {
destradaa2102dd72014-07-18 17:50:24 -07001188 jmethodID setterMethod =
1189 env->GetMethodID(gpsMeasurementClass, "setDopplerShiftInHz", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001190 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->doppler_shift_hz);
destradaaea8a8a62014-06-23 18:19:03 -07001191 }
1192
1193 if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY) {
1194 jmethodID setterMethod = env->GetMethodID(
1195 gpsMeasurementClass,
1196 "setDopplerShiftUncertaintyInHz",
1197 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001198 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001199 gpsMeasurementObject,
1200 setterMethod,
1201 measurement->doppler_shift_uncertainty_hz);
1202 }
1203
destradaa2102dd72014-07-18 17:50:24 -07001204 jmethodID multipathIndicatorSetterMethod =
1205 env->GetMethodID(gpsMeasurementClass, "setMultipathIndicator", byteSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001206 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001207 gpsMeasurementObject,
1208 multipathIndicatorSetterMethod,
1209 measurement->multipath_indicator);
1210
1211 if (flags & GPS_MEASUREMENT_HAS_SNR) {
1212 jmethodID setterMethod =
1213 env->GetMethodID(gpsMeasurementClass, "setSnrInDb", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001214 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->snr_db);
destradaaea8a8a62014-06-23 18:19:03 -07001215 }
1216
1217 if (flags & GPS_MEASUREMENT_HAS_ELEVATION) {
destradaa2102dd72014-07-18 17:50:24 -07001218 jmethodID setterMethod =
1219 env->GetMethodID(gpsMeasurementClass, "setElevationInDeg", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001220 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->elevation_deg);
destradaaea8a8a62014-06-23 18:19:03 -07001221 }
1222
1223 if (flags & GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY) {
destradaa2102dd72014-07-18 17:50:24 -07001224 jmethodID setterMethod =
1225 env->GetMethodID(gpsMeasurementClass, "setElevationUncertaintyInDeg", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001226 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001227 gpsMeasurementObject,
1228 setterMethod,
1229 measurement->elevation_uncertainty_deg);
1230 }
1231
1232 if (flags & GPS_MEASUREMENT_HAS_AZIMUTH) {
1233 jmethodID setterMethod =
1234 env->GetMethodID(gpsMeasurementClass, "setAzimuthInDeg", doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001235 env->CallVoidMethod(gpsMeasurementObject, setterMethod, measurement->azimuth_deg);
destradaaea8a8a62014-06-23 18:19:03 -07001236 }
1237
1238 if (flags & GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY) {
1239 jmethodID setterMethod = env->GetMethodID(
1240 gpsMeasurementClass,
1241 "setAzimuthUncertaintyInDeg",
1242 doubleSignature);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001243 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001244 gpsMeasurementObject,
1245 setterMethod,
1246 measurement->azimuth_uncertainty_deg);
1247 }
1248
1249 jmethodID usedInFixSetterMethod = env->GetMethodID(gpsMeasurementClass, "setUsedInFix", "(Z)V");
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001250 env->CallVoidMethod(
destradaaea8a8a62014-06-23 18:19:03 -07001251 gpsMeasurementObject,
1252 usedInFixSetterMethod,
1253 (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
1254
destradaadf119842014-10-14 16:52:43 -07001255 env->DeleteLocalRef(gpsMeasurementClass);
destradaaea8a8a62014-06-23 18:19:03 -07001256 return gpsMeasurementObject;
1257}
1258
1259static jobjectArray translate_gps_measurements(JNIEnv* env, GpsData* data) {
1260 size_t measurementCount = data->measurement_count;
1261 if (measurementCount == 0) {
1262 return NULL;
1263 }
1264
1265 jclass gpsMeasurementClass = env->FindClass("android/location/GpsMeasurement");
1266 jobjectArray gpsMeasurementArray = env->NewObjectArray(
1267 measurementCount,
1268 gpsMeasurementClass,
1269 NULL /* initialElement */);
1270
1271 GpsMeasurement* gpsMeasurements = data->measurements;
1272 for (uint16_t i = 0; i < measurementCount; ++i) {
destradaa2102dd72014-07-18 17:50:24 -07001273 jobject gpsMeasurement = translate_gps_measurement(env, &gpsMeasurements[i]);
destradaaea8a8a62014-06-23 18:19:03 -07001274 env->SetObjectArrayElement(gpsMeasurementArray, i, gpsMeasurement);
1275 env->DeleteLocalRef(gpsMeasurement);
1276 }
1277
1278 env->DeleteLocalRef(gpsMeasurementClass);
1279 return gpsMeasurementArray;
1280}
1281
1282static void measurement_callback(GpsData* data) {
1283 JNIEnv* env = AndroidRuntime::getJNIEnv();
1284 if (data == NULL) {
1285 ALOGE("Invalid data provided to gps_measurement_callback");
1286 return;
1287 }
1288
1289 if (data->size == sizeof(GpsData)) {
1290 jobject gpsClock = translate_gps_clock(env, &data->clock);
1291 jobjectArray measurementArray = translate_gps_measurements(env, data);
1292
1293 jclass gpsMeasurementsEventClass = env->FindClass("android/location/GpsMeasurementsEvent");
1294 jmethodID gpsMeasurementsEventCtor = env->GetMethodID(
1295 gpsMeasurementsEventClass,
1296 "<init>",
1297 "(Landroid/location/GpsClock;[Landroid/location/GpsMeasurement;)V");
1298
1299 jobject gpsMeasurementsEvent = env->NewObject(
1300 gpsMeasurementsEventClass,
1301 gpsMeasurementsEventCtor,
1302 gpsClock,
1303 measurementArray);
1304
1305 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gpsMeasurementsEvent);
1306 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001307
1308 env->DeleteLocalRef(gpsClock);
1309 env->DeleteLocalRef(measurementArray);
1310 env->DeleteLocalRef(gpsMeasurementsEventClass);
1311 env->DeleteLocalRef(gpsMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -07001312 } else {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +01001313 ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%zd", data->size);
destradaaea8a8a62014-06-23 18:19:03 -07001314 }
1315}
1316
1317GpsMeasurementCallbacks sGpsMeasurementCallbacks = {
1318 sizeof(GpsMeasurementCallbacks),
1319 measurement_callback,
1320};
1321
Lifu Tang30f95a72016-01-07 23:20:38 -08001322static jboolean android_location_GnssLocationProvider_is_measurement_supported(
destradaaea8a8a62014-06-23 18:19:03 -07001323 JNIEnv* env,
destradaa4b3e3932014-07-21 18:01:47 -07001324 jclass clazz) {
destradaaea8a8a62014-06-23 18:19:03 -07001325 if (sGpsMeasurementInterface != NULL) {
1326 return JNI_TRUE;
1327 }
1328 return JNI_FALSE;
1329}
1330
Lifu Tang30f95a72016-01-07 23:20:38 -08001331static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001332 JNIEnv* env,
1333 jobject obj) {
1334 if (sGpsMeasurementInterface == NULL) {
1335 ALOGE("Measurement interface is not available.");
1336 return JNI_FALSE;
1337 }
1338
1339 int result = sGpsMeasurementInterface->init(&sGpsMeasurementCallbacks);
1340 if (result != GPS_GEOFENCE_OPERATION_SUCCESS) {
1341 ALOGE("An error has been found on GpsMeasurementInterface::init, status=%d", result);
1342 return JNI_FALSE;
1343 }
1344
1345 return JNI_TRUE;
1346}
1347
Lifu Tang30f95a72016-01-07 23:20:38 -08001348static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001349 JNIEnv* env,
1350 jobject obj) {
1351 if (sGpsMeasurementInterface == NULL) {
1352 ALOGE("Measurement interface not available");
1353 return JNI_FALSE;
1354 }
1355
1356 sGpsMeasurementInterface->close();
1357 return JNI_TRUE;
1358}
1359
destradaa4b3e3932014-07-21 18:01:47 -07001360static jobject translate_gps_navigation_message(JNIEnv* env, GpsNavigationMessage* message) {
1361 size_t dataLength = message->data_length;
1362 uint8_t* data = message->data;
1363 if (dataLength == 0 || data == NULL) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +01001364 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
destradaa4b3e3932014-07-21 18:01:47 -07001365 return NULL;
1366 }
1367
1368 jclass navigationMessageClass = env->FindClass("android/location/GpsNavigationMessage");
1369 jmethodID navigationMessageCtor = env->GetMethodID(navigationMessageClass, "<init>", "()V");
1370 jobject navigationMessageObject = env->NewObject(navigationMessageClass, navigationMessageCtor);
1371
1372 jmethodID setTypeMethod = env->GetMethodID(navigationMessageClass, "setType", "(B)V");
1373 env->CallVoidMethod(navigationMessageObject, setTypeMethod, message->type);
1374
1375 jmethodID setPrnMethod = env->GetMethodID(navigationMessageClass, "setPrn", "(B)V");
1376 env->CallVoidMethod(navigationMessageObject, setPrnMethod, message->prn);
1377
1378 jmethodID setMessageIdMethod = env->GetMethodID(navigationMessageClass, "setMessageId", "(S)V");
1379 env->CallVoidMethod(navigationMessageObject, setMessageIdMethod, message->message_id);
1380
1381 jmethodID setSubmessageIdMethod =
1382 env->GetMethodID(navigationMessageClass, "setSubmessageId", "(S)V");
1383 env->CallVoidMethod(navigationMessageObject, setSubmessageIdMethod, message->submessage_id);
1384
1385 jbyteArray dataArray = env->NewByteArray(dataLength);
1386 env->SetByteArrayRegion(dataArray, 0, dataLength, (jbyte*) data);
1387 jmethodID setDataMethod = env->GetMethodID(navigationMessageClass, "setData", "([B)V");
1388 env->CallVoidMethod(navigationMessageObject, setDataMethod, dataArray);
1389
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001390 env->DeleteLocalRef(navigationMessageClass);
1391 env->DeleteLocalRef(dataArray);
destradaa4b3e3932014-07-21 18:01:47 -07001392 return navigationMessageObject;
1393}
1394
1395static void navigation_message_callback(GpsNavigationMessage* message) {
1396 JNIEnv* env = AndroidRuntime::getJNIEnv();
1397 if (message == NULL) {
1398 ALOGE("Invalid Navigation Message provided to callback");
1399 return;
1400 }
1401
1402 if (message->size == sizeof(GpsNavigationMessage)) {
1403 jobject navigationMessage = translate_gps_navigation_message(env, message);
1404
1405 jclass navigationMessageEventClass =
1406 env->FindClass("android/location/GpsNavigationMessageEvent");
1407 jmethodID navigationMessageEventCtor = env->GetMethodID(
1408 navigationMessageEventClass,
1409 "<init>",
1410 "(Landroid/location/GpsNavigationMessage;)V");
1411 jobject navigationMessageEvent = env->NewObject(
1412 navigationMessageEventClass,
1413 navigationMessageEventCtor,
1414 navigationMessage);
1415
1416 env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessageEvent);
1417 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001418
1419 env->DeleteLocalRef(navigationMessage);
1420 env->DeleteLocalRef(navigationMessageEventClass);
1421 env->DeleteLocalRef(navigationMessageEvent);
destradaa4b3e3932014-07-21 18:01:47 -07001422 } else {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +01001423 ALOGE("Invalid GpsNavigationMessage size found: %zd", message->size);
destradaa4b3e3932014-07-21 18:01:47 -07001424 }
1425}
1426
1427GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = {
1428 sizeof(GpsNavigationMessageCallbacks),
1429 navigation_message_callback,
1430};
1431
Lifu Tang30f95a72016-01-07 23:20:38 -08001432static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001433 JNIEnv* env,
1434 jclass clazz) {
1435 if(sGpsNavigationMessageInterface != NULL) {
1436 return JNI_TRUE;
1437 }
1438 return JNI_FALSE;
1439}
1440
Lifu Tang30f95a72016-01-07 23:20:38 -08001441static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001442 JNIEnv* env,
1443 jobject obj) {
1444 if (sGpsNavigationMessageInterface == NULL) {
1445 ALOGE("Navigation Message interface is not available.");
1446 return JNI_FALSE;
1447 }
1448
1449 int result = sGpsNavigationMessageInterface->init(&sGpsNavigationMessageCallbacks);
1450 if (result != GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS) {
1451 ALOGE("An error has been found in %s: %d", __FUNCTION__, result);
1452 return JNI_FALSE;
1453 }
1454
1455 return JNI_TRUE;
1456}
1457
Lifu Tang30f95a72016-01-07 23:20:38 -08001458static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001459 JNIEnv* env,
1460 jobject obj) {
1461 if (sGpsNavigationMessageInterface == NULL) {
1462 ALOGE("Navigation Message interface is not available.");
1463 return JNI_FALSE;
1464 }
1465
1466 sGpsNavigationMessageInterface->close();
1467 return JNI_TRUE;
1468}
1469
Lifu Tang30f95a72016-01-07 23:20:38 -08001470static void android_location_GnssLocationProvider_configuration_update(JNIEnv* env, jobject obj,
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001471 jstring config_content)
1472{
1473 if (!sGnssConfigurationInterface) {
1474 ALOGE("no GPS configuration interface in configuraiton_update");
1475 return;
1476 }
1477 const char *data = env->GetStringUTFChars(config_content, NULL);
1478 ALOGD("GPS configuration:\n %s", data);
1479 sGnssConfigurationInterface->configuration_update(
1480 data, env->GetStringUTFLength(config_content));
1481 env->ReleaseStringUTFChars(config_content, data);
1482}
1483
Daniel Micay76f6a862015-09-19 17:31:01 -04001484static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 /* name, signature, funcPtr */
Lifu Tang30f95a72016-01-07 23:20:38 -08001486 {"class_init_native", "()V", (void *)android_location_GnssLocationProvider_class_init_native},
1487 {"native_is_supported", "()Z", (void*)android_location_GnssLocationProvider_is_supported},
destradaaef752b62015-04-17 13:10:47 -07001488 {"native_is_agps_ril_supported", "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001489 (void*)android_location_GnssLocationProvider_is_agps_ril_supported},
destradaaef752b62015-04-17 13:10:47 -07001490 {"native_is_gnss_configuration_supported", "()Z",
1491 (void*)android_location_gpsLocationProvider_is_gnss_configuration_supported},
Lifu Tang30f95a72016-01-07 23:20:38 -08001492 {"native_init", "()Z", (void*)android_location_GnssLocationProvider_init},
1493 {"native_cleanup", "()V", (void*)android_location_GnssLocationProvider_cleanup},
destradaaea8a8a62014-06-23 18:19:03 -07001494 {"native_set_position_mode",
1495 "(IIIII)Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001496 (void*)android_location_GnssLocationProvider_set_position_mode},
1497 {"native_start", "()Z", (void*)android_location_GnssLocationProvider_start},
1498 {"native_stop", "()Z", (void*)android_location_GnssLocationProvider_stop},
destradaaea8a8a62014-06-23 18:19:03 -07001499 {"native_delete_aiding_data",
1500 "(I)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001501 (void*)android_location_GnssLocationProvider_delete_aiding_data},
destradaaea8a8a62014-06-23 18:19:03 -07001502 {"native_read_sv_status",
1503 "([I[F[F[F[I)I",
Lifu Tang30f95a72016-01-07 23:20:38 -08001504 (void*)android_location_GnssLocationProvider_read_sv_status},
1505 {"native_read_nmea", "([BI)I", (void*)android_location_GnssLocationProvider_read_nmea},
1506 {"native_inject_time", "(JJI)V", (void*)android_location_GnssLocationProvider_inject_time},
destradaaea8a8a62014-06-23 18:19:03 -07001507 {"native_inject_location",
1508 "(DDF)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001509 (void*)android_location_GnssLocationProvider_inject_location},
1510 {"native_supports_xtra", "()Z", (void*)android_location_GnssLocationProvider_supports_xtra},
destradaaea8a8a62014-06-23 18:19:03 -07001511 {"native_inject_xtra_data",
1512 "([BI)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001513 (void*)android_location_GnssLocationProvider_inject_xtra_data},
destradaaea8a8a62014-06-23 18:19:03 -07001514 {"native_agps_data_conn_open",
1515 "(Ljava/lang/String;I)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001516 (void*)android_location_GnssLocationProvider_agps_data_conn_open},
destradaaea8a8a62014-06-23 18:19:03 -07001517 {"native_agps_data_conn_closed",
1518 "()V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001519 (void*)android_location_GnssLocationProvider_agps_data_conn_closed},
destradaaea8a8a62014-06-23 18:19:03 -07001520 {"native_agps_data_conn_failed",
1521 "()V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001522 (void*)android_location_GnssLocationProvider_agps_data_conn_failed},
destradaaea8a8a62014-06-23 18:19:03 -07001523 {"native_agps_set_id",
1524 "(ILjava/lang/String;)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001525 (void*)android_location_GnssLocationProvider_agps_set_id},
destradaaea8a8a62014-06-23 18:19:03 -07001526 {"native_agps_set_ref_location_cellid",
1527 "(IIIII)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001528 (void*)android_location_GnssLocationProvider_agps_set_reference_location_cellid},
destradaaea8a8a62014-06-23 18:19:03 -07001529 {"native_set_agps_server",
1530 "(ILjava/lang/String;I)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001531 (void*)android_location_GnssLocationProvider_set_agps_server},
destradaaea8a8a62014-06-23 18:19:03 -07001532 {"native_send_ni_response",
1533 "(II)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001534 (void*)android_location_GnssLocationProvider_send_ni_response},
destradaaea8a8a62014-06-23 18:19:03 -07001535 {"native_agps_ni_message",
1536 "([BI)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001537 (void *)android_location_GnssLocationProvider_agps_send_ni_message},
destradaaea8a8a62014-06-23 18:19:03 -07001538 {"native_get_internal_state",
1539 "()Ljava/lang/String;",
Lifu Tang30f95a72016-01-07 23:20:38 -08001540 (void*)android_location_GnssLocationProvider_get_internal_state},
destradaaea8a8a62014-06-23 18:19:03 -07001541 {"native_update_network_state",
1542 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001543 (void*)android_location_GnssLocationProvider_update_network_state },
destradaaea8a8a62014-06-23 18:19:03 -07001544 {"native_is_geofence_supported",
1545 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001546 (void*) android_location_GnssLocationProvider_is_geofence_supported},
destradaaea8a8a62014-06-23 18:19:03 -07001547 {"native_add_geofence",
1548 "(IDDDIIII)Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001549 (void *)android_location_GnssLocationProvider_add_geofence},
destradaaea8a8a62014-06-23 18:19:03 -07001550 {"native_remove_geofence",
1551 "(I)Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001552 (void *)android_location_GnssLocationProvider_remove_geofence},
1553 {"native_pause_geofence", "(I)Z", (void *)android_location_GnssLocationProvider_pause_geofence},
destradaaea8a8a62014-06-23 18:19:03 -07001554 {"native_resume_geofence",
1555 "(II)Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001556 (void *)android_location_GnssLocationProvider_resume_geofence},
destradaaea8a8a62014-06-23 18:19:03 -07001557 {"native_is_measurement_supported",
1558 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001559 (void*) android_location_GnssLocationProvider_is_measurement_supported},
destradaaea8a8a62014-06-23 18:19:03 -07001560 {"native_start_measurement_collection",
1561 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001562 (void*) android_location_GnssLocationProvider_start_measurement_collection},
destradaaea8a8a62014-06-23 18:19:03 -07001563 {"native_stop_measurement_collection",
1564 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001565 (void*) android_location_GnssLocationProvider_stop_measurement_collection},
destradaa4b3e3932014-07-21 18:01:47 -07001566 {"native_is_navigation_message_supported",
1567 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001568 (void*) android_location_GnssLocationProvider_is_navigation_message_supported},
destradaa4b3e3932014-07-21 18:01:47 -07001569 {"native_start_navigation_message_collection",
1570 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001571 (void*) android_location_GnssLocationProvider_start_navigation_message_collection},
destradaa4b3e3932014-07-21 18:01:47 -07001572 {"native_stop_navigation_message_collection",
1573 "()Z",
Lifu Tang30f95a72016-01-07 23:20:38 -08001574 (void*) android_location_GnssLocationProvider_stop_navigation_message_collection},
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001575 {"native_configuration_update",
1576 "(Ljava/lang/String;)V",
Lifu Tang30f95a72016-01-07 23:20:38 -08001577 (void*)android_location_GnssLocationProvider_configuration_update},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578};
1579
Lifu Tang30f95a72016-01-07 23:20:38 -08001580int register_android_server_location_GnssLocationProvider(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581{
destradaaea8a8a62014-06-23 18:19:03 -07001582 return jniRegisterNativeMethods(
1583 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001584 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001585 sMethods,
1586 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587}
1588
1589} /* namespace android */