blob: 504626544fe491cefe1be12d3c4c89581fdd8d4f [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
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070021#include <android/hardware/gnss/1.0/IGnss.h>
22
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include "JNIHelp.h"
24#include "jni.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>
Lifu Tang38bce792016-02-24 17:17:38 -080032#include <limits>
destradaa96a14702014-06-05 11:36:30 -070033#include <linux/in.h>
34#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <pthread.h>
36#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070037#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
Mike Lockwoodf602d362010-06-20 14:28:16 -070039static jobject mCallbacksObj = NULL;
40
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041static jmethodID method_reportLocation;
42static jmethodID method_reportStatus;
43static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040044static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040045static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040046static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080047static jmethodID method_setGnssYearOfHardware;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040049static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020050static jmethodID method_requestRefLocation;
51static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040052static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070053static jmethodID method_reportGeofenceTransition;
54static jmethodID method_reportGeofenceStatus;
55static jmethodID method_reportGeofenceAddStatus;
56static jmethodID method_reportGeofenceRemoveStatus;
57static jmethodID method_reportGeofencePauseStatus;
58static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070059static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070060static jmethodID method_reportNavigationMessages;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080062/*
63 * Save a pointer to JavaVm to attach/detach threads executing
64 * callback methods that need to make JNI calls.
65 */
66static JavaVM* sJvm;
67
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070068using android::OK;
69using android::sp;
70using android::status_t;
71using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070073using android::hardware::Return;
74using android::hardware::Void;
75using android::hardware::hidl_vec;
Lifu Tang30f95a72016-01-07 23:20:38 -080076
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070077using android::hardware::gnss::V1_0::IAGnss;
78using android::hardware::gnss::V1_0::IAGnssCallback;
79using android::hardware::gnss::V1_0::IAGnssCallback;
80using android::hardware::gnss::V1_0::IAGnssRil;
81using android::hardware::gnss::V1_0::IAGnssRilCallback;
82using android::hardware::gnss::V1_0::IGnss;
83using android::hardware::gnss::V1_0::IGnssCallback;
84using android::hardware::gnss::V1_0::IGnssConfiguration;
85using android::hardware::gnss::V1_0::IGnssDebug;
86using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
87using android::hardware::gnss::V1_0::IGnssGeofencing;
88using android::hardware::gnss::V1_0::IGnssMeasurement;
89using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
90using android::hardware::gnss::V1_0::IGnssNavigationMessage;
91using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
92using android::hardware::gnss::V1_0::IGnssNi;
93using android::hardware::gnss::V1_0::IGnssNiCallback;
94using android::hardware::gnss::V1_0::IGnssXtra;
95using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -070096
Wyatt Rileyf6527ae2016-05-23 15:23:12 -070097
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070098sp<IGnss> gnssHal = nullptr;
99sp<IGnssXtra> gnssXtraIface = nullptr;
100sp<IAGnssRil> agnssRilIface = nullptr;
101sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
102sp<IAGnss> agnssIface = nullptr;
103sp<IGnssDebug> gnssDebugIface = nullptr;
104sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
105sp<IGnssNi> gnssNiIface = nullptr;
106sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
107sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400109#define WAKE_LOCK_NAME "GPS"
110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111namespace android {
112
Lifu Tang120480f2016-02-07 18:08:19 -0800113template<class T>
114class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700115 public:
116 // Helper function to call setter on a Java object.
117 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800118 JNIEnv* env,
119 jclass clazz,
120 jobject object,
121 const char* method_name,
122 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700123
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700124 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800125 static const char *const signature_;
126};
Lifu Tange5a0e212016-01-25 18:02:17 -0800127
Lifu Tang120480f2016-02-07 18:08:19 -0800128template<class T>
129void JavaMethodHelper<T>::callJavaMethod(
130 JNIEnv* env,
131 jclass clazz,
132 jobject object,
133 const char* method_name,
134 T value) {
135 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
136 env->CallVoidMethod(object, method, value);
137}
destradaaea8a8a62014-06-23 18:19:03 -0700138
Lifu Tang120480f2016-02-07 18:08:19 -0800139class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700140 public:
141 JavaObject(JNIEnv* env, const char* class_name);
142 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800143
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144 template<class T>
145 void callSetter(const char* method_name, T value);
146 template<class T>
147 void callSetter(const char* method_name, T* value, size_t size);
148 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800149
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700150 private:
151 JNIEnv* env_;
152 jclass clazz_;
153 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800154};
155
156JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
157 clazz_ = env_->FindClass(class_name);
158 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
159 object_ = env_->NewObject(clazz_, ctor);
160}
161
162JavaObject::~JavaObject() {
163 env_->DeleteLocalRef(clazz_);
164}
165
166template<class T>
167void JavaObject::callSetter(const char* method_name, T value) {
168 JavaMethodHelper<T>::callJavaMethod(
169 env_, clazz_, object_, method_name, value);
170}
171
172template<>
173void JavaObject::callSetter(
174 const char* method_name, uint8_t* value, size_t size) {
175 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700176 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800177 jmethodID method = env_->GetMethodID(
178 clazz_,
179 method_name,
180 "([B)V");
181 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700182 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800183}
184
185jobject JavaObject::get() {
186 return object_;
187}
188
189// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800190template<>
191const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
192template<>
193const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
194template<>
195const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
196template<>
197const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
198template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800199const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
200template<>
201const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800202template<>
203const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
204template<>
205const char *const JavaMethodHelper<float>::signature_ = "(F)V";
206template<>
207const char *const JavaMethodHelper<double>::signature_ = "(D)V";
208template<>
209const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
210
211#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800212
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700213static inline jboolean boolToJbool(bool value) {
214 return value ? JNI_TRUE : JNI_FALSE;
215}
Lifu Tang120480f2016-02-07 18:08:19 -0800216
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700217static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
218 if (env->ExceptionCheck()) {
219 ALOGE("An exception was thrown by callback '%s'.", methodName);
220 LOGE_EX(env);
221 env->ExceptionClear();
222 }
223}
destradaaea8a8a62014-06-23 18:19:03 -0700224
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800225class ScopedJniThreadAttach {
226public:
227 ScopedJniThreadAttach() {
228 /*
229 * attachResult will also be JNI_OK if the thead was already attached to
230 * JNI before the call to AttachCurrentThread().
231 */
232 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
233 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
234 attachResult);
235 }
236
237 ~ScopedJniThreadAttach() {
238 jint detachResult = sJvm->DetachCurrentThread();
239 /*
240 * Return if the thread was already detached. Log error for any other
241 * failure.
242 */
243 if (detachResult == JNI_EDETACHED) {
244 return;
245 }
246
247 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
248 detachResult);
249 }
250
251 JNIEnv* getEnv() {
252 /*
253 * Checking validity of mEnv in case the thread was detached elsewhere.
254 */
255 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
256 return mEnv;
257 }
258
259private:
260 JNIEnv* mEnv = nullptr;
261};
262
263thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
264
265static JNIEnv* getJniEnv() {
266 JNIEnv* env = AndroidRuntime::getJNIEnv();
267
268 /*
269 * If env is nullptr, the thread is not already attached to
270 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
271 * will detach it on thread exit.
272 */
273 if (env == nullptr) {
274 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
275 env = tJniThreadAttacher->getEnv();
276 }
277
278 return env;
279}
280
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700281/*
282 * GnssCallback class implements the callback methods for IGnss interface.
283 */
284struct GnssCallback : public IGnssCallback {
285 Return<void> gnssLocationCb(
286 const android::hardware::gnss::V1_0::GnssLocation& location) override;
287 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
288 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
289 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
290 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
291 Return<void> gnssAcquireWakelockCb() override;
292 Return<void> gnssReleaseWakelockCb() override;
293 Return<void> gnssRequestTimeCb() override;
294 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800295
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700296 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
297 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
298 static size_t sGnssSvListSize;
299
300 static const char* sNmeaString;
301 static size_t sNmeaStringLength;
302};
303
304IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
305 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
306const char* GnssCallback::sNmeaString = nullptr;
307size_t GnssCallback::sNmeaStringLength = 0;
308size_t GnssCallback::sGnssSvListSize = 0;
309
310Return<void> GnssCallback::gnssLocationCb(
311 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800312 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700313 env->CallVoidMethod(mCallbacksObj,
314 method_reportLocation,
315 location.gnssLocationFlags,
316 static_cast<jdouble>(location.latitudeDegrees),
317 static_cast<jdouble>(location.longitudeDegrees),
318 static_cast<jdouble>(location.altitudeMeters),
319 static_cast<jfloat>(location.speedMetersPerSec),
320 static_cast<jfloat>(location.bearingDegrees),
321 static_cast<jfloat>(location.accuracyMeters),
322 static_cast<jlong>(location.timestamp));
323 checkAndClearExceptionFromCallback(env, __FUNCTION__);
324 return Void();
325}
326
327Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800328 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700329 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
330 checkAndClearExceptionFromCallback(env, __FUNCTION__);
331 return Void();
332}
333
334Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800335 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700336
337 sGnssSvListSize = svStatus.numSvs;
338 if (sGnssSvListSize > static_cast<uint32_t>(
339 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
340 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
341 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
342 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800343 }
344
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700345 // Copy GNSS SV info into sGnssSvList, if any.
346 if (svStatus.numSvs > 0) {
347 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800348 }
destradaaea8a8a62014-06-23 18:19:03 -0700349
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700350 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
351 checkAndClearExceptionFromCallback(env, __FUNCTION__);
352 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700353}
354
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700355Return<void> GnssCallback::gnssNmeaCb(
356 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800357 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700358 /*
359 * The Java code will call back to read these values.
360 * We do this to avoid creating unnecessary String objects.
361 */
362 sNmeaString = nmea.c_str();
363 sNmeaStringLength = nmea.size();
364
365 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
366 checkAndClearExceptionFromCallback(env, __FUNCTION__);
367 return Void();
368}
369
370Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
371 ALOGD("%s: %du\n", __func__, capabilities);
372
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800373 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700374 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
375 checkAndClearExceptionFromCallback(env, __FUNCTION__);
376 return Void();
377}
378
379Return<void> GnssCallback::gnssAcquireWakelockCb() {
380 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
381 return Void();
382}
383
384Return<void> GnssCallback::gnssReleaseWakelockCb() {
385 release_wake_lock(WAKE_LOCK_NAME);
386 return Void();
387}
388
389Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800390 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700391 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
392 checkAndClearExceptionFromCallback(env, __FUNCTION__);
393 return Void();
394}
395
396Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
397 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
398
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800399 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700400 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
401 info.yearOfHw);
402 checkAndClearExceptionFromCallback(env, __FUNCTION__);
403 return Void();
404}
405
406class GnssXtraCallback : public IGnssXtraCallback {
407 Return<void> downloadRequestCb() override;
408};
409
410/*
411 * GnssXtraCallback class implements the callback methods for the IGnssXtra
412 * interface.
413 */
414Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800415 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700416 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
417 checkAndClearExceptionFromCallback(env, __FUNCTION__);
418 return Void();
419}
420
421/*
422 * GnssGeofenceCallback class implements the callback methods for the
423 * IGnssGeofence interface.
424 */
425struct GnssGeofenceCallback : public IGnssGeofenceCallback {
426 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
427 Return<void> gnssGeofenceTransitionCb(
428 int32_t geofenceId,
429 const android::hardware::gnss::V1_0::GnssLocation& location,
430 GeofenceTransition transition,
431 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
432 Return<void> gnssGeofenceStatusCb(
433 GeofenceAvailability status,
434 const android::hardware::gnss::V1_0::GnssLocation& location) override;
435 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
436 GeofenceStatus status) override;
437 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
438 GeofenceStatus status) override;
439 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
440 GeofenceStatus status) override;
441 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
442 GeofenceStatus status) override;
443};
444
445Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
446 int32_t geofenceId,
447 const android::hardware::gnss::V1_0::GnssLocation& location,
448 GeofenceTransition transition,
449 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800450 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700451
452 env->CallVoidMethod(mCallbacksObj,
453 method_reportGeofenceTransition,
454 geofenceId,
455 location.gnssLocationFlags,
456 static_cast<jdouble>(location.latitudeDegrees),
457 static_cast<jdouble>(location.longitudeDegrees),
458 static_cast<jdouble>(location.altitudeMeters),
459 static_cast<jfloat>(location.speedMetersPerSec),
460 static_cast<jfloat>(location.bearingDegrees),
461 static_cast<jfloat>(location.accuracyMeters),
462 static_cast<jlong>(location.timestamp),
463 transition,
464 timestamp);
465
466 checkAndClearExceptionFromCallback(env, __FUNCTION__);
467 return Void();
468}
469
470Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
471 GeofenceAvailability status,
472 const android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800473 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700474 env->CallVoidMethod(mCallbacksObj,
475 method_reportGeofenceStatus,
476 status,
477 location.gnssLocationFlags,
478 static_cast<jdouble>(location.latitudeDegrees),
479 static_cast<jdouble>(location.longitudeDegrees),
480 static_cast<jdouble>(location.altitudeMeters),
481 static_cast<jfloat>(location.speedMetersPerSec),
482 static_cast<jfloat>(location.bearingDegrees),
483 static_cast<jfloat>(location.accuracyMeters),
484 static_cast<jlong>(location.timestamp));
485 checkAndClearExceptionFromCallback(env, __FUNCTION__);
486 return Void();
487}
488
489Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
490 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800491 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700492 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
493 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
494 }
495
496 env->CallVoidMethod(mCallbacksObj,
497 method_reportGeofenceAddStatus,
498 geofenceId,
499 status);
500 checkAndClearExceptionFromCallback(env, __FUNCTION__);
501 return Void();
502}
503
504Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
505 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800506 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700507 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
508 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
509 }
510
511 env->CallVoidMethod(mCallbacksObj,
512 method_reportGeofenceRemoveStatus,
513 geofenceId, status);
514 checkAndClearExceptionFromCallback(env, __FUNCTION__);
515 return Void();
516}
517
518Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
519 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800520 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700521 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
522 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
523 }
524
525 env->CallVoidMethod(mCallbacksObj,
526 method_reportGeofencePauseStatus,
527 geofenceId, status);
528 checkAndClearExceptionFromCallback(env, __FUNCTION__);
529 return Void();
530}
531
532Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
533 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800534 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700535 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
536 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
537 }
538
539 env->CallVoidMethod(mCallbacksObj,
540 method_reportGeofenceResumeStatus,
541 geofenceId, status);
542 checkAndClearExceptionFromCallback(env, __FUNCTION__);
543 return Void();
544}
545
546/*
547 * GnssNavigationMessageCallback interface implements the callback methods
548 * required by the IGnssNavigationMessage interface.
549 */
550struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
551 /*
552 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
553 * follow.
554 */
555 Return<void> gnssNavigationMessageCb(
556 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
557};
558
559Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
560 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800561 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700562
563 size_t dataLength = message.data.size();
564
565 std::vector<uint8_t> navigationData = message.data;
566 uint8_t* data = &(navigationData[0]);
567 if (dataLength == 0 || data == NULL) {
568 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
569 dataLength);
570 return Void();
571 }
572
573 JavaObject object(env, "android/location/GnssNavigationMessage");
574 SET(Type, static_cast<int32_t>(message.type));
575 SET(Svid, static_cast<int32_t>(message.svid));
576 SET(MessageId, static_cast<int32_t>(message.messageId));
577 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
578 object.callSetter("setData", data, dataLength);
579 SET(Status, static_cast<int32_t>(message.status));
580
581 jobject navigationMessage = object.get();
582 env->CallVoidMethod(mCallbacksObj,
583 method_reportNavigationMessages,
584 navigationMessage);
585 env->DeleteLocalRef(navigationMessage);
586 return Void();
587}
588
589/*
590 * GnssMeasurementCallback implements the callback methods required for the
591 * GnssMeasurement interface.
592 */
593struct GnssMeasurementCallback : public IGnssMeasurementCallback {
594 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
595 private:
596 jobject translateGnssMeasurement(
597 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
598 jobject translateGnssClock(
599 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
600 jobjectArray translateGnssMeasurements(
601 JNIEnv* env,
602 const IGnssMeasurementCallback::GnssMeasurement* measurements,
603 size_t count);
604 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
605};
606
607
608Return<void> GnssMeasurementCallback::GnssMeasurementCb(
609 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800610 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700611
612 jobject clock;
613 jobjectArray measurementArray;
614
615 clock = translateGnssClock(env, &data.clock);
616 measurementArray = translateGnssMeasurements(
617 env, data.measurements.data(), data.measurementCount);
618 setMeasurementData(env, clock, measurementArray);
619
620 env->DeleteLocalRef(clock);
621 env->DeleteLocalRef(measurementArray);
622 return Void();
623}
624
625jobject GnssMeasurementCallback::translateGnssMeasurement(
626 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800627 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800628
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700629 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700630
631 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800632 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700633 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800634 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700635 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800636 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700637 measurement->receivedSvTimeUncertaintyInNs);
638 SET(Cn0DbHz, measurement->cN0DbHz);
639 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800640 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700641 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800642 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700643 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
644 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800645 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700646 measurement->accumulatedDeltaRangeUncertaintyM);
647
648 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
649 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
650 }
651
652 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
653 SET(CarrierPhase, measurement->carrierPhase);
654 }
655
656 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
657 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
658 }
659
660 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
661
662 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
663 SET(SnrInDb, measurement->snrDb);
664 }
Lifu Tang120480f2016-02-07 18:08:19 -0800665
666 return object.get();
667}
668
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700669jobject GnssMeasurementCallback::translateGnssClock(
670 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
671 JavaObject object(env, "android/location/GnssClock");
672
673 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
674 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
675 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
676 }
677
678 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
679 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
680 }
681
682 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
683 SET(FullBiasNanos, clock->fullBiasNs);
684 }
685
686 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
687 SET(BiasNanos, clock->biasNs);
688 }
689
690 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
691 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
692 }
693
694 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
695 SET(DriftNanosPerSecond, clock->driftNsps);
696 }
697
698 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
699 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
700 }
701
702 SET(TimeNanos, clock->timeNs);
703 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
704
705 return object.get();
706}
707
708jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
709 const IGnssMeasurementCallback::GnssMeasurement*
710 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800711 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700712 return NULL;
713 }
714
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700715 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800716 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800717 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800718 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700719 NULL /* initialElement */);
720
Lifu Tang120480f2016-02-07 18:08:19 -0800721 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700722 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800723 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800724 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800725 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
726 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700727 }
728
Lifu Tang818aa2c2016-02-01 01:52:00 -0800729 env->DeleteLocalRef(gnssMeasurementClass);
730 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700731}
732
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700733void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
734 jobjectArray measurementArray) {
735 jclass gnssMeasurementsEventClass =
736 env->FindClass("android/location/GnssMeasurementsEvent");
737 jmethodID gnssMeasurementsEventCtor =
738 env->GetMethodID(
739 gnssMeasurementsEventClass,
740 "<init>",
741 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800742
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700743 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
744 gnssMeasurementsEventCtor,
745 clock,
746 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800747
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700748 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
749 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800750 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800751 env->DeleteLocalRef(gnssMeasurementsEventClass);
752 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700753}
754
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700755/*
756 * GnssNiCallback implements callback methods required by the IGnssNi interface.
757 */
758struct GnssNiCallback : public IGnssNiCallback {
759 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
760 override;
destradaaea8a8a62014-06-23 18:19:03 -0700761};
762
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700763Return<void> GnssNiCallback::niNotifyCb(
764 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800765 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700766 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
767 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
768
769 if (requestorId && text) {
770 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
771 notification.notificationId, notification.niType,
772 notification.notifyFlags, notification.timeoutSec,
773 notification.defaultResponse, requestorId, text,
774 notification.requestorIdEncoding,
775 notification.notificationIdEncoding);
776 } else {
777 ALOGE("%s: OOM Error\n", __func__);
778 }
779
780 if (requestorId) {
781 env->DeleteLocalRef(requestorId);
782 }
783
784 if (text) {
785 env->DeleteLocalRef(text);
786 }
787 checkAndClearExceptionFromCallback(env, __FUNCTION__);
788 return Void();
789}
790
791/*
792 * AGnssCallback implements callback methods required by the IAGnss interface.
793 */
794struct AGnssCallback : public IAGnssCallback {
795 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
796 Return<void> agnssStatusIpV6Cb(
797 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
798
799 Return<void> agnssStatusIpV4Cb(
800 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
801 private:
802 jbyteArray convertToIpV4(uint32_t ip);
803};
804
805Return<void> AGnssCallback::agnssStatusIpV6Cb(
806 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800807 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700808 jbyteArray byteArray = NULL;
809 bool isSupported = false;
810
811 byteArray = env->NewByteArray(16);
812 if (byteArray != NULL) {
813 env->SetByteArrayRegion(byteArray, 0, 16,
814 (const jbyte*)(agps_status.ipV6Addr.data()));
815 isSupported = true;
816 } else {
817 ALOGE("Unable to allocate byte array for IPv6 address.");
818 }
819
820 IF_ALOGD() {
821 // log the IP for reference in case there is a bogus value pushed by HAL
822 char str[INET6_ADDRSTRLEN];
823 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
824 ALOGD("AGPS IP is v6: %s", str);
825 }
826
827 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
828 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
829 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
830 agps_status.type, agps_status.status, byteArray);
831
832 checkAndClearExceptionFromCallback(env, __FUNCTION__);
833
834 if (byteArray) {
835 env->DeleteLocalRef(byteArray);
836 }
837
838 return Void();
839}
840
841Return<void> AGnssCallback::agnssStatusIpV4Cb(
842 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800843 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700844 jbyteArray byteArray = NULL;
845
846 uint32_t ipAddr = agps_status.ipV4Addr;
847 byteArray = convertToIpV4(ipAddr);
848
849 IF_ALOGD() {
850 /*
851 * log the IP for reference in case there is a bogus value pushed by
852 * HAL.
853 */
854 char str[INET_ADDRSTRLEN];
855 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
856 ALOGD("AGPS IP is v4: %s", str);
857 }
858
859 jsize byteArrayLength =
860 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
861 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
862 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
863 agps_status.type, agps_status.status, byteArray);
864
865 checkAndClearExceptionFromCallback(env, __FUNCTION__);
866
867 if (byteArray) {
868 env->DeleteLocalRef(byteArray);
869 }
870 return Void();
871}
872
873jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
874 if (INADDR_NONE == ip) {
875 return NULL;
876 }
877
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800878 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700879 jbyteArray byteArray = env->NewByteArray(4);
880 if (byteArray == NULL) {
881 ALOGE("Unable to allocate byte array for IPv4 address");
882 return NULL;
883 }
884
885 jbyte ipv4[4];
886 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
887 memcpy(ipv4, &ip, sizeof(ipv4));
888 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
889 return byteArray;
890}
891
892/*
893 * AGnssRilCallback implements the callback methods required by the AGnssRil
894 * interface.
895 */
896struct AGnssRilCallback : IAGnssRilCallback {
897 Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override;
898 Return<void> requestRefLocCb() override;
899};
900
901Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800902 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700903 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
904 checkAndClearExceptionFromCallback(env, __FUNCTION__);
905 return Void();
906}
907
908Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800909 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700910 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
911 checkAndClearExceptionFromCallback(env, __FUNCTION__);
912 return Void();
913}
914
915static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
916 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
917 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
918 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
919 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
920 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
921 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
922 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
923 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
924 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
925 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
926 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
927 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
928 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
929 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
930 "(IIDDDFFFJIJ)V");
931 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
932 "(IIDDDFFFJ)V");
933 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
934 "(II)V");
935 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
936 "(II)V");
937 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
938 "(II)V");
939 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
940 "(II)V");
941 method_reportMeasurementData = env->GetMethodID(
942 clazz,
943 "reportMeasurementData",
944 "(Landroid/location/GnssMeasurementsEvent;)V");
945 method_reportNavigationMessages = env->GetMethodID(
946 clazz,
947 "reportNavigationMessage",
948 "(Landroid/location/GnssNavigationMessage;)V");
949
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800950 /*
951 * Save a pointer to JVM.
952 */
953 jint jvmStatus = env->GetJavaVM(&sJvm);
954 if (jvmStatus != JNI_OK) {
955 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
956 }
957
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700958 // TODO(b/31632518)
959 gnssHal = IGnss::getService("gnss");
960 if (gnssHal != nullptr) {
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100961 auto gnssXtra = gnssHal->getExtensionXtra();
962 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700963 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100964 } else {
965 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700966 }
967
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100968 auto gnssRil = gnssHal->getExtensionAGnssRil();
969 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700970 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100971 } else {
972 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700973 }
974
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100975 auto gnssAgnss = gnssHal->getExtensionAGnss();
976 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700977 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100978 } else {
979 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700980 }
981
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100982 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
983 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700984 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100985 } else {
986 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700987 }
988
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100989 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
990 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100992 } else {
993 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700994 }
995
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100996 auto gnssDebug = gnssHal->getExtensionGnssDebug();
997 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700998 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100999 } else {
1000 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001001 }
1002
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001003 auto gnssNi = gnssHal->getExtensionGnssNi();
1004 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001005 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001006 } else {
1007 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001008 }
1009
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001010 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1011 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001012 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001013 } else {
1014 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001015 }
1016
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001017 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1018 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001019 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001020 } else {
1021 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001022 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001023 } else {
1024 ALOGE("Unable to get GPS service\n");
1025 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001026}
1027
1028static jboolean android_location_GnssLocationProvider_is_supported(
1029 JNIEnv* /* env */, jclass /* clazz */) {
1030 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1031}
1032
1033static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1034 JNIEnv* /* env */, jclass /* clazz */) {
1035 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1036}
1037
1038static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1039 JNIEnv* /* env */, jclass /* jclazz */) {
1040 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1041}
1042
1043static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1044 /*
1045 * This must be set before calling into the HAL library.
1046 */
1047 if (!mCallbacksObj)
1048 mCallbacksObj = env->NewGlobalRef(obj);
1049
1050 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1051 /*
1052 * Fail if the main interface fails to initialize
1053 */
1054 if (gnssHal == nullptr) {
1055 ALOGE("Unable to Initialize GNSS HAL\n");
1056 return JNI_FALSE;
1057 }
1058
1059 auto result = gnssHal->setCallback(gnssCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001060 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001061 ALOGE("SetCallback for Gnss Interface fails\n");
1062 return JNI_FALSE;
1063 }
1064
1065 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1066 if (gnssXtraIface == nullptr) {
1067 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001068 } else {
1069 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001070 if ((!result) || (!result.isOk())) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001071 gnssXtraIface = nullptr;
1072 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1073 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 }
1075
1076 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1077 if (agnssIface != nullptr) {
1078 agnssIface->setCallback(aGnssCbIface);
1079 } else {
1080 ALOGE("Unable to Initialize AGnss interface\n");
1081 }
1082
1083 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1084 if (gnssGeofencingIface != nullptr) {
1085 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1086 } else {
1087 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1088 }
1089
1090 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1091 if (gnssNiCbIface != nullptr) {
1092 gnssNiIface->setCallback(gnssNiCbIface);
1093 } else {
1094 ALOGE("Unable to initialize GNSS NI interface\n");
1095 }
1096
1097 return JNI_TRUE;
1098}
1099
1100static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1101 if (gnssHal != nullptr) {
1102 gnssHal->cleanup();
1103 }
1104}
1105
1106static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1107 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1108 jint preferred_time) {
1109 if (gnssHal != nullptr) {
1110 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1111 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1112 min_interval,
1113 preferred_accuracy,
1114 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001115 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001116 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1117 return JNI_FALSE;
1118 } else {
1119 return result;
1120 }
1121 } else {
1122 return JNI_FALSE;
1123 }
1124}
1125
1126static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1127 if (gnssHal != nullptr) {
1128 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001129 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001130 return JNI_FALSE;
1131 } else {
1132 return result;
1133 }
1134 } else {
1135 return JNI_FALSE;
1136 }
1137}
1138
1139static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1140 if (gnssHal != nullptr) {
1141 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001142 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001143 return JNI_FALSE;
1144 } else {
1145 return result;
1146 }
1147 } else {
1148 return JNI_FALSE;
1149 }
1150}
1151static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1152 jobject /* obj */,
1153 jint flags) {
1154 if (gnssHal != nullptr) {
1155 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001156 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001157 ALOGE("Error in deleting aiding data");
1158 }
1159 }
1160}
1161
1162/*
1163 * This enum is used by the read_sv_status method to combine the svid,
1164 * constellation and svFlag fields.
1165 */
1166enum ShiftWidth: uint8_t {
1167 SVID_SHIFT_WIDTH = 7,
1168 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1169};
1170
1171static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1172 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
1173 jfloatArray azumArray) {
1174 /*
1175 * This method should only be called from within a call to reportSvStatus.
1176 */
1177 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1178 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1179 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1180 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
1181
1182 /*
1183 * Read GNSS SV info.
1184 */
1185 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1186 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1187 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1188 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1189 static_cast<uint32_t>(info.svFlag);
1190 cn0s[i] = info.cN0Dbhz;
1191 elev[i] = info.elevationDegrees;
1192 azim[i] = info.azimuthDegrees;
1193 }
1194
1195 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1196 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1197 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1198 env->ReleaseFloatArrayElements(azumArray, azim, 0);
1199 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1200}
1201
1202static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1203 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1204 IAGnssRil::AGnssRefLocation location;
1205
1206 if (agnssRilIface == nullptr) {
1207 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1208 return;
1209 }
1210
1211 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1212 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1213 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1214 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1215 location.cellID.mcc = mcc;
1216 location.cellID.mnc = mnc;
1217 location.cellID.lac = lac;
1218 location.cellID.cid = cid;
1219 break;
1220 default:
1221 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1222 return;
1223 break;
1224 }
1225
1226 agnssRilIface->setRefLocation(location);
1227}
1228
1229static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1230 jint type, jstring setid_string) {
1231 if (agnssRilIface == nullptr) {
1232 ALOGE("no AGPS RIL interface in agps_set_id");
1233 return;
1234 }
1235
1236 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1237 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1238 env->ReleaseStringUTFChars(setid_string, setid);
1239}
1240
1241static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1242 jbyteArray nmeaArray, jint buffer_size) {
1243 // this should only be called from within a call to reportNmea
1244 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1245 int length = GnssCallback::sNmeaStringLength;
1246 if (length > buffer_size)
1247 length = buffer_size;
1248 memcpy(nmea, GnssCallback::sNmeaString, length);
1249 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1250 return (jint) length;
1251}
1252
1253static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1254 jlong time, jlong timeReference, jint uncertainty) {
1255 if (gnssHal != nullptr) {
1256 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001257 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001258 ALOGE("%s: Gnss injectTime() failed", __func__);
1259 }
1260 }
1261}
1262
1263static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1264 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1265 if (gnssHal != nullptr) {
1266 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001267 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001268 ALOGE("%s: Gnss injectLocation() failed", __func__);
1269 }
1270 }
1271}
1272
1273static jboolean android_location_GnssLocationProvider_supports_xtra(
1274 JNIEnv* /* env */, jobject /* obj */) {
1275 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1276}
1277
1278static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1279 jbyteArray data, jint length) {
1280 if (gnssXtraIface == nullptr) {
1281 ALOGE("XTRA Interface not supported");
1282 return;
1283 }
1284
1285 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1286 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1287 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1288}
1289
1290static void android_location_GnssLocationProvider_agps_data_conn_open(
1291 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1292 if (agnssIface == nullptr) {
1293 ALOGE("no AGPS interface in agps_data_conn_open");
1294 return;
1295 }
1296 if (apn == NULL) {
1297 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1298 return;
1299 }
1300
1301 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1302
1303 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001304 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001305 ALOGE("%s: Failed to set APN and its IP type", __func__);
1306 }
1307 env->ReleaseStringUTFChars(apn, apnStr);
1308}
1309
1310static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1311 jobject /* obj */) {
1312 if (agnssIface == nullptr) {
1313 ALOGE("%s: AGPS interface not supported", __func__);
1314 return;
1315 }
1316
1317 auto result = agnssIface->dataConnClosed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001318 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001319 ALOGE("%s: Failed to close AGnss data connection", __func__);
1320 }
1321}
1322
1323static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1324 jobject /* obj */) {
1325 if (agnssIface == nullptr) {
1326 ALOGE("%s: AGPS interface not supported", __func__);
1327 return;
1328 }
1329
1330 auto result = agnssIface->dataConnFailed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001331 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001332 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1333 }
1334}
1335
1336static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1337 jint type, jstring hostname, jint port) {
1338 if (agnssIface == nullptr) {
1339 ALOGE("no AGPS interface in set_agps_server");
1340 return;
1341 }
1342
1343 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1344 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1345 c_hostname,
1346 port);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001347 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001348 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1349 }
1350
1351 env->ReleaseStringUTFChars(hostname, c_hostname);
1352}
1353
1354static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1355 jobject /* obj */, jint notifId, jint response) {
1356 if (gnssNiIface == nullptr) {
1357 ALOGE("no NI interface in send_ni_response");
1358 return;
1359 }
1360
1361 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1362}
1363
1364static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1365 jobject /* obj */) {
1366 jstring result = NULL;
1367 /*
1368 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1369 */
1370 if (gnssDebugIface != nullptr) {
1371 IGnssDebug::DebugData data;
1372 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1373 data = debugData;
1374 });
1375
1376 std::stringstream internalState;
1377 if (data.position.valid) {
1378 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1379 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1380 << ", altitudeMeters: " << data.position.altitudeMeters
1381 << ", accuracyMeters: " << data.position.accuracyMeters
1382 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1383 }
1384
1385 if (data.time.valid) {
1386 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1387 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1388 }
1389
1390 if (data.satelliteDataArray.size() != 0) {
1391 internalState << "Satellite Data:: ";
1392 }
1393
1394 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1395 internalState << "svid: " << data.satelliteDataArray[i].svid
1396 << ", constellation: "
1397 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1398 << ", ephemerisType: "
1399 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1400 << ", ephemerisAgeSeconds: "
1401 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1402 }
1403 result = env->NewStringUTF(internalState.str().c_str());
1404 }
1405 return result;
1406}
1407
1408static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1409 jobject /* obj */,
1410 jboolean connected,
1411 jint type,
1412 jboolean roaming,
1413 jboolean available,
1414 jstring extraInfo,
1415 jstring apn) {
1416 if (agnssRilIface != nullptr) {
1417 auto result = agnssRilIface->updateNetworkState(connected,
1418 static_cast<IAGnssRil::NetworkType>(type),
1419 roaming);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001420 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001421 ALOGE("updateNetworkState failed");
1422 }
1423
1424 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1425 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001426 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001427 ALOGE("updateNetworkAvailability failed");
1428 }
1429
1430 env->ReleaseStringUTFChars(apn, c_apn);
1431 } else {
1432 ALOGE("AGnssRilInterface does not exist");
1433 }
1434}
1435
1436static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1437 JNIEnv* /* env */, jobject /* obj */) {
1438 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1439}
1440
1441static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1442 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1443 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1444 jint unknown_timer) {
1445 if (gnssGeofencingIface != nullptr) {
1446 auto result = gnssGeofencingIface->addGeofence(
1447 geofenceId, latitude, longitude, radius,
1448 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1449 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001450 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001451 } else {
1452 ALOGE("Geofence Interface not available");
1453 }
1454 return JNI_FALSE;
1455}
1456
1457static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1458 jobject /* obj */, jint geofenceId) {
1459 if (gnssGeofencingIface != nullptr) {
1460 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001461 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001462 } else {
1463 ALOGE("Geofence interface not available");
1464 }
1465 return JNI_FALSE;
1466}
1467
1468static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1469 jobject /* obj */, jint geofenceId) {
1470 if (gnssGeofencingIface != nullptr) {
1471 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001472 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001473 } else {
1474 ALOGE("Geofence interface not available");
1475 }
1476 return JNI_FALSE;
1477}
1478
1479static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1480 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1481 if (gnssGeofencingIface != nullptr) {
1482 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001483 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001484 } else {
1485 ALOGE("Geofence interface not available");
1486 }
1487 return JNI_FALSE;
1488}
1489
Lifu Tang30f95a72016-01-07 23:20:38 -08001490static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001491 JNIEnv* env, jclass clazz) {
1492 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001493 return JNI_TRUE;
1494 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001495
destradaaea8a8a62014-06-23 18:19:03 -07001496 return JNI_FALSE;
1497}
1498
Lifu Tang30f95a72016-01-07 23:20:38 -08001499static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001500 JNIEnv* env,
1501 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001502 if (gnssMeasurementIface == nullptr) {
1503 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001504 return JNI_FALSE;
1505 }
1506
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001507 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1508 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1509 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1510 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1511 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001512 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001513 } else {
1514 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001515 }
1516
1517 return JNI_TRUE;
1518}
1519
Lifu Tang30f95a72016-01-07 23:20:38 -08001520static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001521 JNIEnv* env,
1522 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001523 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001524 ALOGE("Measurement interface not available");
1525 return JNI_FALSE;
1526 }
1527
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001528 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001529 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001530}
1531
Lifu Tang30f95a72016-01-07 23:20:38 -08001532static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001533 JNIEnv* env,
1534 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001535 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001536 return JNI_TRUE;
1537 }
1538 return JNI_FALSE;
1539}
1540
Lifu Tang30f95a72016-01-07 23:20:38 -08001541static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001542 JNIEnv* env,
1543 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001544 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001545 ALOGE("Navigation Message interface is not available.");
1546 return JNI_FALSE;
1547 }
1548
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001549 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1550 new GnssNavigationMessageCallback();
1551 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1552 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1553
1554 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1555 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001556 return JNI_FALSE;
1557 }
1558
1559 return JNI_TRUE;
1560}
1561
Lifu Tang30f95a72016-01-07 23:20:38 -08001562static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001563 JNIEnv* env,
1564 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001565 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001566 ALOGE("Navigation Message interface is not available.");
1567 return JNI_FALSE;
1568 }
1569
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001570 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001571 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001572}
1573
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001574static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1575 jobject,
1576 jint emergencySuplPdn) {
1577 if (gnssConfigurationIface == nullptr) {
1578 ALOGE("no GNSS configuration interface available");
1579 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001580 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001581
1582 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001583 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001584 return result;
1585 } else {
1586 return JNI_FALSE;
1587 }
1588}
1589
1590static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1591 jobject,
1592 jint version) {
1593 if (gnssConfigurationIface == nullptr) {
1594 ALOGE("no GNSS configuration interface available");
1595 return JNI_FALSE;
1596 }
1597 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001598 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001599 return result;
1600 } else {
1601 return JNI_FALSE;
1602 }
1603}
1604
1605static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1606 jobject,
1607 jint suplEs) {
1608 if (gnssConfigurationIface == nullptr) {
1609 ALOGE("no GNSS configuration interface available");
1610 return JNI_FALSE;
1611 }
1612
1613 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001614 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001615 return result;
1616 } else {
1617 return JNI_FALSE;
1618 }
1619}
1620
1621static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1622 jobject,
1623 jint mode) {
1624 if (gnssConfigurationIface == nullptr) {
1625 ALOGE("no GNSS configuration interface available");
1626 return JNI_FALSE;
1627 }
1628
1629 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001630 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001631 return result;
1632 } else {
1633 return JNI_FALSE;
1634 }
1635}
1636
1637static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1638 jobject,
1639 jint gpsLock) {
1640 if (gnssConfigurationIface == nullptr) {
1641 ALOGE("no GNSS configuration interface available");
1642 return JNI_FALSE;
1643 }
1644
1645 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001646 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647 return result;
1648 } else {
1649 return JNI_FALSE;
1650 }
1651}
1652
1653static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1654 jobject,
1655 jint lppProfile) {
1656 if (gnssConfigurationIface == nullptr) {
1657 ALOGE("no GNSS configuration interface available");
1658 return JNI_FALSE;
1659 }
1660
1661 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1662
Steven Morelandd002a8b2017-01-03 17:18:24 -08001663 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001664 return result;
1665 } else {
1666 return JNI_FALSE;
1667 }
1668}
1669
1670static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1671 jobject,
1672 jint gnssPosProtocol) {
1673 if (gnssConfigurationIface == nullptr) {
1674 ALOGE("no GNSS configuration interface available");
1675 return JNI_FALSE;
1676 }
1677
1678 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001679 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 return result;
1681 } else {
1682 return JNI_FALSE;
1683 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001684}
1685
Daniel Micay76f6a862015-09-19 17:31:01 -04001686static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001688 {"class_init_native", "()V", reinterpret_cast<void *>(
1689 android_location_GnssLocationProvider_class_init_native)},
1690 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1691 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001692 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001694 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001695 reinterpret_cast<void *>(
1696 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1697 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1698 {"native_cleanup", "()V", reinterpret_cast<void *>(
1699 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001700 {"native_set_position_mode",
1701 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001702 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1703 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1704 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001705 {"native_delete_aiding_data",
1706 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001707 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001708 {"native_read_sv_status",
Lifu Tang120480f2016-02-07 18:08:19 -08001709 "([I[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001710 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1711 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1712 android_location_GnssLocationProvider_read_nmea)},
1713 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1714 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001715 {"native_inject_location",
1716 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1718 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1719 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001720 {"native_inject_xtra_data",
1721 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001722 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001723 {"native_agps_data_conn_open",
1724 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001725 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001726 {"native_agps_data_conn_closed",
1727 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001728 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001729 {"native_agps_data_conn_failed",
1730 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001731 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001732 {"native_agps_set_id",
1733 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001734 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001735 {"native_agps_set_ref_location_cellid",
1736 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001737 reinterpret_cast<void *>(
1738 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001739 {"native_set_agps_server",
1740 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001741 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001742 {"native_send_ni_response",
1743 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001744 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001745 {"native_get_internal_state",
1746 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001747 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001748 {"native_update_network_state",
1749 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001751 {"native_is_geofence_supported",
1752 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001753 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001754 {"native_add_geofence",
1755 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001756 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001757 {"native_remove_geofence",
1758 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001759 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1760 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1761 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001762 {"native_resume_geofence",
1763 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001764 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001765 {"native_is_measurement_supported",
1766 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001767 reinterpret_cast<void *>(
1768 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001769 {"native_start_measurement_collection",
1770 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001771 reinterpret_cast<void *>(
1772 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001773 {"native_stop_measurement_collection",
1774 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001775 reinterpret_cast<void *>(
1776 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001777 {"native_is_navigation_message_supported",
1778 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001779 reinterpret_cast<void *>(
1780 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001781 {"native_start_navigation_message_collection",
1782 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001783 reinterpret_cast<void *>(
1784 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001785 {"native_stop_navigation_message_collection",
1786 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001787 reinterpret_cast<void *>(
1788 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1789 {"native_set_supl_es",
1790 "(I)Z",
1791 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1792 {"native_set_supl_version",
1793 "(I)Z",
1794 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1795 {"native_set_supl_mode",
1796 "(I)Z",
1797 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1798 {"native_set_lpp_profile",
1799 "(I)Z",
1800 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1801 {"native_set_gnss_pos_protocol_select",
1802 "(I)Z",
1803 reinterpret_cast<void *>(
1804 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1805 {"native_set_gps_lock",
1806 "(I)Z",
1807 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1808 {"native_set_emergency_supl_pdn",
1809 "(I)Z",
1810 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811};
1812
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001813int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001814 return jniRegisterNativeMethods(
1815 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001816 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001817 sMethods,
1818 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819}
1820
1821} /* namespace android */