blob: 93c7cd5b9abbc8181be7ed21e8d025d29794e236 [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) {
891 auto result = gnssHal->getExtensionXtra([](const sp<IGnssXtra>& xtraIface) {
892 gnssXtraIface = xtraIface;
893 });
894
Steven Morelandd002a8b2017-01-03 17:18:24 -0800895 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700896 ALOGD("Unable to get a handle to Xtra");
897 }
898
899 result = gnssHal->getExtensionAGnssRil([](const sp<IAGnssRil>& rilIface) {
900 agnssRilIface = rilIface;
901 });
902
Steven Morelandd002a8b2017-01-03 17:18:24 -0800903 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700904 ALOGD("Unable to get a handle to AGnssRil");
905 }
906
907 result = gnssHal->getExtensionAGnss([](const sp<IAGnss>& assistedGnssIface) {
908 agnssIface = assistedGnssIface;
909 });
910
Steven Morelandd002a8b2017-01-03 17:18:24 -0800911 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700912 ALOGD("Unable to get a handle to AGnss");
913 }
914
915 result = gnssHal->getExtensionGnssNavigationMessage(
916 [](const sp<IGnssNavigationMessage>& navigationMessageIface) {
917 gnssNavigationMessageIface = navigationMessageIface;
918 });
919
Steven Morelandd002a8b2017-01-03 17:18:24 -0800920 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700921 ALOGD("Unable to get a handle to GnssNavigationMessage");
922 }
923
924 result = gnssHal->getExtensionGnssMeasurement([](
925 const sp<IGnssMeasurement>& measurementIface) {
926 gnssMeasurementIface = measurementIface;
927 });
Steven Morelandd002a8b2017-01-03 17:18:24 -0800928 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700929 ALOGD("Unable to get a handle to GnssMeasurement");
930 }
931
932 result = gnssHal->getExtensionGnssDebug([](const sp<IGnssDebug>& debugIface) {
933 gnssDebugIface = debugIface;
934 });
Steven Morelandd002a8b2017-01-03 17:18:24 -0800935 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700936 ALOGD("Unable to get a handle to GnssDebug");
937 }
938
939 result = gnssHal->getExtensionGnssNi([](const sp<IGnssNi>& niIface) {
940 gnssNiIface = niIface;
941 });
Steven Morelandd002a8b2017-01-03 17:18:24 -0800942 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943 ALOGD("Unable to get a handle to GnssNi");
944 }
945
946 result = gnssHal->getExtensionGnssConfiguration([](const sp<IGnssConfiguration>& configIface) {
947 gnssConfigurationIface = configIface;
948 });
Steven Morelandd002a8b2017-01-03 17:18:24 -0800949 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700950 ALOGD("Unable to get a handle to GnssConfiguration");
951 }
952
953 result = gnssHal->getExtensionGnssGeofencing([](const sp<IGnssGeofencing>& geofenceIface) {
954 gnssGeofencingIface = geofenceIface;
955 });
Steven Morelandd002a8b2017-01-03 17:18:24 -0800956 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700957 ALOGD("Unable to get a handle to GnssGeofencing");
958 }
959
960 } else {
961 ALOGE("Unable to get GPS service\n");
962 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700963}
964
965static jboolean android_location_GnssLocationProvider_is_supported(
966 JNIEnv* /* env */, jclass /* clazz */) {
967 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
968}
969
970static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
971 JNIEnv* /* env */, jclass /* clazz */) {
972 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
973}
974
975static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
976 JNIEnv* /* env */, jclass /* jclazz */) {
977 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
978}
979
980static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
981 /*
982 * This must be set before calling into the HAL library.
983 */
984 if (!mCallbacksObj)
985 mCallbacksObj = env->NewGlobalRef(obj);
986
987 sp<IGnssCallback> gnssCbIface = new GnssCallback();
988 /*
989 * Fail if the main interface fails to initialize
990 */
991 if (gnssHal == nullptr) {
992 ALOGE("Unable to Initialize GNSS HAL\n");
993 return JNI_FALSE;
994 }
995
996 auto result = gnssHal->setCallback(gnssCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -0800997 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700998 ALOGE("SetCallback for Gnss Interface fails\n");
999 return JNI_FALSE;
1000 }
1001
1002 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1003 if (gnssXtraIface == nullptr) {
1004 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001005 } else {
1006 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001007 if ((!result) || (!result.isOk())) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001008 gnssXtraIface = nullptr;
1009 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1010 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001011 }
1012
1013 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1014 if (agnssIface != nullptr) {
1015 agnssIface->setCallback(aGnssCbIface);
1016 } else {
1017 ALOGE("Unable to Initialize AGnss interface\n");
1018 }
1019
1020 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1021 if (gnssGeofencingIface != nullptr) {
1022 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1023 } else {
1024 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1025 }
1026
1027 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1028 if (gnssNiCbIface != nullptr) {
1029 gnssNiIface->setCallback(gnssNiCbIface);
1030 } else {
1031 ALOGE("Unable to initialize GNSS NI interface\n");
1032 }
1033
1034 return JNI_TRUE;
1035}
1036
1037static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1038 if (gnssHal != nullptr) {
1039 gnssHal->cleanup();
1040 }
1041}
1042
1043static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1044 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1045 jint preferred_time) {
1046 if (gnssHal != nullptr) {
1047 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1048 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1049 min_interval,
1050 preferred_accuracy,
1051 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001052 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001053 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1054 return JNI_FALSE;
1055 } else {
1056 return result;
1057 }
1058 } else {
1059 return JNI_FALSE;
1060 }
1061}
1062
1063static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1064 if (gnssHal != nullptr) {
1065 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001066 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001067 return JNI_FALSE;
1068 } else {
1069 return result;
1070 }
1071 } else {
1072 return JNI_FALSE;
1073 }
1074}
1075
1076static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1077 if (gnssHal != nullptr) {
1078 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001079 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001080 return JNI_FALSE;
1081 } else {
1082 return result;
1083 }
1084 } else {
1085 return JNI_FALSE;
1086 }
1087}
1088static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1089 jobject /* obj */,
1090 jint flags) {
1091 if (gnssHal != nullptr) {
1092 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001093 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001094 ALOGE("Error in deleting aiding data");
1095 }
1096 }
1097}
1098
1099/*
1100 * This enum is used by the read_sv_status method to combine the svid,
1101 * constellation and svFlag fields.
1102 */
1103enum ShiftWidth: uint8_t {
1104 SVID_SHIFT_WIDTH = 7,
1105 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1106};
1107
1108static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1109 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
1110 jfloatArray azumArray) {
1111 /*
1112 * This method should only be called from within a call to reportSvStatus.
1113 */
1114 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1115 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1116 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1117 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
1118
1119 /*
1120 * Read GNSS SV info.
1121 */
1122 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1123 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1124 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1125 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1126 static_cast<uint32_t>(info.svFlag);
1127 cn0s[i] = info.cN0Dbhz;
1128 elev[i] = info.elevationDegrees;
1129 azim[i] = info.azimuthDegrees;
1130 }
1131
1132 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1133 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1134 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1135 env->ReleaseFloatArrayElements(azumArray, azim, 0);
1136 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1137}
1138
1139static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1140 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1141 IAGnssRil::AGnssRefLocation location;
1142
1143 if (agnssRilIface == nullptr) {
1144 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1145 return;
1146 }
1147
1148 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1149 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1150 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1151 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1152 location.cellID.mcc = mcc;
1153 location.cellID.mnc = mnc;
1154 location.cellID.lac = lac;
1155 location.cellID.cid = cid;
1156 break;
1157 default:
1158 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1159 return;
1160 break;
1161 }
1162
1163 agnssRilIface->setRefLocation(location);
1164}
1165
1166static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1167 jint type, jstring setid_string) {
1168 if (agnssRilIface == nullptr) {
1169 ALOGE("no AGPS RIL interface in agps_set_id");
1170 return;
1171 }
1172
1173 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1174 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1175 env->ReleaseStringUTFChars(setid_string, setid);
1176}
1177
1178static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1179 jbyteArray nmeaArray, jint buffer_size) {
1180 // this should only be called from within a call to reportNmea
1181 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1182 int length = GnssCallback::sNmeaStringLength;
1183 if (length > buffer_size)
1184 length = buffer_size;
1185 memcpy(nmea, GnssCallback::sNmeaString, length);
1186 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1187 return (jint) length;
1188}
1189
1190static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1191 jlong time, jlong timeReference, jint uncertainty) {
1192 if (gnssHal != nullptr) {
1193 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001194 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001195 ALOGE("%s: Gnss injectTime() failed", __func__);
1196 }
1197 }
1198}
1199
1200static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1201 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1202 if (gnssHal != nullptr) {
1203 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001204 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001205 ALOGE("%s: Gnss injectLocation() failed", __func__);
1206 }
1207 }
1208}
1209
1210static jboolean android_location_GnssLocationProvider_supports_xtra(
1211 JNIEnv* /* env */, jobject /* obj */) {
1212 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1213}
1214
1215static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1216 jbyteArray data, jint length) {
1217 if (gnssXtraIface == nullptr) {
1218 ALOGE("XTRA Interface not supported");
1219 return;
1220 }
1221
1222 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1223 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1224 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1225}
1226
1227static void android_location_GnssLocationProvider_agps_data_conn_open(
1228 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1229 if (agnssIface == nullptr) {
1230 ALOGE("no AGPS interface in agps_data_conn_open");
1231 return;
1232 }
1233 if (apn == NULL) {
1234 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1235 return;
1236 }
1237
1238 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1239
1240 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001241 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001242 ALOGE("%s: Failed to set APN and its IP type", __func__);
1243 }
1244 env->ReleaseStringUTFChars(apn, apnStr);
1245}
1246
1247static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1248 jobject /* obj */) {
1249 if (agnssIface == nullptr) {
1250 ALOGE("%s: AGPS interface not supported", __func__);
1251 return;
1252 }
1253
1254 auto result = agnssIface->dataConnClosed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001255 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001256 ALOGE("%s: Failed to close AGnss data connection", __func__);
1257 }
1258}
1259
1260static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1261 jobject /* obj */) {
1262 if (agnssIface == nullptr) {
1263 ALOGE("%s: AGPS interface not supported", __func__);
1264 return;
1265 }
1266
1267 auto result = agnssIface->dataConnFailed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001268 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001269 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1270 }
1271}
1272
1273static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1274 jint type, jstring hostname, jint port) {
1275 if (agnssIface == nullptr) {
1276 ALOGE("no AGPS interface in set_agps_server");
1277 return;
1278 }
1279
1280 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1281 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1282 c_hostname,
1283 port);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001284 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001285 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1286 }
1287
1288 env->ReleaseStringUTFChars(hostname, c_hostname);
1289}
1290
1291static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1292 jobject /* obj */, jint notifId, jint response) {
1293 if (gnssNiIface == nullptr) {
1294 ALOGE("no NI interface in send_ni_response");
1295 return;
1296 }
1297
1298 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1299}
1300
1301static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1302 jobject /* obj */) {
1303 jstring result = NULL;
1304 /*
1305 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1306 */
1307 if (gnssDebugIface != nullptr) {
1308 IGnssDebug::DebugData data;
1309 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1310 data = debugData;
1311 });
1312
1313 std::stringstream internalState;
1314 if (data.position.valid) {
1315 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1316 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1317 << ", altitudeMeters: " << data.position.altitudeMeters
1318 << ", accuracyMeters: " << data.position.accuracyMeters
1319 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1320 }
1321
1322 if (data.time.valid) {
1323 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1324 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1325 }
1326
1327 if (data.satelliteDataArray.size() != 0) {
1328 internalState << "Satellite Data:: ";
1329 }
1330
1331 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1332 internalState << "svid: " << data.satelliteDataArray[i].svid
1333 << ", constellation: "
1334 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1335 << ", ephemerisType: "
1336 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1337 << ", ephemerisAgeSeconds: "
1338 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1339 }
1340 result = env->NewStringUTF(internalState.str().c_str());
1341 }
1342 return result;
1343}
1344
1345static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1346 jobject /* obj */,
1347 jboolean connected,
1348 jint type,
1349 jboolean roaming,
1350 jboolean available,
1351 jstring extraInfo,
1352 jstring apn) {
1353 if (agnssRilIface != nullptr) {
1354 auto result = agnssRilIface->updateNetworkState(connected,
1355 static_cast<IAGnssRil::NetworkType>(type),
1356 roaming);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001357 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001358 ALOGE("updateNetworkState failed");
1359 }
1360
1361 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1362 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001363 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001364 ALOGE("updateNetworkAvailability failed");
1365 }
1366
1367 env->ReleaseStringUTFChars(apn, c_apn);
1368 } else {
1369 ALOGE("AGnssRilInterface does not exist");
1370 }
1371}
1372
1373static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1374 JNIEnv* /* env */, jobject /* obj */) {
1375 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1376}
1377
1378static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1379 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1380 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1381 jint unknown_timer) {
1382 if (gnssGeofencingIface != nullptr) {
1383 auto result = gnssGeofencingIface->addGeofence(
1384 geofenceId, latitude, longitude, radius,
1385 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1386 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001387 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001388 } else {
1389 ALOGE("Geofence Interface not available");
1390 }
1391 return JNI_FALSE;
1392}
1393
1394static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1395 jobject /* obj */, jint geofenceId) {
1396 if (gnssGeofencingIface != nullptr) {
1397 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001398 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001399 } else {
1400 ALOGE("Geofence interface not available");
1401 }
1402 return JNI_FALSE;
1403}
1404
1405static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1406 jobject /* obj */, jint geofenceId) {
1407 if (gnssGeofencingIface != nullptr) {
1408 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001409 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001410 } else {
1411 ALOGE("Geofence interface not available");
1412 }
1413 return JNI_FALSE;
1414}
1415
1416static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1417 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1418 if (gnssGeofencingIface != nullptr) {
1419 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001420 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001421 } else {
1422 ALOGE("Geofence interface not available");
1423 }
1424 return JNI_FALSE;
1425}
1426
Lifu Tang30f95a72016-01-07 23:20:38 -08001427static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001428 JNIEnv* env, jclass clazz) {
1429 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001430 return JNI_TRUE;
1431 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432
destradaaea8a8a62014-06-23 18:19:03 -07001433 return JNI_FALSE;
1434}
1435
Lifu Tang30f95a72016-01-07 23:20:38 -08001436static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001437 JNIEnv* env,
1438 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001439 if (gnssMeasurementIface == nullptr) {
1440 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001441 return JNI_FALSE;
1442 }
1443
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001444 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1445 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1446 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1447 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1448 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001449 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001450 } else {
1451 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001452 }
1453
1454 return JNI_TRUE;
1455}
1456
Lifu Tang30f95a72016-01-07 23:20:38 -08001457static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001458 JNIEnv* env,
1459 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001460 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001461 ALOGE("Measurement interface not available");
1462 return JNI_FALSE;
1463 }
1464
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001465 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001466 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001467}
1468
Lifu Tang30f95a72016-01-07 23:20:38 -08001469static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001470 JNIEnv* env,
1471 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001472 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001473 return JNI_TRUE;
1474 }
1475 return JNI_FALSE;
1476}
1477
Lifu Tang30f95a72016-01-07 23:20:38 -08001478static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001479 JNIEnv* env,
1480 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001481 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001482 ALOGE("Navigation Message interface is not available.");
1483 return JNI_FALSE;
1484 }
1485
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001486 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1487 new GnssNavigationMessageCallback();
1488 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1489 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1490
1491 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1492 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001493 return JNI_FALSE;
1494 }
1495
1496 return JNI_TRUE;
1497}
1498
Lifu Tang30f95a72016-01-07 23:20:38 -08001499static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001500 JNIEnv* env,
1501 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001502 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001503 ALOGE("Navigation Message interface is not available.");
1504 return JNI_FALSE;
1505 }
1506
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001507 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001508 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001509}
1510
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001511static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1512 jobject,
1513 jint emergencySuplPdn) {
1514 if (gnssConfigurationIface == nullptr) {
1515 ALOGE("no GNSS configuration interface available");
1516 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001517 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001518
1519 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001520 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001521 return result;
1522 } else {
1523 return JNI_FALSE;
1524 }
1525}
1526
1527static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1528 jobject,
1529 jint version) {
1530 if (gnssConfigurationIface == nullptr) {
1531 ALOGE("no GNSS configuration interface available");
1532 return JNI_FALSE;
1533 }
1534 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001535 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001536 return result;
1537 } else {
1538 return JNI_FALSE;
1539 }
1540}
1541
1542static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1543 jobject,
1544 jint suplEs) {
1545 if (gnssConfigurationIface == nullptr) {
1546 ALOGE("no GNSS configuration interface available");
1547 return JNI_FALSE;
1548 }
1549
1550 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001551 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001552 return result;
1553 } else {
1554 return JNI_FALSE;
1555 }
1556}
1557
1558static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1559 jobject,
1560 jint mode) {
1561 if (gnssConfigurationIface == nullptr) {
1562 ALOGE("no GNSS configuration interface available");
1563 return JNI_FALSE;
1564 }
1565
1566 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001567 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001568 return result;
1569 } else {
1570 return JNI_FALSE;
1571 }
1572}
1573
1574static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1575 jobject,
1576 jint gpsLock) {
1577 if (gnssConfigurationIface == nullptr) {
1578 ALOGE("no GNSS configuration interface available");
1579 return JNI_FALSE;
1580 }
1581
1582 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001583 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001584 return result;
1585 } else {
1586 return JNI_FALSE;
1587 }
1588}
1589
1590static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1591 jobject,
1592 jint lppProfile) {
1593 if (gnssConfigurationIface == nullptr) {
1594 ALOGE("no GNSS configuration interface available");
1595 return JNI_FALSE;
1596 }
1597
1598 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1599
Steven Morelandd002a8b2017-01-03 17:18:24 -08001600 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001601 return result;
1602 } else {
1603 return JNI_FALSE;
1604 }
1605}
1606
1607static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1608 jobject,
1609 jint gnssPosProtocol) {
1610 if (gnssConfigurationIface == nullptr) {
1611 ALOGE("no GNSS configuration interface available");
1612 return JNI_FALSE;
1613 }
1614
1615 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001616 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001617 return result;
1618 } else {
1619 return JNI_FALSE;
1620 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001621}
1622
Daniel Micay76f6a862015-09-19 17:31:01 -04001623static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001624 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001625 {"class_init_native", "()V", reinterpret_cast<void *>(
1626 android_location_GnssLocationProvider_class_init_native)},
1627 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1628 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001629 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001630 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001631 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 reinterpret_cast<void *>(
1633 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1634 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1635 {"native_cleanup", "()V", reinterpret_cast<void *>(
1636 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001637 {"native_set_position_mode",
1638 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001639 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1640 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1641 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001642 {"native_delete_aiding_data",
1643 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001644 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001645 {"native_read_sv_status",
Lifu Tang120480f2016-02-07 18:08:19 -08001646 "([I[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1648 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1649 android_location_GnssLocationProvider_read_nmea)},
1650 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1651 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001652 {"native_inject_location",
1653 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001654 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1655 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1656 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001657 {"native_inject_xtra_data",
1658 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001659 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001660 {"native_agps_data_conn_open",
1661 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001662 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001663 {"native_agps_data_conn_closed",
1664 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001665 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001666 {"native_agps_data_conn_failed",
1667 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001668 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001669 {"native_agps_set_id",
1670 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001671 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001672 {"native_agps_set_ref_location_cellid",
1673 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001674 reinterpret_cast<void *>(
1675 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001676 {"native_set_agps_server",
1677 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001678 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001679 {"native_send_ni_response",
1680 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001681 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001682 {"native_get_internal_state",
1683 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001684 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001685 {"native_update_network_state",
1686 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001687 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001688 {"native_is_geofence_supported",
1689 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001690 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001691 {"native_add_geofence",
1692 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001694 {"native_remove_geofence",
1695 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001696 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1697 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1698 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001699 {"native_resume_geofence",
1700 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001701 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001702 {"native_is_measurement_supported",
1703 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001704 reinterpret_cast<void *>(
1705 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001706 {"native_start_measurement_collection",
1707 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001708 reinterpret_cast<void *>(
1709 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001710 {"native_stop_measurement_collection",
1711 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001712 reinterpret_cast<void *>(
1713 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001714 {"native_is_navigation_message_supported",
1715 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001716 reinterpret_cast<void *>(
1717 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001718 {"native_start_navigation_message_collection",
1719 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001720 reinterpret_cast<void *>(
1721 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001722 {"native_stop_navigation_message_collection",
1723 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001724 reinterpret_cast<void *>(
1725 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1726 {"native_set_supl_es",
1727 "(I)Z",
1728 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1729 {"native_set_supl_version",
1730 "(I)Z",
1731 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1732 {"native_set_supl_mode",
1733 "(I)Z",
1734 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1735 {"native_set_lpp_profile",
1736 "(I)Z",
1737 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1738 {"native_set_gnss_pos_protocol_select",
1739 "(I)Z",
1740 reinterpret_cast<void *>(
1741 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1742 {"native_set_gps_lock",
1743 "(I)Z",
1744 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1745 {"native_set_emergency_supl_pdn",
1746 "(I)Z",
1747 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001748};
1749
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001751 return jniRegisterNativeMethods(
1752 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001753 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001754 sMethods,
1755 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756}
1757
1758} /* namespace android */