blob: 5a20bed04d6e916a00d596b06fe24e81c865f30e [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),
gomo4402af62017-01-11 13:20:13 -0800321 static_cast<jfloat>(location.horizontalAccuracyMeters),
322 static_cast<jfloat>(location.verticalAccuracyMeters),
323 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
324 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700325 static_cast<jlong>(location.timestamp));
326 checkAndClearExceptionFromCallback(env, __FUNCTION__);
327 return Void();
328}
329
330Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800331 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700332 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
333 checkAndClearExceptionFromCallback(env, __FUNCTION__);
334 return Void();
335}
336
337Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800338 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700339
340 sGnssSvListSize = svStatus.numSvs;
341 if (sGnssSvListSize > static_cast<uint32_t>(
342 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
343 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
344 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
345 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800346 }
347
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700348 // Copy GNSS SV info into sGnssSvList, if any.
349 if (svStatus.numSvs > 0) {
350 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800351 }
destradaaea8a8a62014-06-23 18:19:03 -0700352
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700353 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
354 checkAndClearExceptionFromCallback(env, __FUNCTION__);
355 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700356}
357
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700358Return<void> GnssCallback::gnssNmeaCb(
359 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800360 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700361 /*
362 * The Java code will call back to read these values.
363 * We do this to avoid creating unnecessary String objects.
364 */
365 sNmeaString = nmea.c_str();
366 sNmeaStringLength = nmea.size();
367
368 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
369 checkAndClearExceptionFromCallback(env, __FUNCTION__);
370 return Void();
371}
372
373Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
374 ALOGD("%s: %du\n", __func__, capabilities);
375
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800376 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700377 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
378 checkAndClearExceptionFromCallback(env, __FUNCTION__);
379 return Void();
380}
381
382Return<void> GnssCallback::gnssAcquireWakelockCb() {
383 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
384 return Void();
385}
386
387Return<void> GnssCallback::gnssReleaseWakelockCb() {
388 release_wake_lock(WAKE_LOCK_NAME);
389 return Void();
390}
391
392Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800393 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700394 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
395 checkAndClearExceptionFromCallback(env, __FUNCTION__);
396 return Void();
397}
398
399Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
400 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
401
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800402 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
404 info.yearOfHw);
405 checkAndClearExceptionFromCallback(env, __FUNCTION__);
406 return Void();
407}
408
409class GnssXtraCallback : public IGnssXtraCallback {
410 Return<void> downloadRequestCb() override;
411};
412
413/*
414 * GnssXtraCallback class implements the callback methods for the IGnssXtra
415 * interface.
416 */
417Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800418 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700419 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
420 checkAndClearExceptionFromCallback(env, __FUNCTION__);
421 return Void();
422}
423
424/*
425 * GnssGeofenceCallback class implements the callback methods for the
426 * IGnssGeofence interface.
427 */
428struct GnssGeofenceCallback : public IGnssGeofenceCallback {
429 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
430 Return<void> gnssGeofenceTransitionCb(
431 int32_t geofenceId,
432 const android::hardware::gnss::V1_0::GnssLocation& location,
433 GeofenceTransition transition,
434 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
435 Return<void> gnssGeofenceStatusCb(
436 GeofenceAvailability status,
437 const android::hardware::gnss::V1_0::GnssLocation& location) override;
438 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
439 GeofenceStatus status) override;
440 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
441 GeofenceStatus status) override;
442 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
443 GeofenceStatus status) override;
444 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
445 GeofenceStatus status) override;
446};
447
448Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
449 int32_t geofenceId,
450 const android::hardware::gnss::V1_0::GnssLocation& location,
451 GeofenceTransition transition,
452 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800453 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700454
455 env->CallVoidMethod(mCallbacksObj,
456 method_reportGeofenceTransition,
457 geofenceId,
458 location.gnssLocationFlags,
459 static_cast<jdouble>(location.latitudeDegrees),
460 static_cast<jdouble>(location.longitudeDegrees),
461 static_cast<jdouble>(location.altitudeMeters),
462 static_cast<jfloat>(location.speedMetersPerSec),
463 static_cast<jfloat>(location.bearingDegrees),
gomo4402af62017-01-11 13:20:13 -0800464 static_cast<jfloat>(location.horizontalAccuracyMeters),
465 static_cast<jfloat>(location.verticalAccuracyMeters),
466 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
467 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700468 static_cast<jlong>(location.timestamp),
469 transition,
470 timestamp);
471
472 checkAndClearExceptionFromCallback(env, __FUNCTION__);
473 return Void();
474}
475
476Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
477 GeofenceAvailability status,
478 const android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800479 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700480 env->CallVoidMethod(mCallbacksObj,
481 method_reportGeofenceStatus,
482 status,
483 location.gnssLocationFlags,
484 static_cast<jdouble>(location.latitudeDegrees),
485 static_cast<jdouble>(location.longitudeDegrees),
486 static_cast<jdouble>(location.altitudeMeters),
487 static_cast<jfloat>(location.speedMetersPerSec),
488 static_cast<jfloat>(location.bearingDegrees),
gomo4402af62017-01-11 13:20:13 -0800489 static_cast<jfloat>(location.horizontalAccuracyMeters),
490 static_cast<jfloat>(location.verticalAccuracyMeters),
491 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
492 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700493 static_cast<jlong>(location.timestamp));
494 checkAndClearExceptionFromCallback(env, __FUNCTION__);
495 return Void();
496}
497
498Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
499 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800500 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700501 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
502 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
503 }
504
505 env->CallVoidMethod(mCallbacksObj,
506 method_reportGeofenceAddStatus,
507 geofenceId,
508 status);
509 checkAndClearExceptionFromCallback(env, __FUNCTION__);
510 return Void();
511}
512
513Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
514 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800515 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700516 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
517 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
518 }
519
520 env->CallVoidMethod(mCallbacksObj,
521 method_reportGeofenceRemoveStatus,
522 geofenceId, status);
523 checkAndClearExceptionFromCallback(env, __FUNCTION__);
524 return Void();
525}
526
527Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
528 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800529 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700530 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
531 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
532 }
533
534 env->CallVoidMethod(mCallbacksObj,
535 method_reportGeofencePauseStatus,
536 geofenceId, status);
537 checkAndClearExceptionFromCallback(env, __FUNCTION__);
538 return Void();
539}
540
541Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
542 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800543 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700544 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
545 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
546 }
547
548 env->CallVoidMethod(mCallbacksObj,
549 method_reportGeofenceResumeStatus,
550 geofenceId, status);
551 checkAndClearExceptionFromCallback(env, __FUNCTION__);
552 return Void();
553}
554
555/*
556 * GnssNavigationMessageCallback interface implements the callback methods
557 * required by the IGnssNavigationMessage interface.
558 */
559struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
560 /*
561 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
562 * follow.
563 */
564 Return<void> gnssNavigationMessageCb(
565 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
566};
567
568Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
569 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800570 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700571
572 size_t dataLength = message.data.size();
573
574 std::vector<uint8_t> navigationData = message.data;
575 uint8_t* data = &(navigationData[0]);
576 if (dataLength == 0 || data == NULL) {
577 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
578 dataLength);
579 return Void();
580 }
581
582 JavaObject object(env, "android/location/GnssNavigationMessage");
583 SET(Type, static_cast<int32_t>(message.type));
584 SET(Svid, static_cast<int32_t>(message.svid));
585 SET(MessageId, static_cast<int32_t>(message.messageId));
586 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
587 object.callSetter("setData", data, dataLength);
588 SET(Status, static_cast<int32_t>(message.status));
589
590 jobject navigationMessage = object.get();
591 env->CallVoidMethod(mCallbacksObj,
592 method_reportNavigationMessages,
593 navigationMessage);
594 env->DeleteLocalRef(navigationMessage);
595 return Void();
596}
597
598/*
599 * GnssMeasurementCallback implements the callback methods required for the
600 * GnssMeasurement interface.
601 */
602struct GnssMeasurementCallback : public IGnssMeasurementCallback {
603 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
604 private:
605 jobject translateGnssMeasurement(
606 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
607 jobject translateGnssClock(
608 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
609 jobjectArray translateGnssMeasurements(
610 JNIEnv* env,
611 const IGnssMeasurementCallback::GnssMeasurement* measurements,
612 size_t count);
613 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
614};
615
616
617Return<void> GnssMeasurementCallback::GnssMeasurementCb(
618 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800619 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700620
621 jobject clock;
622 jobjectArray measurementArray;
623
624 clock = translateGnssClock(env, &data.clock);
625 measurementArray = translateGnssMeasurements(
626 env, data.measurements.data(), data.measurementCount);
627 setMeasurementData(env, clock, measurementArray);
628
629 env->DeleteLocalRef(clock);
630 env->DeleteLocalRef(measurementArray);
631 return Void();
632}
633
634jobject GnssMeasurementCallback::translateGnssMeasurement(
635 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800636 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800637
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700638 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700639
640 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800641 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700642 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800643 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700644 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800645 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700646 measurement->receivedSvTimeUncertaintyInNs);
647 SET(Cn0DbHz, measurement->cN0DbHz);
648 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800649 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700650 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800651 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700652 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
653 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800654 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700655 measurement->accumulatedDeltaRangeUncertaintyM);
656
657 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
658 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
659 }
660
661 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
662 SET(CarrierPhase, measurement->carrierPhase);
663 }
664
665 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
666 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
667 }
668
669 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
670
671 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
672 SET(SnrInDb, measurement->snrDb);
673 }
Lifu Tang120480f2016-02-07 18:08:19 -0800674
gomo4402af62017-01-11 13:20:13 -0800675 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
676 SET(AgcLevelDb, measurement->agcLevelDb);
677 }
678
Lifu Tang120480f2016-02-07 18:08:19 -0800679 return object.get();
680}
681
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700682jobject GnssMeasurementCallback::translateGnssClock(
683 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
684 JavaObject object(env, "android/location/GnssClock");
685
686 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
687 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
688 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
689 }
690
691 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
692 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
693 }
694
695 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
696 SET(FullBiasNanos, clock->fullBiasNs);
697 }
698
699 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
700 SET(BiasNanos, clock->biasNs);
701 }
702
703 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
704 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
705 }
706
707 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
708 SET(DriftNanosPerSecond, clock->driftNsps);
709 }
710
711 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
712 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
713 }
714
715 SET(TimeNanos, clock->timeNs);
716 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
717
718 return object.get();
719}
720
721jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
722 const IGnssMeasurementCallback::GnssMeasurement*
723 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800724 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700725 return NULL;
726 }
727
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700728 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800729 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800730 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800731 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700732 NULL /* initialElement */);
733
Lifu Tang120480f2016-02-07 18:08:19 -0800734 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700735 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800736 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800737 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800738 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
739 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700740 }
741
Lifu Tang818aa2c2016-02-01 01:52:00 -0800742 env->DeleteLocalRef(gnssMeasurementClass);
743 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700744}
745
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700746void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
747 jobjectArray measurementArray) {
748 jclass gnssMeasurementsEventClass =
749 env->FindClass("android/location/GnssMeasurementsEvent");
750 jmethodID gnssMeasurementsEventCtor =
751 env->GetMethodID(
752 gnssMeasurementsEventClass,
753 "<init>",
754 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800755
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700756 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
757 gnssMeasurementsEventCtor,
758 clock,
759 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800760
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700761 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
762 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800763 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800764 env->DeleteLocalRef(gnssMeasurementsEventClass);
765 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700766}
767
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700768/*
769 * GnssNiCallback implements callback methods required by the IGnssNi interface.
770 */
771struct GnssNiCallback : public IGnssNiCallback {
772 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
773 override;
destradaaea8a8a62014-06-23 18:19:03 -0700774};
775
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700776Return<void> GnssNiCallback::niNotifyCb(
777 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800778 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700779 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
780 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
781
782 if (requestorId && text) {
783 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
784 notification.notificationId, notification.niType,
785 notification.notifyFlags, notification.timeoutSec,
786 notification.defaultResponse, requestorId, text,
787 notification.requestorIdEncoding,
788 notification.notificationIdEncoding);
789 } else {
790 ALOGE("%s: OOM Error\n", __func__);
791 }
792
793 if (requestorId) {
794 env->DeleteLocalRef(requestorId);
795 }
796
797 if (text) {
798 env->DeleteLocalRef(text);
799 }
800 checkAndClearExceptionFromCallback(env, __FUNCTION__);
801 return Void();
802}
803
804/*
805 * AGnssCallback implements callback methods required by the IAGnss interface.
806 */
807struct AGnssCallback : public IAGnssCallback {
808 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
809 Return<void> agnssStatusIpV6Cb(
810 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
811
812 Return<void> agnssStatusIpV4Cb(
813 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
814 private:
815 jbyteArray convertToIpV4(uint32_t ip);
816};
817
818Return<void> AGnssCallback::agnssStatusIpV6Cb(
819 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800820 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700821 jbyteArray byteArray = NULL;
822 bool isSupported = false;
823
824 byteArray = env->NewByteArray(16);
825 if (byteArray != NULL) {
826 env->SetByteArrayRegion(byteArray, 0, 16,
827 (const jbyte*)(agps_status.ipV6Addr.data()));
828 isSupported = true;
829 } else {
830 ALOGE("Unable to allocate byte array for IPv6 address.");
831 }
832
833 IF_ALOGD() {
834 // log the IP for reference in case there is a bogus value pushed by HAL
835 char str[INET6_ADDRSTRLEN];
836 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
837 ALOGD("AGPS IP is v6: %s", str);
838 }
839
840 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
841 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
842 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
843 agps_status.type, agps_status.status, byteArray);
844
845 checkAndClearExceptionFromCallback(env, __FUNCTION__);
846
847 if (byteArray) {
848 env->DeleteLocalRef(byteArray);
849 }
850
851 return Void();
852}
853
854Return<void> AGnssCallback::agnssStatusIpV4Cb(
855 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800856 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700857 jbyteArray byteArray = NULL;
858
859 uint32_t ipAddr = agps_status.ipV4Addr;
860 byteArray = convertToIpV4(ipAddr);
861
862 IF_ALOGD() {
863 /*
864 * log the IP for reference in case there is a bogus value pushed by
865 * HAL.
866 */
867 char str[INET_ADDRSTRLEN];
868 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
869 ALOGD("AGPS IP is v4: %s", str);
870 }
871
872 jsize byteArrayLength =
873 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
874 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
875 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
876 agps_status.type, agps_status.status, byteArray);
877
878 checkAndClearExceptionFromCallback(env, __FUNCTION__);
879
880 if (byteArray) {
881 env->DeleteLocalRef(byteArray);
882 }
883 return Void();
884}
885
886jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
887 if (INADDR_NONE == ip) {
888 return NULL;
889 }
890
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800891 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700892 jbyteArray byteArray = env->NewByteArray(4);
893 if (byteArray == NULL) {
894 ALOGE("Unable to allocate byte array for IPv4 address");
895 return NULL;
896 }
897
898 jbyte ipv4[4];
899 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
900 memcpy(ipv4, &ip, sizeof(ipv4));
901 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
902 return byteArray;
903}
904
905/*
906 * AGnssRilCallback implements the callback methods required by the AGnssRil
907 * interface.
908 */
909struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800910 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700911 Return<void> requestRefLocCb() override;
912};
913
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800914Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800915 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700916 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
917 checkAndClearExceptionFromCallback(env, __FUNCTION__);
918 return Void();
919}
920
921Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800922 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700923 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
924 checkAndClearExceptionFromCallback(env, __FUNCTION__);
925 return Void();
926}
927
928static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
gomo4402af62017-01-11 13:20:13 -0800929 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFFFFJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700930 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
931 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
932 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
933 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
934 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
935 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
936 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
937 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
938 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
939 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
940 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
941 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
942 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
gomo4402af62017-01-11 13:20:13 -0800943 "(IIDDDFFFFFFJIJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700944 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
gomo4402af62017-01-11 13:20:13 -0800945 "(IIDDDFFFFFFJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700946 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
947 "(II)V");
948 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
949 "(II)V");
950 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
951 "(II)V");
952 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
953 "(II)V");
954 method_reportMeasurementData = env->GetMethodID(
955 clazz,
956 "reportMeasurementData",
957 "(Landroid/location/GnssMeasurementsEvent;)V");
958 method_reportNavigationMessages = env->GetMethodID(
959 clazz,
960 "reportNavigationMessage",
961 "(Landroid/location/GnssNavigationMessage;)V");
962
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800963 /*
964 * Save a pointer to JVM.
965 */
966 jint jvmStatus = env->GetJavaVM(&sJvm);
967 if (jvmStatus != JNI_OK) {
968 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
969 }
970
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700971 // TODO(b/31632518)
972 gnssHal = IGnss::getService("gnss");
973 if (gnssHal != nullptr) {
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100974 auto gnssXtra = gnssHal->getExtensionXtra();
975 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700976 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100977 } else {
978 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700979 }
980
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100981 auto gnssRil = gnssHal->getExtensionAGnssRil();
982 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700983 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100984 } else {
985 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700986 }
987
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100988 auto gnssAgnss = gnssHal->getExtensionAGnss();
989 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700990 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100991 } else {
992 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700993 }
994
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100995 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
996 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700997 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100998 } else {
999 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001000 }
1001
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001002 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1003 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001004 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001005 } else {
1006 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001007 }
1008
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001009 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1010 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001011 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001012 } else {
1013 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001014 }
1015
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001016 auto gnssNi = gnssHal->getExtensionGnssNi();
1017 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001018 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001019 } else {
1020 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001021 }
1022
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001023 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1024 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001025 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001026 } else {
1027 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001028 }
1029
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001030 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1031 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001032 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001033 } else {
1034 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001035 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001036 } else {
1037 ALOGE("Unable to get GPS service\n");
1038 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001039}
1040
1041static jboolean android_location_GnssLocationProvider_is_supported(
1042 JNIEnv* /* env */, jclass /* clazz */) {
1043 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1044}
1045
1046static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1047 JNIEnv* /* env */, jclass /* clazz */) {
1048 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1049}
1050
1051static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1052 JNIEnv* /* env */, jclass /* jclazz */) {
1053 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1054}
1055
1056static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1057 /*
1058 * This must be set before calling into the HAL library.
1059 */
1060 if (!mCallbacksObj)
1061 mCallbacksObj = env->NewGlobalRef(obj);
1062
1063 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1064 /*
1065 * Fail if the main interface fails to initialize
1066 */
1067 if (gnssHal == nullptr) {
1068 ALOGE("Unable to Initialize GNSS HAL\n");
1069 return JNI_FALSE;
1070 }
1071
1072 auto result = gnssHal->setCallback(gnssCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001073 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 ALOGE("SetCallback for Gnss Interface fails\n");
1075 return JNI_FALSE;
1076 }
1077
1078 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1079 if (gnssXtraIface == nullptr) {
1080 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001081 } else {
1082 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001083 if ((!result) || (!result.isOk())) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001084 gnssXtraIface = nullptr;
1085 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1086 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001087 }
1088
1089 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1090 if (agnssIface != nullptr) {
1091 agnssIface->setCallback(aGnssCbIface);
1092 } else {
1093 ALOGE("Unable to Initialize AGnss interface\n");
1094 }
1095
1096 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1097 if (gnssGeofencingIface != nullptr) {
1098 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1099 } else {
1100 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1101 }
1102
1103 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1104 if (gnssNiCbIface != nullptr) {
1105 gnssNiIface->setCallback(gnssNiCbIface);
1106 } else {
1107 ALOGE("Unable to initialize GNSS NI interface\n");
1108 }
1109
1110 return JNI_TRUE;
1111}
1112
1113static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1114 if (gnssHal != nullptr) {
1115 gnssHal->cleanup();
1116 }
1117}
1118
1119static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1120 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1121 jint preferred_time) {
1122 if (gnssHal != nullptr) {
1123 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1124 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1125 min_interval,
1126 preferred_accuracy,
1127 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001128 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001129 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1130 return JNI_FALSE;
1131 } else {
1132 return result;
1133 }
1134 } else {
1135 return JNI_FALSE;
1136 }
1137}
1138
1139static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1140 if (gnssHal != nullptr) {
1141 auto result = gnssHal->start();
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}
1151
1152static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1153 if (gnssHal != nullptr) {
1154 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001155 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001156 return JNI_FALSE;
1157 } else {
1158 return result;
1159 }
1160 } else {
1161 return JNI_FALSE;
1162 }
1163}
1164static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1165 jobject /* obj */,
1166 jint flags) {
1167 if (gnssHal != nullptr) {
1168 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001169 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001170 ALOGE("Error in deleting aiding data");
1171 }
1172 }
1173}
1174
1175/*
1176 * This enum is used by the read_sv_status method to combine the svid,
1177 * constellation and svFlag fields.
1178 */
1179enum ShiftWidth: uint8_t {
1180 SVID_SHIFT_WIDTH = 7,
1181 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1182};
1183
1184static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1185 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001186 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001187 /*
1188 * This method should only be called from within a call to reportSvStatus.
1189 */
1190 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1191 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1192 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1193 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001194 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001195
1196 /*
1197 * Read GNSS SV info.
1198 */
1199 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1200 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1201 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1202 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1203 static_cast<uint32_t>(info.svFlag);
1204 cn0s[i] = info.cN0Dbhz;
1205 elev[i] = info.elevationDegrees;
1206 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001207 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001208 }
1209
1210 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1211 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1212 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1213 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001214 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001215 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1216}
1217
1218static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1219 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1220 IAGnssRil::AGnssRefLocation location;
1221
1222 if (agnssRilIface == nullptr) {
1223 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1224 return;
1225 }
1226
1227 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1228 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1229 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1230 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1231 location.cellID.mcc = mcc;
1232 location.cellID.mnc = mnc;
1233 location.cellID.lac = lac;
1234 location.cellID.cid = cid;
1235 break;
1236 default:
1237 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1238 return;
1239 break;
1240 }
1241
1242 agnssRilIface->setRefLocation(location);
1243}
1244
1245static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1246 jint type, jstring setid_string) {
1247 if (agnssRilIface == nullptr) {
1248 ALOGE("no AGPS RIL interface in agps_set_id");
1249 return;
1250 }
1251
1252 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1253 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1254 env->ReleaseStringUTFChars(setid_string, setid);
1255}
1256
1257static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1258 jbyteArray nmeaArray, jint buffer_size) {
1259 // this should only be called from within a call to reportNmea
1260 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1261 int length = GnssCallback::sNmeaStringLength;
1262 if (length > buffer_size)
1263 length = buffer_size;
1264 memcpy(nmea, GnssCallback::sNmeaString, length);
1265 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1266 return (jint) length;
1267}
1268
1269static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1270 jlong time, jlong timeReference, jint uncertainty) {
1271 if (gnssHal != nullptr) {
1272 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001273 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001274 ALOGE("%s: Gnss injectTime() failed", __func__);
1275 }
1276 }
1277}
1278
1279static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1280 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1281 if (gnssHal != nullptr) {
1282 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001283 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001284 ALOGE("%s: Gnss injectLocation() failed", __func__);
1285 }
1286 }
1287}
1288
1289static jboolean android_location_GnssLocationProvider_supports_xtra(
1290 JNIEnv* /* env */, jobject /* obj */) {
1291 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1292}
1293
1294static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1295 jbyteArray data, jint length) {
1296 if (gnssXtraIface == nullptr) {
1297 ALOGE("XTRA Interface not supported");
1298 return;
1299 }
1300
1301 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1302 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1303 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1304}
1305
1306static void android_location_GnssLocationProvider_agps_data_conn_open(
1307 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1308 if (agnssIface == nullptr) {
1309 ALOGE("no AGPS interface in agps_data_conn_open");
1310 return;
1311 }
1312 if (apn == NULL) {
1313 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1314 return;
1315 }
1316
1317 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1318
1319 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001320 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001321 ALOGE("%s: Failed to set APN and its IP type", __func__);
1322 }
1323 env->ReleaseStringUTFChars(apn, apnStr);
1324}
1325
1326static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1327 jobject /* obj */) {
1328 if (agnssIface == nullptr) {
1329 ALOGE("%s: AGPS interface not supported", __func__);
1330 return;
1331 }
1332
1333 auto result = agnssIface->dataConnClosed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001334 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001335 ALOGE("%s: Failed to close AGnss data connection", __func__);
1336 }
1337}
1338
1339static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1340 jobject /* obj */) {
1341 if (agnssIface == nullptr) {
1342 ALOGE("%s: AGPS interface not supported", __func__);
1343 return;
1344 }
1345
1346 auto result = agnssIface->dataConnFailed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001347 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001348 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1349 }
1350}
1351
1352static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1353 jint type, jstring hostname, jint port) {
1354 if (agnssIface == nullptr) {
1355 ALOGE("no AGPS interface in set_agps_server");
1356 return;
1357 }
1358
1359 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1360 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1361 c_hostname,
1362 port);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001363 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001364 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1365 }
1366
1367 env->ReleaseStringUTFChars(hostname, c_hostname);
1368}
1369
1370static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1371 jobject /* obj */, jint notifId, jint response) {
1372 if (gnssNiIface == nullptr) {
1373 ALOGE("no NI interface in send_ni_response");
1374 return;
1375 }
1376
1377 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1378}
1379
1380static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1381 jobject /* obj */) {
1382 jstring result = NULL;
1383 /*
1384 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1385 */
1386 if (gnssDebugIface != nullptr) {
1387 IGnssDebug::DebugData data;
1388 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1389 data = debugData;
1390 });
1391
1392 std::stringstream internalState;
1393 if (data.position.valid) {
1394 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1395 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1396 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001397 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1398 << ", bearingDegrees: " << data.position.bearingDegrees
1399 << ", horizontalAccuracyMeters: " << data.position.horizontalAccuracyMeters
1400 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
1401 << ", speedAccuracyMetersPerSecond: " << data.position.speedAccuracyMetersPerSecond
1402 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001403 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1404 }
1405
1406 if (data.time.valid) {
1407 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1408 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1409 }
1410
1411 if (data.satelliteDataArray.size() != 0) {
1412 internalState << "Satellite Data:: ";
1413 }
1414
1415 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1416 internalState << "svid: " << data.satelliteDataArray[i].svid
1417 << ", constellation: "
1418 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1419 << ", ephemerisType: "
1420 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1421 << ", ephemerisAgeSeconds: "
1422 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1423 }
1424 result = env->NewStringUTF(internalState.str().c_str());
1425 }
1426 return result;
1427}
1428
1429static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1430 jobject /* obj */,
1431 jboolean connected,
1432 jint type,
1433 jboolean roaming,
1434 jboolean available,
1435 jstring extraInfo,
1436 jstring apn) {
1437 if (agnssRilIface != nullptr) {
1438 auto result = agnssRilIface->updateNetworkState(connected,
1439 static_cast<IAGnssRil::NetworkType>(type),
1440 roaming);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001441 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001442 ALOGE("updateNetworkState failed");
1443 }
1444
1445 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1446 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001447 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001448 ALOGE("updateNetworkAvailability failed");
1449 }
1450
1451 env->ReleaseStringUTFChars(apn, c_apn);
1452 } else {
1453 ALOGE("AGnssRilInterface does not exist");
1454 }
1455}
1456
1457static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1458 JNIEnv* /* env */, jobject /* obj */) {
1459 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1460}
1461
1462static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1463 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1464 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1465 jint unknown_timer) {
1466 if (gnssGeofencingIface != nullptr) {
1467 auto result = gnssGeofencingIface->addGeofence(
1468 geofenceId, latitude, longitude, radius,
1469 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1470 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001471 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001472 } else {
1473 ALOGE("Geofence Interface not available");
1474 }
1475 return JNI_FALSE;
1476}
1477
1478static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1479 jobject /* obj */, jint geofenceId) {
1480 if (gnssGeofencingIface != nullptr) {
1481 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001482 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001483 } else {
1484 ALOGE("Geofence interface not available");
1485 }
1486 return JNI_FALSE;
1487}
1488
1489static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1490 jobject /* obj */, jint geofenceId) {
1491 if (gnssGeofencingIface != nullptr) {
1492 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001493 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001494 } else {
1495 ALOGE("Geofence interface not available");
1496 }
1497 return JNI_FALSE;
1498}
1499
1500static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1501 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1502 if (gnssGeofencingIface != nullptr) {
1503 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001504 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001505 } else {
1506 ALOGE("Geofence interface not available");
1507 }
1508 return JNI_FALSE;
1509}
1510
Lifu Tang30f95a72016-01-07 23:20:38 -08001511static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001512 JNIEnv* env, jclass clazz) {
1513 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001514 return JNI_TRUE;
1515 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001516
destradaaea8a8a62014-06-23 18:19:03 -07001517 return JNI_FALSE;
1518}
1519
Lifu Tang30f95a72016-01-07 23:20:38 -08001520static jboolean android_location_GnssLocationProvider_start_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) {
1524 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001525 return JNI_FALSE;
1526 }
1527
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001528 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1529 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1530 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1531 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1532 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001533 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001534 } else {
1535 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001536 }
1537
1538 return JNI_TRUE;
1539}
1540
Lifu Tang30f95a72016-01-07 23:20:38 -08001541static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001542 JNIEnv* env,
1543 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001544 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001545 ALOGE("Measurement interface not available");
1546 return JNI_FALSE;
1547 }
1548
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001549 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001550 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001551}
1552
Lifu Tang30f95a72016-01-07 23:20:38 -08001553static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001554 JNIEnv* env,
1555 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001556 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001557 return JNI_TRUE;
1558 }
1559 return JNI_FALSE;
1560}
1561
Lifu Tang30f95a72016-01-07 23:20:38 -08001562static jboolean android_location_GnssLocationProvider_start_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 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1571 new GnssNavigationMessageCallback();
1572 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1573 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1574
1575 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1576 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001577 return JNI_FALSE;
1578 }
1579
1580 return JNI_TRUE;
1581}
1582
Lifu Tang30f95a72016-01-07 23:20:38 -08001583static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001584 JNIEnv* env,
1585 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001586 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001587 ALOGE("Navigation Message interface is not available.");
1588 return JNI_FALSE;
1589 }
1590
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001591 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001592 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001593}
1594
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001595static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1596 jobject,
1597 jint emergencySuplPdn) {
1598 if (gnssConfigurationIface == nullptr) {
1599 ALOGE("no GNSS configuration interface available");
1600 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001601 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001602
1603 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001604 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001605 return result;
1606 } else {
1607 return JNI_FALSE;
1608 }
1609}
1610
1611static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1612 jobject,
1613 jint version) {
1614 if (gnssConfigurationIface == nullptr) {
1615 ALOGE("no GNSS configuration interface available");
1616 return JNI_FALSE;
1617 }
1618 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001619 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001620 return result;
1621 } else {
1622 return JNI_FALSE;
1623 }
1624}
1625
1626static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1627 jobject,
1628 jint suplEs) {
1629 if (gnssConfigurationIface == nullptr) {
1630 ALOGE("no GNSS configuration interface available");
1631 return JNI_FALSE;
1632 }
1633
1634 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001635 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001636 return result;
1637 } else {
1638 return JNI_FALSE;
1639 }
1640}
1641
1642static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1643 jobject,
1644 jint mode) {
1645 if (gnssConfigurationIface == nullptr) {
1646 ALOGE("no GNSS configuration interface available");
1647 return JNI_FALSE;
1648 }
1649
1650 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001651 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001652 return result;
1653 } else {
1654 return JNI_FALSE;
1655 }
1656}
1657
1658static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1659 jobject,
1660 jint gpsLock) {
1661 if (gnssConfigurationIface == nullptr) {
1662 ALOGE("no GNSS configuration interface available");
1663 return JNI_FALSE;
1664 }
1665
1666 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001667 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001668 return result;
1669 } else {
1670 return JNI_FALSE;
1671 }
1672}
1673
1674static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1675 jobject,
1676 jint lppProfile) {
1677 if (gnssConfigurationIface == nullptr) {
1678 ALOGE("no GNSS configuration interface available");
1679 return JNI_FALSE;
1680 }
1681
1682 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1683
Steven Morelandd002a8b2017-01-03 17:18:24 -08001684 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001685 return result;
1686 } else {
1687 return JNI_FALSE;
1688 }
1689}
1690
1691static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1692 jobject,
1693 jint gnssPosProtocol) {
1694 if (gnssConfigurationIface == nullptr) {
1695 ALOGE("no GNSS configuration interface available");
1696 return JNI_FALSE;
1697 }
1698
1699 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001700 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001701 return result;
1702 } else {
1703 return JNI_FALSE;
1704 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001705}
1706
Daniel Micay76f6a862015-09-19 17:31:01 -04001707static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001708 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001709 {"class_init_native", "()V", reinterpret_cast<void *>(
1710 android_location_GnssLocationProvider_class_init_native)},
1711 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1712 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001713 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001714 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001715 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001716 reinterpret_cast<void *>(
1717 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1718 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1719 {"native_cleanup", "()V", reinterpret_cast<void *>(
1720 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001721 {"native_set_position_mode",
1722 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001723 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1724 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1725 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001726 {"native_delete_aiding_data",
1727 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001728 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001729 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001730 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001731 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1732 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1733 android_location_GnssLocationProvider_read_nmea)},
1734 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1735 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001736 {"native_inject_location",
1737 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001738 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1739 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1740 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001741 {"native_inject_xtra_data",
1742 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001743 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001744 {"native_agps_data_conn_open",
1745 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001746 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001747 {"native_agps_data_conn_closed",
1748 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001749 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001750 {"native_agps_data_conn_failed",
1751 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001752 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001753 {"native_agps_set_id",
1754 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001755 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001756 {"native_agps_set_ref_location_cellid",
1757 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001758 reinterpret_cast<void *>(
1759 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001760 {"native_set_agps_server",
1761 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001762 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001763 {"native_send_ni_response",
1764 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001765 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001766 {"native_get_internal_state",
1767 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001768 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001769 {"native_update_network_state",
1770 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001771 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001772 {"native_is_geofence_supported",
1773 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001774 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001775 {"native_add_geofence",
1776 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001777 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001778 {"native_remove_geofence",
1779 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001780 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1781 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1782 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001783 {"native_resume_geofence",
1784 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001785 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001786 {"native_is_measurement_supported",
1787 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001788 reinterpret_cast<void *>(
1789 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001790 {"native_start_measurement_collection",
1791 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001792 reinterpret_cast<void *>(
1793 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001794 {"native_stop_measurement_collection",
1795 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001796 reinterpret_cast<void *>(
1797 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001798 {"native_is_navigation_message_supported",
1799 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001800 reinterpret_cast<void *>(
1801 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001802 {"native_start_navigation_message_collection",
1803 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001804 reinterpret_cast<void *>(
1805 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001806 {"native_stop_navigation_message_collection",
1807 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001808 reinterpret_cast<void *>(
1809 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1810 {"native_set_supl_es",
1811 "(I)Z",
1812 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1813 {"native_set_supl_version",
1814 "(I)Z",
1815 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1816 {"native_set_supl_mode",
1817 "(I)Z",
1818 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1819 {"native_set_lpp_profile",
1820 "(I)Z",
1821 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1822 {"native_set_gnss_pos_protocol_select",
1823 "(I)Z",
1824 reinterpret_cast<void *>(
1825 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1826 {"native_set_gps_lock",
1827 "(I)Z",
1828 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1829 {"native_set_emergency_supl_pdn",
1830 "(I)Z",
1831 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832};
1833
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001834int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001835 return jniRegisterNativeMethods(
1836 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001837 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001838 sMethods,
1839 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840}
1841
1842} /* namespace android */