blob: 09886db17af649c317c64da89e4914c7db3fab1f [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 Valsaraju2ea29602016-09-13 08:38:09 -070062using android::OK;
63using android::sp;
64using android::status_t;
65using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070067using android::hardware::Return;
68using android::hardware::Void;
69using android::hardware::hidl_vec;
Lifu Tang30f95a72016-01-07 23:20:38 -080070
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070071using android::hardware::gnss::V1_0::IAGnss;
72using android::hardware::gnss::V1_0::IAGnssCallback;
73using android::hardware::gnss::V1_0::IAGnssCallback;
74using android::hardware::gnss::V1_0::IAGnssRil;
75using android::hardware::gnss::V1_0::IAGnssRilCallback;
76using android::hardware::gnss::V1_0::IGnss;
77using android::hardware::gnss::V1_0::IGnssCallback;
78using android::hardware::gnss::V1_0::IGnssConfiguration;
79using android::hardware::gnss::V1_0::IGnssDebug;
80using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
81using android::hardware::gnss::V1_0::IGnssGeofencing;
82using android::hardware::gnss::V1_0::IGnssMeasurement;
83using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
84using android::hardware::gnss::V1_0::IGnssNavigationMessage;
85using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
86using android::hardware::gnss::V1_0::IGnssNi;
87using android::hardware::gnss::V1_0::IGnssNiCallback;
88using android::hardware::gnss::V1_0::IGnssXtra;
89using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -070090
Wyatt Rileyf6527ae2016-05-23 15:23:12 -070091
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070092sp<IGnss> gnssHal = nullptr;
93sp<IGnssXtra> gnssXtraIface = nullptr;
94sp<IAGnssRil> agnssRilIface = nullptr;
95sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
96sp<IAGnss> agnssIface = nullptr;
97sp<IGnssDebug> gnssDebugIface = nullptr;
98sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
99sp<IGnssNi> gnssNiIface = nullptr;
100sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
101sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400103#define WAKE_LOCK_NAME "GPS"
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105namespace android {
106
Lifu Tang120480f2016-02-07 18:08:19 -0800107template<class T>
108class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700109 public:
110 // Helper function to call setter on a Java object.
111 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800112 JNIEnv* env,
113 jclass clazz,
114 jobject object,
115 const char* method_name,
116 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700117
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700118 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800119 static const char *const signature_;
120};
Lifu Tange5a0e212016-01-25 18:02:17 -0800121
Lifu Tang120480f2016-02-07 18:08:19 -0800122template<class T>
123void JavaMethodHelper<T>::callJavaMethod(
124 JNIEnv* env,
125 jclass clazz,
126 jobject object,
127 const char* method_name,
128 T value) {
129 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
130 env->CallVoidMethod(object, method, value);
131}
destradaaea8a8a62014-06-23 18:19:03 -0700132
Lifu Tang120480f2016-02-07 18:08:19 -0800133class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700134 public:
135 JavaObject(JNIEnv* env, const char* class_name);
136 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800137
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700138 template<class T>
139 void callSetter(const char* method_name, T value);
140 template<class T>
141 void callSetter(const char* method_name, T* value, size_t size);
142 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800143
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144 private:
145 JNIEnv* env_;
146 jclass clazz_;
147 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800148};
149
150JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
151 clazz_ = env_->FindClass(class_name);
152 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
153 object_ = env_->NewObject(clazz_, ctor);
154}
155
156JavaObject::~JavaObject() {
157 env_->DeleteLocalRef(clazz_);
158}
159
160template<class T>
161void JavaObject::callSetter(const char* method_name, T value) {
162 JavaMethodHelper<T>::callJavaMethod(
163 env_, clazz_, object_, method_name, value);
164}
165
166template<>
167void JavaObject::callSetter(
168 const char* method_name, uint8_t* value, size_t size) {
169 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700170 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800171 jmethodID method = env_->GetMethodID(
172 clazz_,
173 method_name,
174 "([B)V");
175 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700176 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800177}
178
179jobject JavaObject::get() {
180 return object_;
181}
182
183// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800184template<>
185const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
186template<>
187const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
188template<>
189const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
190template<>
191const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
192template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800193const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
194template<>
195const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800196template<>
197const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
198template<>
199const char *const JavaMethodHelper<float>::signature_ = "(F)V";
200template<>
201const char *const JavaMethodHelper<double>::signature_ = "(D)V";
202template<>
203const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
204
205#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800206
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700207static inline jboolean boolToJbool(bool value) {
208 return value ? JNI_TRUE : JNI_FALSE;
209}
Lifu Tang120480f2016-02-07 18:08:19 -0800210
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700211static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
212 if (env->ExceptionCheck()) {
213 ALOGE("An exception was thrown by callback '%s'.", methodName);
214 LOGE_EX(env);
215 env->ExceptionClear();
216 }
217}
destradaaea8a8a62014-06-23 18:19:03 -0700218
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700219/*
220 * GnssCallback class implements the callback methods for IGnss interface.
221 */
222struct GnssCallback : public IGnssCallback {
223 Return<void> gnssLocationCb(
224 const android::hardware::gnss::V1_0::GnssLocation& location) override;
225 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
226 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
227 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
228 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
229 Return<void> gnssAcquireWakelockCb() override;
230 Return<void> gnssReleaseWakelockCb() override;
231 Return<void> gnssRequestTimeCb() override;
232 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800233
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700234 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
235 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
236 static size_t sGnssSvListSize;
237
238 static const char* sNmeaString;
239 static size_t sNmeaStringLength;
240};
241
242IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
243 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
244const char* GnssCallback::sNmeaString = nullptr;
245size_t GnssCallback::sNmeaStringLength = 0;
246size_t GnssCallback::sGnssSvListSize = 0;
247
248Return<void> GnssCallback::gnssLocationCb(
249 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
250 JNIEnv* env = AndroidRuntime::getJNIEnv();
251 env->CallVoidMethod(mCallbacksObj,
252 method_reportLocation,
253 location.gnssLocationFlags,
254 static_cast<jdouble>(location.latitudeDegrees),
255 static_cast<jdouble>(location.longitudeDegrees),
256 static_cast<jdouble>(location.altitudeMeters),
257 static_cast<jfloat>(location.speedMetersPerSec),
258 static_cast<jfloat>(location.bearingDegrees),
259 static_cast<jfloat>(location.accuracyMeters),
260 static_cast<jlong>(location.timestamp));
261 checkAndClearExceptionFromCallback(env, __FUNCTION__);
262 return Void();
263}
264
265Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
266 JNIEnv* env = AndroidRuntime::getJNIEnv();
267 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
268 checkAndClearExceptionFromCallback(env, __FUNCTION__);
269 return Void();
270}
271
272Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
273 JNIEnv* env = AndroidRuntime::getJNIEnv();
274
275 sGnssSvListSize = svStatus.numSvs;
276 if (sGnssSvListSize > static_cast<uint32_t>(
277 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
278 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
279 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
280 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800281 }
282
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700283 // Copy GNSS SV info into sGnssSvList, if any.
284 if (svStatus.numSvs > 0) {
285 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800286 }
destradaaea8a8a62014-06-23 18:19:03 -0700287
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700288 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
289 checkAndClearExceptionFromCallback(env, __FUNCTION__);
290 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700291}
292
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700293Return<void> GnssCallback::gnssNmeaCb(
294 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
295 JNIEnv* env = AndroidRuntime::getJNIEnv();
296 /*
297 * The Java code will call back to read these values.
298 * We do this to avoid creating unnecessary String objects.
299 */
300 sNmeaString = nmea.c_str();
301 sNmeaStringLength = nmea.size();
302
303 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
304 checkAndClearExceptionFromCallback(env, __FUNCTION__);
305 return Void();
306}
307
308Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
309 ALOGD("%s: %du\n", __func__, capabilities);
310
311 JNIEnv* env = AndroidRuntime::getJNIEnv();
312 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
313 checkAndClearExceptionFromCallback(env, __FUNCTION__);
314 return Void();
315}
316
317Return<void> GnssCallback::gnssAcquireWakelockCb() {
318 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
319 return Void();
320}
321
322Return<void> GnssCallback::gnssReleaseWakelockCb() {
323 release_wake_lock(WAKE_LOCK_NAME);
324 return Void();
325}
326
327Return<void> GnssCallback::gnssRequestTimeCb() {
328 JNIEnv* env = AndroidRuntime::getJNIEnv();
329 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
330 checkAndClearExceptionFromCallback(env, __FUNCTION__);
331 return Void();
332}
333
334Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
335 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
336
337 JNIEnv* env = AndroidRuntime::getJNIEnv();
338 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
339 info.yearOfHw);
340 checkAndClearExceptionFromCallback(env, __FUNCTION__);
341 return Void();
342}
343
344class GnssXtraCallback : public IGnssXtraCallback {
345 Return<void> downloadRequestCb() override;
346};
347
348/*
349 * GnssXtraCallback class implements the callback methods for the IGnssXtra
350 * interface.
351 */
352Return<void> GnssXtraCallback::downloadRequestCb() {
353 JNIEnv* env = AndroidRuntime::getJNIEnv();
354 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
355 checkAndClearExceptionFromCallback(env, __FUNCTION__);
356 return Void();
357}
358
359/*
360 * GnssGeofenceCallback class implements the callback methods for the
361 * IGnssGeofence interface.
362 */
363struct GnssGeofenceCallback : public IGnssGeofenceCallback {
364 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
365 Return<void> gnssGeofenceTransitionCb(
366 int32_t geofenceId,
367 const android::hardware::gnss::V1_0::GnssLocation& location,
368 GeofenceTransition transition,
369 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
370 Return<void> gnssGeofenceStatusCb(
371 GeofenceAvailability status,
372 const android::hardware::gnss::V1_0::GnssLocation& location) override;
373 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
374 GeofenceStatus status) override;
375 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
376 GeofenceStatus status) override;
377 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
378 GeofenceStatus status) override;
379 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
380 GeofenceStatus status) override;
381};
382
383Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
384 int32_t geofenceId,
385 const android::hardware::gnss::V1_0::GnssLocation& location,
386 GeofenceTransition transition,
387 hardware::gnss::V1_0::GnssUtcTime timestamp) {
388 JNIEnv* env = AndroidRuntime::getJNIEnv();
389
390 env->CallVoidMethod(mCallbacksObj,
391 method_reportGeofenceTransition,
392 geofenceId,
393 location.gnssLocationFlags,
394 static_cast<jdouble>(location.latitudeDegrees),
395 static_cast<jdouble>(location.longitudeDegrees),
396 static_cast<jdouble>(location.altitudeMeters),
397 static_cast<jfloat>(location.speedMetersPerSec),
398 static_cast<jfloat>(location.bearingDegrees),
399 static_cast<jfloat>(location.accuracyMeters),
400 static_cast<jlong>(location.timestamp),
401 transition,
402 timestamp);
403
404 checkAndClearExceptionFromCallback(env, __FUNCTION__);
405 return Void();
406}
407
408Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
409 GeofenceAvailability status,
410 const android::hardware::gnss::V1_0::GnssLocation& location) {
411 JNIEnv* env = AndroidRuntime::getJNIEnv();
412 env->CallVoidMethod(mCallbacksObj,
413 method_reportGeofenceStatus,
414 status,
415 location.gnssLocationFlags,
416 static_cast<jdouble>(location.latitudeDegrees),
417 static_cast<jdouble>(location.longitudeDegrees),
418 static_cast<jdouble>(location.altitudeMeters),
419 static_cast<jfloat>(location.speedMetersPerSec),
420 static_cast<jfloat>(location.bearingDegrees),
421 static_cast<jfloat>(location.accuracyMeters),
422 static_cast<jlong>(location.timestamp));
423 checkAndClearExceptionFromCallback(env, __FUNCTION__);
424 return Void();
425}
426
427Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
428 GeofenceStatus status) {
429 JNIEnv* env = AndroidRuntime::getJNIEnv();
430 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
431 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
432 }
433
434 env->CallVoidMethod(mCallbacksObj,
435 method_reportGeofenceAddStatus,
436 geofenceId,
437 status);
438 checkAndClearExceptionFromCallback(env, __FUNCTION__);
439 return Void();
440}
441
442Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
443 GeofenceStatus status) {
444 JNIEnv* env = AndroidRuntime::getJNIEnv();
445 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
446 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
447 }
448
449 env->CallVoidMethod(mCallbacksObj,
450 method_reportGeofenceRemoveStatus,
451 geofenceId, status);
452 checkAndClearExceptionFromCallback(env, __FUNCTION__);
453 return Void();
454}
455
456Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
457 GeofenceStatus status) {
458 JNIEnv* env = AndroidRuntime::getJNIEnv();
459 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
460 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
461 }
462
463 env->CallVoidMethod(mCallbacksObj,
464 method_reportGeofencePauseStatus,
465 geofenceId, status);
466 checkAndClearExceptionFromCallback(env, __FUNCTION__);
467 return Void();
468}
469
470Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
471 GeofenceStatus status) {
472 JNIEnv* env = AndroidRuntime::getJNIEnv();
473 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
474 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
475 }
476
477 env->CallVoidMethod(mCallbacksObj,
478 method_reportGeofenceResumeStatus,
479 geofenceId, status);
480 checkAndClearExceptionFromCallback(env, __FUNCTION__);
481 return Void();
482}
483
484/*
485 * GnssNavigationMessageCallback interface implements the callback methods
486 * required by the IGnssNavigationMessage interface.
487 */
488struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
489 /*
490 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
491 * follow.
492 */
493 Return<void> gnssNavigationMessageCb(
494 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
495};
496
497Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
498 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
499 JNIEnv* env = AndroidRuntime::getJNIEnv();
500
501 size_t dataLength = message.data.size();
502
503 std::vector<uint8_t> navigationData = message.data;
504 uint8_t* data = &(navigationData[0]);
505 if (dataLength == 0 || data == NULL) {
506 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
507 dataLength);
508 return Void();
509 }
510
511 JavaObject object(env, "android/location/GnssNavigationMessage");
512 SET(Type, static_cast<int32_t>(message.type));
513 SET(Svid, static_cast<int32_t>(message.svid));
514 SET(MessageId, static_cast<int32_t>(message.messageId));
515 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
516 object.callSetter("setData", data, dataLength);
517 SET(Status, static_cast<int32_t>(message.status));
518
519 jobject navigationMessage = object.get();
520 env->CallVoidMethod(mCallbacksObj,
521 method_reportNavigationMessages,
522 navigationMessage);
523 env->DeleteLocalRef(navigationMessage);
524 return Void();
525}
526
527/*
528 * GnssMeasurementCallback implements the callback methods required for the
529 * GnssMeasurement interface.
530 */
531struct GnssMeasurementCallback : public IGnssMeasurementCallback {
532 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
533 private:
534 jobject translateGnssMeasurement(
535 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
536 jobject translateGnssClock(
537 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
538 jobjectArray translateGnssMeasurements(
539 JNIEnv* env,
540 const IGnssMeasurementCallback::GnssMeasurement* measurements,
541 size_t count);
542 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
543};
544
545
546Return<void> GnssMeasurementCallback::GnssMeasurementCb(
547 const IGnssMeasurementCallback::GnssData& data) {
548 JNIEnv* env = AndroidRuntime::getJNIEnv();
549
550 jobject clock;
551 jobjectArray measurementArray;
552
553 clock = translateGnssClock(env, &data.clock);
554 measurementArray = translateGnssMeasurements(
555 env, data.measurements.data(), data.measurementCount);
556 setMeasurementData(env, clock, measurementArray);
557
558 env->DeleteLocalRef(clock);
559 env->DeleteLocalRef(measurementArray);
560 return Void();
561}
562
563jobject GnssMeasurementCallback::translateGnssMeasurement(
564 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800565 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800566
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700567 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700568
569 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800570 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700571 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800572 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700573 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800574 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700575 measurement->receivedSvTimeUncertaintyInNs);
576 SET(Cn0DbHz, measurement->cN0DbHz);
577 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800578 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700579 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800580 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700581 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
582 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800583 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700584 measurement->accumulatedDeltaRangeUncertaintyM);
585
586 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
587 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
588 }
589
590 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
591 SET(CarrierPhase, measurement->carrierPhase);
592 }
593
594 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
595 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
596 }
597
598 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
599
600 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
601 SET(SnrInDb, measurement->snrDb);
602 }
Lifu Tang120480f2016-02-07 18:08:19 -0800603
604 return object.get();
605}
606
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700607jobject GnssMeasurementCallback::translateGnssClock(
608 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
609 JavaObject object(env, "android/location/GnssClock");
610
611 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
612 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
613 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
614 }
615
616 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
617 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
618 }
619
620 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
621 SET(FullBiasNanos, clock->fullBiasNs);
622 }
623
624 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
625 SET(BiasNanos, clock->biasNs);
626 }
627
628 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
629 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
630 }
631
632 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
633 SET(DriftNanosPerSecond, clock->driftNsps);
634 }
635
636 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
637 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
638 }
639
640 SET(TimeNanos, clock->timeNs);
641 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
642
643 return object.get();
644}
645
646jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
647 const IGnssMeasurementCallback::GnssMeasurement*
648 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800649 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700650 return NULL;
651 }
652
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700653 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800654 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800655 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800656 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700657 NULL /* initialElement */);
658
Lifu Tang120480f2016-02-07 18:08:19 -0800659 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700660 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800661 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800662 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800663 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
664 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700665 }
666
Lifu Tang818aa2c2016-02-01 01:52:00 -0800667 env->DeleteLocalRef(gnssMeasurementClass);
668 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700669}
670
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700671void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
672 jobjectArray measurementArray) {
673 jclass gnssMeasurementsEventClass =
674 env->FindClass("android/location/GnssMeasurementsEvent");
675 jmethodID gnssMeasurementsEventCtor =
676 env->GetMethodID(
677 gnssMeasurementsEventClass,
678 "<init>",
679 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800680
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700681 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
682 gnssMeasurementsEventCtor,
683 clock,
684 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800685
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700686 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
687 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800688 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800689 env->DeleteLocalRef(gnssMeasurementsEventClass);
690 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700691}
692
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693/*
694 * GnssNiCallback implements callback methods required by the IGnssNi interface.
695 */
696struct GnssNiCallback : public IGnssNiCallback {
697 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
698 override;
destradaaea8a8a62014-06-23 18:19:03 -0700699};
700
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700701Return<void> GnssNiCallback::niNotifyCb(
702 const IGnssNiCallback::GnssNiNotification& notification) {
703 JNIEnv* env = AndroidRuntime::getJNIEnv();
704 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
705 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
706
707 if (requestorId && text) {
708 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
709 notification.notificationId, notification.niType,
710 notification.notifyFlags, notification.timeoutSec,
711 notification.defaultResponse, requestorId, text,
712 notification.requestorIdEncoding,
713 notification.notificationIdEncoding);
714 } else {
715 ALOGE("%s: OOM Error\n", __func__);
716 }
717
718 if (requestorId) {
719 env->DeleteLocalRef(requestorId);
720 }
721
722 if (text) {
723 env->DeleteLocalRef(text);
724 }
725 checkAndClearExceptionFromCallback(env, __FUNCTION__);
726 return Void();
727}
728
729/*
730 * AGnssCallback implements callback methods required by the IAGnss interface.
731 */
732struct AGnssCallback : public IAGnssCallback {
733 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
734 Return<void> agnssStatusIpV6Cb(
735 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
736
737 Return<void> agnssStatusIpV4Cb(
738 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
739 private:
740 jbyteArray convertToIpV4(uint32_t ip);
741};
742
743Return<void> AGnssCallback::agnssStatusIpV6Cb(
744 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
745 JNIEnv* env = AndroidRuntime::getJNIEnv();
746 jbyteArray byteArray = NULL;
747 bool isSupported = false;
748
749 byteArray = env->NewByteArray(16);
750 if (byteArray != NULL) {
751 env->SetByteArrayRegion(byteArray, 0, 16,
752 (const jbyte*)(agps_status.ipV6Addr.data()));
753 isSupported = true;
754 } else {
755 ALOGE("Unable to allocate byte array for IPv6 address.");
756 }
757
758 IF_ALOGD() {
759 // log the IP for reference in case there is a bogus value pushed by HAL
760 char str[INET6_ADDRSTRLEN];
761 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
762 ALOGD("AGPS IP is v6: %s", str);
763 }
764
765 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
766 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
767 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
768 agps_status.type, agps_status.status, byteArray);
769
770 checkAndClearExceptionFromCallback(env, __FUNCTION__);
771
772 if (byteArray) {
773 env->DeleteLocalRef(byteArray);
774 }
775
776 return Void();
777}
778
779Return<void> AGnssCallback::agnssStatusIpV4Cb(
780 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
781 JNIEnv* env = AndroidRuntime::getJNIEnv();
782 jbyteArray byteArray = NULL;
783
784 uint32_t ipAddr = agps_status.ipV4Addr;
785 byteArray = convertToIpV4(ipAddr);
786
787 IF_ALOGD() {
788 /*
789 * log the IP for reference in case there is a bogus value pushed by
790 * HAL.
791 */
792 char str[INET_ADDRSTRLEN];
793 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
794 ALOGD("AGPS IP is v4: %s", str);
795 }
796
797 jsize byteArrayLength =
798 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
799 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
800 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
801 agps_status.type, agps_status.status, byteArray);
802
803 checkAndClearExceptionFromCallback(env, __FUNCTION__);
804
805 if (byteArray) {
806 env->DeleteLocalRef(byteArray);
807 }
808 return Void();
809}
810
811jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
812 if (INADDR_NONE == ip) {
813 return NULL;
814 }
815
816 JNIEnv* env = AndroidRuntime::getJNIEnv();
817 jbyteArray byteArray = env->NewByteArray(4);
818 if (byteArray == NULL) {
819 ALOGE("Unable to allocate byte array for IPv4 address");
820 return NULL;
821 }
822
823 jbyte ipv4[4];
824 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
825 memcpy(ipv4, &ip, sizeof(ipv4));
826 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
827 return byteArray;
828}
829
830/*
831 * AGnssRilCallback implements the callback methods required by the AGnssRil
832 * interface.
833 */
834struct AGnssRilCallback : IAGnssRilCallback {
835 Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override;
836 Return<void> requestRefLocCb() override;
837};
838
839Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) {
840 JNIEnv* env = AndroidRuntime::getJNIEnv();
841 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
842 checkAndClearExceptionFromCallback(env, __FUNCTION__);
843 return Void();
844}
845
846Return<void> AGnssRilCallback::requestRefLocCb() {
847 JNIEnv* env = AndroidRuntime::getJNIEnv();
848 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
849 checkAndClearExceptionFromCallback(env, __FUNCTION__);
850 return Void();
851}
852
853static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
854 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
855 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
856 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
857 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
858 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
859 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
860 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
861 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
862 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
863 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
864 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
865 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
866 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
867 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
868 "(IIDDDFFFJIJ)V");
869 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
870 "(IIDDDFFFJ)V");
871 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
872 "(II)V");
873 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
874 "(II)V");
875 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
876 "(II)V");
877 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
878 "(II)V");
879 method_reportMeasurementData = env->GetMethodID(
880 clazz,
881 "reportMeasurementData",
882 "(Landroid/location/GnssMeasurementsEvent;)V");
883 method_reportNavigationMessages = env->GetMethodID(
884 clazz,
885 "reportNavigationMessage",
886 "(Landroid/location/GnssNavigationMessage;)V");
887
888 // TODO(b/31632518)
889 gnssHal = IGnss::getService("gnss");
890 if (gnssHal != nullptr) {
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100891 auto gnssXtra = gnssHal->getExtensionXtra();
892 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700893 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100894 } else {
895 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700896 }
897
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100898 auto gnssRil = gnssHal->getExtensionAGnssRil();
899 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700900 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100901 } else {
902 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700903 }
904
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100905 auto gnssAgnss = gnssHal->getExtensionAGnss();
906 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700907 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100908 } else {
909 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700910 }
911
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100912 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
913 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700914 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100915 } else {
916 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700917 }
918
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100919 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
920 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700921 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100922 } else {
923 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700924 }
925
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100926 auto gnssDebug = gnssHal->getExtensionGnssDebug();
927 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700928 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100929 } else {
930 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700931 }
932
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100933 auto gnssNi = gnssHal->getExtensionGnssNi();
934 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700935 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100936 } else {
937 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700938 }
939
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100940 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
941 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700942 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100943 } else {
944 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700945 }
946
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100947 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
948 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700949 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +0100950 } else {
951 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700952 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700953 } else {
954 ALOGE("Unable to get GPS service\n");
955 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700956}
957
958static jboolean android_location_GnssLocationProvider_is_supported(
959 JNIEnv* /* env */, jclass /* clazz */) {
960 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
961}
962
963static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
964 JNIEnv* /* env */, jclass /* clazz */) {
965 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
966}
967
968static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
969 JNIEnv* /* env */, jclass /* jclazz */) {
970 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
971}
972
973static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
974 /*
975 * This must be set before calling into the HAL library.
976 */
977 if (!mCallbacksObj)
978 mCallbacksObj = env->NewGlobalRef(obj);
979
980 sp<IGnssCallback> gnssCbIface = new GnssCallback();
981 /*
982 * Fail if the main interface fails to initialize
983 */
984 if (gnssHal == nullptr) {
985 ALOGE("Unable to Initialize GNSS HAL\n");
986 return JNI_FALSE;
987 }
988
989 auto result = gnssHal->setCallback(gnssCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -0800990 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991 ALOGE("SetCallback for Gnss Interface fails\n");
992 return JNI_FALSE;
993 }
994
995 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
996 if (gnssXtraIface == nullptr) {
997 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -0800998 } else {
999 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001000 if ((!result) || (!result.isOk())) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001001 gnssXtraIface = nullptr;
1002 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1003 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001004 }
1005
1006 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1007 if (agnssIface != nullptr) {
1008 agnssIface->setCallback(aGnssCbIface);
1009 } else {
1010 ALOGE("Unable to Initialize AGnss interface\n");
1011 }
1012
1013 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1014 if (gnssGeofencingIface != nullptr) {
1015 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1016 } else {
1017 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1018 }
1019
1020 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1021 if (gnssNiCbIface != nullptr) {
1022 gnssNiIface->setCallback(gnssNiCbIface);
1023 } else {
1024 ALOGE("Unable to initialize GNSS NI interface\n");
1025 }
1026
1027 return JNI_TRUE;
1028}
1029
1030static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1031 if (gnssHal != nullptr) {
1032 gnssHal->cleanup();
1033 }
1034}
1035
1036static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1037 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1038 jint preferred_time) {
1039 if (gnssHal != nullptr) {
1040 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1041 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1042 min_interval,
1043 preferred_accuracy,
1044 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001045 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001046 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1047 return JNI_FALSE;
1048 } else {
1049 return result;
1050 }
1051 } else {
1052 return JNI_FALSE;
1053 }
1054}
1055
1056static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1057 if (gnssHal != nullptr) {
1058 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001059 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001060 return JNI_FALSE;
1061 } else {
1062 return result;
1063 }
1064 } else {
1065 return JNI_FALSE;
1066 }
1067}
1068
1069static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1070 if (gnssHal != nullptr) {
1071 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001072 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001073 return JNI_FALSE;
1074 } else {
1075 return result;
1076 }
1077 } else {
1078 return JNI_FALSE;
1079 }
1080}
1081static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1082 jobject /* obj */,
1083 jint flags) {
1084 if (gnssHal != nullptr) {
1085 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001086 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001087 ALOGE("Error in deleting aiding data");
1088 }
1089 }
1090}
1091
1092/*
1093 * This enum is used by the read_sv_status method to combine the svid,
1094 * constellation and svFlag fields.
1095 */
1096enum ShiftWidth: uint8_t {
1097 SVID_SHIFT_WIDTH = 7,
1098 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1099};
1100
1101static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1102 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
1103 jfloatArray azumArray) {
1104 /*
1105 * This method should only be called from within a call to reportSvStatus.
1106 */
1107 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1108 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1109 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1110 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
1111
1112 /*
1113 * Read GNSS SV info.
1114 */
1115 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1116 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1117 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1118 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1119 static_cast<uint32_t>(info.svFlag);
1120 cn0s[i] = info.cN0Dbhz;
1121 elev[i] = info.elevationDegrees;
1122 azim[i] = info.azimuthDegrees;
1123 }
1124
1125 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1126 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1127 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1128 env->ReleaseFloatArrayElements(azumArray, azim, 0);
1129 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1130}
1131
1132static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1133 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1134 IAGnssRil::AGnssRefLocation location;
1135
1136 if (agnssRilIface == nullptr) {
1137 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1138 return;
1139 }
1140
1141 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1142 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1143 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1144 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1145 location.cellID.mcc = mcc;
1146 location.cellID.mnc = mnc;
1147 location.cellID.lac = lac;
1148 location.cellID.cid = cid;
1149 break;
1150 default:
1151 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1152 return;
1153 break;
1154 }
1155
1156 agnssRilIface->setRefLocation(location);
1157}
1158
1159static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1160 jint type, jstring setid_string) {
1161 if (agnssRilIface == nullptr) {
1162 ALOGE("no AGPS RIL interface in agps_set_id");
1163 return;
1164 }
1165
1166 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1167 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1168 env->ReleaseStringUTFChars(setid_string, setid);
1169}
1170
1171static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1172 jbyteArray nmeaArray, jint buffer_size) {
1173 // this should only be called from within a call to reportNmea
1174 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1175 int length = GnssCallback::sNmeaStringLength;
1176 if (length > buffer_size)
1177 length = buffer_size;
1178 memcpy(nmea, GnssCallback::sNmeaString, length);
1179 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1180 return (jint) length;
1181}
1182
1183static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1184 jlong time, jlong timeReference, jint uncertainty) {
1185 if (gnssHal != nullptr) {
1186 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001187 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001188 ALOGE("%s: Gnss injectTime() failed", __func__);
1189 }
1190 }
1191}
1192
1193static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1194 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1195 if (gnssHal != nullptr) {
1196 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001197 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001198 ALOGE("%s: Gnss injectLocation() failed", __func__);
1199 }
1200 }
1201}
1202
1203static jboolean android_location_GnssLocationProvider_supports_xtra(
1204 JNIEnv* /* env */, jobject /* obj */) {
1205 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1206}
1207
1208static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1209 jbyteArray data, jint length) {
1210 if (gnssXtraIface == nullptr) {
1211 ALOGE("XTRA Interface not supported");
1212 return;
1213 }
1214
1215 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1216 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1217 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1218}
1219
1220static void android_location_GnssLocationProvider_agps_data_conn_open(
1221 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1222 if (agnssIface == nullptr) {
1223 ALOGE("no AGPS interface in agps_data_conn_open");
1224 return;
1225 }
1226 if (apn == NULL) {
1227 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1228 return;
1229 }
1230
1231 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1232
1233 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001234 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001235 ALOGE("%s: Failed to set APN and its IP type", __func__);
1236 }
1237 env->ReleaseStringUTFChars(apn, apnStr);
1238}
1239
1240static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1241 jobject /* obj */) {
1242 if (agnssIface == nullptr) {
1243 ALOGE("%s: AGPS interface not supported", __func__);
1244 return;
1245 }
1246
1247 auto result = agnssIface->dataConnClosed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001248 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001249 ALOGE("%s: Failed to close AGnss data connection", __func__);
1250 }
1251}
1252
1253static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1254 jobject /* obj */) {
1255 if (agnssIface == nullptr) {
1256 ALOGE("%s: AGPS interface not supported", __func__);
1257 return;
1258 }
1259
1260 auto result = agnssIface->dataConnFailed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001261 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001262 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1263 }
1264}
1265
1266static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1267 jint type, jstring hostname, jint port) {
1268 if (agnssIface == nullptr) {
1269 ALOGE("no AGPS interface in set_agps_server");
1270 return;
1271 }
1272
1273 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1274 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1275 c_hostname,
1276 port);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001277 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001278 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1279 }
1280
1281 env->ReleaseStringUTFChars(hostname, c_hostname);
1282}
1283
1284static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1285 jobject /* obj */, jint notifId, jint response) {
1286 if (gnssNiIface == nullptr) {
1287 ALOGE("no NI interface in send_ni_response");
1288 return;
1289 }
1290
1291 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1292}
1293
1294static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1295 jobject /* obj */) {
1296 jstring result = NULL;
1297 /*
1298 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1299 */
1300 if (gnssDebugIface != nullptr) {
1301 IGnssDebug::DebugData data;
1302 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1303 data = debugData;
1304 });
1305
1306 std::stringstream internalState;
1307 if (data.position.valid) {
1308 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1309 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1310 << ", altitudeMeters: " << data.position.altitudeMeters
1311 << ", accuracyMeters: " << data.position.accuracyMeters
1312 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1313 }
1314
1315 if (data.time.valid) {
1316 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1317 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1318 }
1319
1320 if (data.satelliteDataArray.size() != 0) {
1321 internalState << "Satellite Data:: ";
1322 }
1323
1324 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1325 internalState << "svid: " << data.satelliteDataArray[i].svid
1326 << ", constellation: "
1327 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1328 << ", ephemerisType: "
1329 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1330 << ", ephemerisAgeSeconds: "
1331 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1332 }
1333 result = env->NewStringUTF(internalState.str().c_str());
1334 }
1335 return result;
1336}
1337
1338static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1339 jobject /* obj */,
1340 jboolean connected,
1341 jint type,
1342 jboolean roaming,
1343 jboolean available,
1344 jstring extraInfo,
1345 jstring apn) {
1346 if (agnssRilIface != nullptr) {
1347 auto result = agnssRilIface->updateNetworkState(connected,
1348 static_cast<IAGnssRil::NetworkType>(type),
1349 roaming);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001350 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001351 ALOGE("updateNetworkState failed");
1352 }
1353
1354 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1355 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001356 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001357 ALOGE("updateNetworkAvailability failed");
1358 }
1359
1360 env->ReleaseStringUTFChars(apn, c_apn);
1361 } else {
1362 ALOGE("AGnssRilInterface does not exist");
1363 }
1364}
1365
1366static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1367 JNIEnv* /* env */, jobject /* obj */) {
1368 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1369}
1370
1371static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1372 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1373 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1374 jint unknown_timer) {
1375 if (gnssGeofencingIface != nullptr) {
1376 auto result = gnssGeofencingIface->addGeofence(
1377 geofenceId, latitude, longitude, radius,
1378 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1379 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001380 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001381 } else {
1382 ALOGE("Geofence Interface not available");
1383 }
1384 return JNI_FALSE;
1385}
1386
1387static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1388 jobject /* obj */, jint geofenceId) {
1389 if (gnssGeofencingIface != nullptr) {
1390 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001391 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001392 } else {
1393 ALOGE("Geofence interface not available");
1394 }
1395 return JNI_FALSE;
1396}
1397
1398static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1399 jobject /* obj */, jint geofenceId) {
1400 if (gnssGeofencingIface != nullptr) {
1401 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001402 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001403 } else {
1404 ALOGE("Geofence interface not available");
1405 }
1406 return JNI_FALSE;
1407}
1408
1409static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1410 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1411 if (gnssGeofencingIface != nullptr) {
1412 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001413 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001414 } else {
1415 ALOGE("Geofence interface not available");
1416 }
1417 return JNI_FALSE;
1418}
1419
Lifu Tang30f95a72016-01-07 23:20:38 -08001420static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001421 JNIEnv* env, jclass clazz) {
1422 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001423 return JNI_TRUE;
1424 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001425
destradaaea8a8a62014-06-23 18:19:03 -07001426 return JNI_FALSE;
1427}
1428
Lifu Tang30f95a72016-01-07 23:20:38 -08001429static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001430 JNIEnv* env,
1431 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432 if (gnssMeasurementIface == nullptr) {
1433 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001434 return JNI_FALSE;
1435 }
1436
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001437 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1438 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1439 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1440 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1441 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001442 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001443 } else {
1444 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001445 }
1446
1447 return JNI_TRUE;
1448}
1449
Lifu Tang30f95a72016-01-07 23:20:38 -08001450static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001451 JNIEnv* env,
1452 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001453 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001454 ALOGE("Measurement interface not available");
1455 return JNI_FALSE;
1456 }
1457
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001458 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001459 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001460}
1461
Lifu Tang30f95a72016-01-07 23:20:38 -08001462static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001463 JNIEnv* env,
1464 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001465 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001466 return JNI_TRUE;
1467 }
1468 return JNI_FALSE;
1469}
1470
Lifu Tang30f95a72016-01-07 23:20:38 -08001471static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001472 JNIEnv* env,
1473 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001474 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001475 ALOGE("Navigation Message interface is not available.");
1476 return JNI_FALSE;
1477 }
1478
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001479 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1480 new GnssNavigationMessageCallback();
1481 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1482 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1483
1484 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1485 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001486 return JNI_FALSE;
1487 }
1488
1489 return JNI_TRUE;
1490}
1491
Lifu Tang30f95a72016-01-07 23:20:38 -08001492static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001493 JNIEnv* env,
1494 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001495 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001496 ALOGE("Navigation Message interface is not available.");
1497 return JNI_FALSE;
1498 }
1499
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001500 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001501 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001502}
1503
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001504static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1505 jobject,
1506 jint emergencySuplPdn) {
1507 if (gnssConfigurationIface == nullptr) {
1508 ALOGE("no GNSS configuration interface available");
1509 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001510 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001511
1512 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001513 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001514 return result;
1515 } else {
1516 return JNI_FALSE;
1517 }
1518}
1519
1520static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1521 jobject,
1522 jint version) {
1523 if (gnssConfigurationIface == nullptr) {
1524 ALOGE("no GNSS configuration interface available");
1525 return JNI_FALSE;
1526 }
1527 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001528 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001529 return result;
1530 } else {
1531 return JNI_FALSE;
1532 }
1533}
1534
1535static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1536 jobject,
1537 jint suplEs) {
1538 if (gnssConfigurationIface == nullptr) {
1539 ALOGE("no GNSS configuration interface available");
1540 return JNI_FALSE;
1541 }
1542
1543 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001544 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001545 return result;
1546 } else {
1547 return JNI_FALSE;
1548 }
1549}
1550
1551static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1552 jobject,
1553 jint mode) {
1554 if (gnssConfigurationIface == nullptr) {
1555 ALOGE("no GNSS configuration interface available");
1556 return JNI_FALSE;
1557 }
1558
1559 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001560 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001561 return result;
1562 } else {
1563 return JNI_FALSE;
1564 }
1565}
1566
1567static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1568 jobject,
1569 jint gpsLock) {
1570 if (gnssConfigurationIface == nullptr) {
1571 ALOGE("no GNSS configuration interface available");
1572 return JNI_FALSE;
1573 }
1574
1575 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001576 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001577 return result;
1578 } else {
1579 return JNI_FALSE;
1580 }
1581}
1582
1583static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1584 jobject,
1585 jint lppProfile) {
1586 if (gnssConfigurationIface == nullptr) {
1587 ALOGE("no GNSS configuration interface available");
1588 return JNI_FALSE;
1589 }
1590
1591 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1592
Steven Morelandd002a8b2017-01-03 17:18:24 -08001593 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001594 return result;
1595 } else {
1596 return JNI_FALSE;
1597 }
1598}
1599
1600static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1601 jobject,
1602 jint gnssPosProtocol) {
1603 if (gnssConfigurationIface == nullptr) {
1604 ALOGE("no GNSS configuration interface available");
1605 return JNI_FALSE;
1606 }
1607
1608 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001609 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001610 return result;
1611 } else {
1612 return JNI_FALSE;
1613 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001614}
1615
Daniel Micay76f6a862015-09-19 17:31:01 -04001616static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001618 {"class_init_native", "()V", reinterpret_cast<void *>(
1619 android_location_GnssLocationProvider_class_init_native)},
1620 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1621 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001622 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001623 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001624 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001625 reinterpret_cast<void *>(
1626 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1627 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1628 {"native_cleanup", "()V", reinterpret_cast<void *>(
1629 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001630 {"native_set_position_mode",
1631 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1633 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1634 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001635 {"native_delete_aiding_data",
1636 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001637 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001638 {"native_read_sv_status",
Lifu Tang120480f2016-02-07 18:08:19 -08001639 "([I[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001640 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1641 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1642 android_location_GnssLocationProvider_read_nmea)},
1643 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1644 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001645 {"native_inject_location",
1646 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1648 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1649 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001650 {"native_inject_xtra_data",
1651 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001652 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001653 {"native_agps_data_conn_open",
1654 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001655 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001656 {"native_agps_data_conn_closed",
1657 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001658 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001659 {"native_agps_data_conn_failed",
1660 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001661 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001662 {"native_agps_set_id",
1663 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001664 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001665 {"native_agps_set_ref_location_cellid",
1666 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001667 reinterpret_cast<void *>(
1668 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001669 {"native_set_agps_server",
1670 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001671 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001672 {"native_send_ni_response",
1673 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001674 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001675 {"native_get_internal_state",
1676 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001677 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001678 {"native_update_network_state",
1679 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001681 {"native_is_geofence_supported",
1682 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001684 {"native_add_geofence",
1685 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001686 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001687 {"native_remove_geofence",
1688 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001689 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1690 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1691 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001692 {"native_resume_geofence",
1693 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001695 {"native_is_measurement_supported",
1696 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001697 reinterpret_cast<void *>(
1698 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001699 {"native_start_measurement_collection",
1700 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001701 reinterpret_cast<void *>(
1702 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001703 {"native_stop_measurement_collection",
1704 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 reinterpret_cast<void *>(
1706 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001707 {"native_is_navigation_message_supported",
1708 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001709 reinterpret_cast<void *>(
1710 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001711 {"native_start_navigation_message_collection",
1712 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001713 reinterpret_cast<void *>(
1714 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001715 {"native_stop_navigation_message_collection",
1716 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 reinterpret_cast<void *>(
1718 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1719 {"native_set_supl_es",
1720 "(I)Z",
1721 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1722 {"native_set_supl_version",
1723 "(I)Z",
1724 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1725 {"native_set_supl_mode",
1726 "(I)Z",
1727 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1728 {"native_set_lpp_profile",
1729 "(I)Z",
1730 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1731 {"native_set_gnss_pos_protocol_select",
1732 "(I)Z",
1733 reinterpret_cast<void *>(
1734 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1735 {"native_set_gps_lock",
1736 "(I)Z",
1737 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1738 {"native_set_emergency_supl_pdn",
1739 "(I)Z",
1740 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001741};
1742
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001743int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001744 return jniRegisterNativeMethods(
1745 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001746 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001747 sMethods,
1748 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749}
1750
1751} /* namespace android */