blob: b0a4297da86e56dad86b7e535ef9a24b1ac33a25 [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
23#include <hwbinder/IPCThreadState.h>
24#include <hwbinder/ProcessState.h>
25
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026#include "JNIHelp.h"
27#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040028#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029#include "utils/Log.h"
30#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070031#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070032#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
destradaa931a37f2014-08-12 16:36:59 -070034#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <limits>
destradaa96a14702014-06-05 11:36:30 -070036#include <linux/in.h>
37#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080038#include <pthread.h>
39#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070040#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Mike Lockwoodf602d362010-06-20 14:28:16 -070042static jobject mCallbacksObj = NULL;
43
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044static jmethodID method_reportLocation;
45static jmethodID method_reportStatus;
46static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040047static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040048static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040049static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080050static jmethodID method_setGnssYearOfHardware;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040052static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020053static jmethodID method_requestRefLocation;
54static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040055static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070056static jmethodID method_reportGeofenceTransition;
57static jmethodID method_reportGeofenceStatus;
58static jmethodID method_reportGeofenceAddStatus;
59static jmethodID method_reportGeofenceRemoveStatus;
60static jmethodID method_reportGeofencePauseStatus;
61static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070062static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070063static jmethodID method_reportNavigationMessages;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070065using android::OK;
66using android::sp;
67using android::status_t;
68using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070070using android::hardware::IPCThreadState;
71using android::hardware::ProcessState;
72using android::hardware::Return;
73using android::hardware::Void;
74using android::hardware::hidl_vec;
Lifu Tang30f95a72016-01-07 23:20:38 -080075
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070076using android::hardware::gnss::V1_0::IAGnss;
77using android::hardware::gnss::V1_0::IAGnssCallback;
78using android::hardware::gnss::V1_0::IAGnssCallback;
79using android::hardware::gnss::V1_0::IAGnssRil;
80using android::hardware::gnss::V1_0::IAGnssRilCallback;
81using android::hardware::gnss::V1_0::IGnss;
82using android::hardware::gnss::V1_0::IGnssCallback;
83using android::hardware::gnss::V1_0::IGnssConfiguration;
84using android::hardware::gnss::V1_0::IGnssDebug;
85using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
86using android::hardware::gnss::V1_0::IGnssGeofencing;
87using android::hardware::gnss::V1_0::IGnssMeasurement;
88using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
89using android::hardware::gnss::V1_0::IGnssNavigationMessage;
90using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
91using android::hardware::gnss::V1_0::IGnssNi;
92using android::hardware::gnss::V1_0::IGnssNiCallback;
93using android::hardware::gnss::V1_0::IGnssXtra;
94using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -070095
Wyatt Rileyf6527ae2016-05-23 15:23:12 -070096
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070097sp<IGnss> gnssHal = nullptr;
98sp<IGnssXtra> gnssXtraIface = nullptr;
99sp<IAGnssRil> agnssRilIface = nullptr;
100sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
101sp<IAGnss> agnssIface = nullptr;
102sp<IGnssDebug> gnssDebugIface = nullptr;
103sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
104sp<IGnssNi> gnssNiIface = nullptr;
105sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
106sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400108#define WAKE_LOCK_NAME "GPS"
109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110namespace android {
111
Lifu Tang120480f2016-02-07 18:08:19 -0800112template<class T>
113class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700114 public:
115 // Helper function to call setter on a Java object.
116 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800117 JNIEnv* env,
118 jclass clazz,
119 jobject object,
120 const char* method_name,
121 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700122
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700123 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800124 static const char *const signature_;
125};
Lifu Tange5a0e212016-01-25 18:02:17 -0800126
Lifu Tang120480f2016-02-07 18:08:19 -0800127template<class T>
128void JavaMethodHelper<T>::callJavaMethod(
129 JNIEnv* env,
130 jclass clazz,
131 jobject object,
132 const char* method_name,
133 T value) {
134 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
135 env->CallVoidMethod(object, method, value);
136}
destradaaea8a8a62014-06-23 18:19:03 -0700137
Lifu Tang120480f2016-02-07 18:08:19 -0800138class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700139 public:
140 JavaObject(JNIEnv* env, const char* class_name);
141 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800142
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700143 template<class T>
144 void callSetter(const char* method_name, T value);
145 template<class T>
146 void callSetter(const char* method_name, T* value, size_t size);
147 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800148
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700149 private:
150 JNIEnv* env_;
151 jclass clazz_;
152 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800153};
154
155JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
156 clazz_ = env_->FindClass(class_name);
157 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
158 object_ = env_->NewObject(clazz_, ctor);
159}
160
161JavaObject::~JavaObject() {
162 env_->DeleteLocalRef(clazz_);
163}
164
165template<class T>
166void JavaObject::callSetter(const char* method_name, T value) {
167 JavaMethodHelper<T>::callJavaMethod(
168 env_, clazz_, object_, method_name, value);
169}
170
171template<>
172void JavaObject::callSetter(
173 const char* method_name, uint8_t* value, size_t size) {
174 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700175 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800176 jmethodID method = env_->GetMethodID(
177 clazz_,
178 method_name,
179 "([B)V");
180 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700181 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800182}
183
184jobject JavaObject::get() {
185 return object_;
186}
187
188// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800189template<>
190const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
191template<>
192const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
193template<>
194const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
195template<>
196const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
197template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800198const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
199template<>
200const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800201template<>
202const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
203template<>
204const char *const JavaMethodHelper<float>::signature_ = "(F)V";
205template<>
206const char *const JavaMethodHelper<double>::signature_ = "(D)V";
207template<>
208const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
209
210#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800211
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700212static inline jboolean boolToJbool(bool value) {
213 return value ? JNI_TRUE : JNI_FALSE;
214}
Lifu Tang120480f2016-02-07 18:08:19 -0800215
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700216static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
217 if (env->ExceptionCheck()) {
218 ALOGE("An exception was thrown by callback '%s'.", methodName);
219 LOGE_EX(env);
220 env->ExceptionClear();
221 }
222}
destradaaea8a8a62014-06-23 18:19:03 -0700223
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700224/*
225 * GnssCallback class implements the callback methods for IGnss interface.
226 */
227struct GnssCallback : public IGnssCallback {
228 Return<void> gnssLocationCb(
229 const android::hardware::gnss::V1_0::GnssLocation& location) override;
230 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
231 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
232 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
233 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
234 Return<void> gnssAcquireWakelockCb() override;
235 Return<void> gnssReleaseWakelockCb() override;
236 Return<void> gnssRequestTimeCb() override;
237 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800238
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700239 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
240 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
241 static size_t sGnssSvListSize;
242
243 static const char* sNmeaString;
244 static size_t sNmeaStringLength;
245};
246
247IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
248 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
249const char* GnssCallback::sNmeaString = nullptr;
250size_t GnssCallback::sNmeaStringLength = 0;
251size_t GnssCallback::sGnssSvListSize = 0;
252
253Return<void> GnssCallback::gnssLocationCb(
254 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
255 JNIEnv* env = AndroidRuntime::getJNIEnv();
256 env->CallVoidMethod(mCallbacksObj,
257 method_reportLocation,
258 location.gnssLocationFlags,
259 static_cast<jdouble>(location.latitudeDegrees),
260 static_cast<jdouble>(location.longitudeDegrees),
261 static_cast<jdouble>(location.altitudeMeters),
262 static_cast<jfloat>(location.speedMetersPerSec),
263 static_cast<jfloat>(location.bearingDegrees),
264 static_cast<jfloat>(location.accuracyMeters),
265 static_cast<jlong>(location.timestamp));
266 checkAndClearExceptionFromCallback(env, __FUNCTION__);
267 return Void();
268}
269
270Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
271 JNIEnv* env = AndroidRuntime::getJNIEnv();
272 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
273 checkAndClearExceptionFromCallback(env, __FUNCTION__);
274 return Void();
275}
276
277Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
278 JNIEnv* env = AndroidRuntime::getJNIEnv();
279
280 sGnssSvListSize = svStatus.numSvs;
281 if (sGnssSvListSize > static_cast<uint32_t>(
282 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
283 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
284 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
285 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800286 }
287
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700288 // Copy GNSS SV info into sGnssSvList, if any.
289 if (svStatus.numSvs > 0) {
290 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800291 }
destradaaea8a8a62014-06-23 18:19:03 -0700292
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700293 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
294 checkAndClearExceptionFromCallback(env, __FUNCTION__);
295 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700296}
297
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700298Return<void> GnssCallback::gnssNmeaCb(
299 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
300 JNIEnv* env = AndroidRuntime::getJNIEnv();
301 /*
302 * The Java code will call back to read these values.
303 * We do this to avoid creating unnecessary String objects.
304 */
305 sNmeaString = nmea.c_str();
306 sNmeaStringLength = nmea.size();
307
308 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
309 checkAndClearExceptionFromCallback(env, __FUNCTION__);
310 return Void();
311}
312
313Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
314 ALOGD("%s: %du\n", __func__, capabilities);
315
316 JNIEnv* env = AndroidRuntime::getJNIEnv();
317 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
318 checkAndClearExceptionFromCallback(env, __FUNCTION__);
319 return Void();
320}
321
322Return<void> GnssCallback::gnssAcquireWakelockCb() {
323 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
324 return Void();
325}
326
327Return<void> GnssCallback::gnssReleaseWakelockCb() {
328 release_wake_lock(WAKE_LOCK_NAME);
329 return Void();
330}
331
332Return<void> GnssCallback::gnssRequestTimeCb() {
333 JNIEnv* env = AndroidRuntime::getJNIEnv();
334 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
335 checkAndClearExceptionFromCallback(env, __FUNCTION__);
336 return Void();
337}
338
339Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
340 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
341
342 JNIEnv* env = AndroidRuntime::getJNIEnv();
343 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
344 info.yearOfHw);
345 checkAndClearExceptionFromCallback(env, __FUNCTION__);
346 return Void();
347}
348
349class GnssXtraCallback : public IGnssXtraCallback {
350 Return<void> downloadRequestCb() override;
351};
352
353/*
354 * GnssXtraCallback class implements the callback methods for the IGnssXtra
355 * interface.
356 */
357Return<void> GnssXtraCallback::downloadRequestCb() {
358 JNIEnv* env = AndroidRuntime::getJNIEnv();
359 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
360 checkAndClearExceptionFromCallback(env, __FUNCTION__);
361 return Void();
362}
363
364/*
365 * GnssGeofenceCallback class implements the callback methods for the
366 * IGnssGeofence interface.
367 */
368struct GnssGeofenceCallback : public IGnssGeofenceCallback {
369 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
370 Return<void> gnssGeofenceTransitionCb(
371 int32_t geofenceId,
372 const android::hardware::gnss::V1_0::GnssLocation& location,
373 GeofenceTransition transition,
374 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
375 Return<void> gnssGeofenceStatusCb(
376 GeofenceAvailability status,
377 const android::hardware::gnss::V1_0::GnssLocation& location) override;
378 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
379 GeofenceStatus status) override;
380 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
381 GeofenceStatus status) override;
382 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
383 GeofenceStatus status) override;
384 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
385 GeofenceStatus status) override;
386};
387
388Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
389 int32_t geofenceId,
390 const android::hardware::gnss::V1_0::GnssLocation& location,
391 GeofenceTransition transition,
392 hardware::gnss::V1_0::GnssUtcTime timestamp) {
393 JNIEnv* env = AndroidRuntime::getJNIEnv();
394
395 env->CallVoidMethod(mCallbacksObj,
396 method_reportGeofenceTransition,
397 geofenceId,
398 location.gnssLocationFlags,
399 static_cast<jdouble>(location.latitudeDegrees),
400 static_cast<jdouble>(location.longitudeDegrees),
401 static_cast<jdouble>(location.altitudeMeters),
402 static_cast<jfloat>(location.speedMetersPerSec),
403 static_cast<jfloat>(location.bearingDegrees),
404 static_cast<jfloat>(location.accuracyMeters),
405 static_cast<jlong>(location.timestamp),
406 transition,
407 timestamp);
408
409 checkAndClearExceptionFromCallback(env, __FUNCTION__);
410 return Void();
411}
412
413Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
414 GeofenceAvailability status,
415 const android::hardware::gnss::V1_0::GnssLocation& location) {
416 JNIEnv* env = AndroidRuntime::getJNIEnv();
417 env->CallVoidMethod(mCallbacksObj,
418 method_reportGeofenceStatus,
419 status,
420 location.gnssLocationFlags,
421 static_cast<jdouble>(location.latitudeDegrees),
422 static_cast<jdouble>(location.longitudeDegrees),
423 static_cast<jdouble>(location.altitudeMeters),
424 static_cast<jfloat>(location.speedMetersPerSec),
425 static_cast<jfloat>(location.bearingDegrees),
426 static_cast<jfloat>(location.accuracyMeters),
427 static_cast<jlong>(location.timestamp));
428 checkAndClearExceptionFromCallback(env, __FUNCTION__);
429 return Void();
430}
431
432Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
433 GeofenceStatus status) {
434 JNIEnv* env = AndroidRuntime::getJNIEnv();
435 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
436 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
437 }
438
439 env->CallVoidMethod(mCallbacksObj,
440 method_reportGeofenceAddStatus,
441 geofenceId,
442 status);
443 checkAndClearExceptionFromCallback(env, __FUNCTION__);
444 return Void();
445}
446
447Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
448 GeofenceStatus status) {
449 JNIEnv* env = AndroidRuntime::getJNIEnv();
450 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
451 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
452 }
453
454 env->CallVoidMethod(mCallbacksObj,
455 method_reportGeofenceRemoveStatus,
456 geofenceId, status);
457 checkAndClearExceptionFromCallback(env, __FUNCTION__);
458 return Void();
459}
460
461Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
462 GeofenceStatus status) {
463 JNIEnv* env = AndroidRuntime::getJNIEnv();
464 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
465 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
466 }
467
468 env->CallVoidMethod(mCallbacksObj,
469 method_reportGeofencePauseStatus,
470 geofenceId, status);
471 checkAndClearExceptionFromCallback(env, __FUNCTION__);
472 return Void();
473}
474
475Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
476 GeofenceStatus status) {
477 JNIEnv* env = AndroidRuntime::getJNIEnv();
478 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
479 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
480 }
481
482 env->CallVoidMethod(mCallbacksObj,
483 method_reportGeofenceResumeStatus,
484 geofenceId, status);
485 checkAndClearExceptionFromCallback(env, __FUNCTION__);
486 return Void();
487}
488
489/*
490 * GnssNavigationMessageCallback interface implements the callback methods
491 * required by the IGnssNavigationMessage interface.
492 */
493struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
494 /*
495 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
496 * follow.
497 */
498 Return<void> gnssNavigationMessageCb(
499 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
500};
501
502Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
503 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
504 JNIEnv* env = AndroidRuntime::getJNIEnv();
505
506 size_t dataLength = message.data.size();
507
508 std::vector<uint8_t> navigationData = message.data;
509 uint8_t* data = &(navigationData[0]);
510 if (dataLength == 0 || data == NULL) {
511 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
512 dataLength);
513 return Void();
514 }
515
516 JavaObject object(env, "android/location/GnssNavigationMessage");
517 SET(Type, static_cast<int32_t>(message.type));
518 SET(Svid, static_cast<int32_t>(message.svid));
519 SET(MessageId, static_cast<int32_t>(message.messageId));
520 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
521 object.callSetter("setData", data, dataLength);
522 SET(Status, static_cast<int32_t>(message.status));
523
524 jobject navigationMessage = object.get();
525 env->CallVoidMethod(mCallbacksObj,
526 method_reportNavigationMessages,
527 navigationMessage);
528 env->DeleteLocalRef(navigationMessage);
529 return Void();
530}
531
532/*
533 * GnssMeasurementCallback implements the callback methods required for the
534 * GnssMeasurement interface.
535 */
536struct GnssMeasurementCallback : public IGnssMeasurementCallback {
537 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
538 private:
539 jobject translateGnssMeasurement(
540 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
541 jobject translateGnssClock(
542 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
543 jobjectArray translateGnssMeasurements(
544 JNIEnv* env,
545 const IGnssMeasurementCallback::GnssMeasurement* measurements,
546 size_t count);
547 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
548};
549
550
551Return<void> GnssMeasurementCallback::GnssMeasurementCb(
552 const IGnssMeasurementCallback::GnssData& data) {
553 JNIEnv* env = AndroidRuntime::getJNIEnv();
554
555 jobject clock;
556 jobjectArray measurementArray;
557
558 clock = translateGnssClock(env, &data.clock);
559 measurementArray = translateGnssMeasurements(
560 env, data.measurements.data(), data.measurementCount);
561 setMeasurementData(env, clock, measurementArray);
562
563 env->DeleteLocalRef(clock);
564 env->DeleteLocalRef(measurementArray);
565 return Void();
566}
567
568jobject GnssMeasurementCallback::translateGnssMeasurement(
569 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800570 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800571
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700572 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700573
574 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800575 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700576 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800577 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700578 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800579 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700580 measurement->receivedSvTimeUncertaintyInNs);
581 SET(Cn0DbHz, measurement->cN0DbHz);
582 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800583 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700584 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800585 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700586 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
587 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800588 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700589 measurement->accumulatedDeltaRangeUncertaintyM);
590
591 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
592 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
593 }
594
595 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
596 SET(CarrierPhase, measurement->carrierPhase);
597 }
598
599 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
600 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
601 }
602
603 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
604
605 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
606 SET(SnrInDb, measurement->snrDb);
607 }
Lifu Tang120480f2016-02-07 18:08:19 -0800608
609 return object.get();
610}
611
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700612jobject GnssMeasurementCallback::translateGnssClock(
613 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
614 JavaObject object(env, "android/location/GnssClock");
615
616 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
617 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
618 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
619 }
620
621 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
622 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
623 }
624
625 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
626 SET(FullBiasNanos, clock->fullBiasNs);
627 }
628
629 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
630 SET(BiasNanos, clock->biasNs);
631 }
632
633 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
634 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
635 }
636
637 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
638 SET(DriftNanosPerSecond, clock->driftNsps);
639 }
640
641 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
642 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
643 }
644
645 SET(TimeNanos, clock->timeNs);
646 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
647
648 return object.get();
649}
650
651jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
652 const IGnssMeasurementCallback::GnssMeasurement*
653 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800654 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700655 return NULL;
656 }
657
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700658 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800659 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800660 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800661 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700662 NULL /* initialElement */);
663
Lifu Tang120480f2016-02-07 18:08:19 -0800664 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700665 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800666 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800667 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800668 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
669 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700670 }
671
Lifu Tang818aa2c2016-02-01 01:52:00 -0800672 env->DeleteLocalRef(gnssMeasurementClass);
673 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700674}
675
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700676void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
677 jobjectArray measurementArray) {
678 jclass gnssMeasurementsEventClass =
679 env->FindClass("android/location/GnssMeasurementsEvent");
680 jmethodID gnssMeasurementsEventCtor =
681 env->GetMethodID(
682 gnssMeasurementsEventClass,
683 "<init>",
684 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800685
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700686 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
687 gnssMeasurementsEventCtor,
688 clock,
689 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800690
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700691 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
692 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800693 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800694 env->DeleteLocalRef(gnssMeasurementsEventClass);
695 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700696}
697
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698/*
699 * GnssNiCallback implements callback methods required by the IGnssNi interface.
700 */
701struct GnssNiCallback : public IGnssNiCallback {
702 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
703 override;
destradaaea8a8a62014-06-23 18:19:03 -0700704};
705
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700706Return<void> GnssNiCallback::niNotifyCb(
707 const IGnssNiCallback::GnssNiNotification& notification) {
708 JNIEnv* env = AndroidRuntime::getJNIEnv();
709 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
710 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
711
712 if (requestorId && text) {
713 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
714 notification.notificationId, notification.niType,
715 notification.notifyFlags, notification.timeoutSec,
716 notification.defaultResponse, requestorId, text,
717 notification.requestorIdEncoding,
718 notification.notificationIdEncoding);
719 } else {
720 ALOGE("%s: OOM Error\n", __func__);
721 }
722
723 if (requestorId) {
724 env->DeleteLocalRef(requestorId);
725 }
726
727 if (text) {
728 env->DeleteLocalRef(text);
729 }
730 checkAndClearExceptionFromCallback(env, __FUNCTION__);
731 return Void();
732}
733
734/*
735 * AGnssCallback implements callback methods required by the IAGnss interface.
736 */
737struct AGnssCallback : public IAGnssCallback {
738 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
739 Return<void> agnssStatusIpV6Cb(
740 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
741
742 Return<void> agnssStatusIpV4Cb(
743 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
744 private:
745 jbyteArray convertToIpV4(uint32_t ip);
746};
747
748Return<void> AGnssCallback::agnssStatusIpV6Cb(
749 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
750 JNIEnv* env = AndroidRuntime::getJNIEnv();
751 jbyteArray byteArray = NULL;
752 bool isSupported = false;
753
754 byteArray = env->NewByteArray(16);
755 if (byteArray != NULL) {
756 env->SetByteArrayRegion(byteArray, 0, 16,
757 (const jbyte*)(agps_status.ipV6Addr.data()));
758 isSupported = true;
759 } else {
760 ALOGE("Unable to allocate byte array for IPv6 address.");
761 }
762
763 IF_ALOGD() {
764 // log the IP for reference in case there is a bogus value pushed by HAL
765 char str[INET6_ADDRSTRLEN];
766 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
767 ALOGD("AGPS IP is v6: %s", str);
768 }
769
770 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
771 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
772 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
773 agps_status.type, agps_status.status, byteArray);
774
775 checkAndClearExceptionFromCallback(env, __FUNCTION__);
776
777 if (byteArray) {
778 env->DeleteLocalRef(byteArray);
779 }
780
781 return Void();
782}
783
784Return<void> AGnssCallback::agnssStatusIpV4Cb(
785 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
786 JNIEnv* env = AndroidRuntime::getJNIEnv();
787 jbyteArray byteArray = NULL;
788
789 uint32_t ipAddr = agps_status.ipV4Addr;
790 byteArray = convertToIpV4(ipAddr);
791
792 IF_ALOGD() {
793 /*
794 * log the IP for reference in case there is a bogus value pushed by
795 * HAL.
796 */
797 char str[INET_ADDRSTRLEN];
798 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
799 ALOGD("AGPS IP is v4: %s", str);
800 }
801
802 jsize byteArrayLength =
803 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
804 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
805 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
806 agps_status.type, agps_status.status, byteArray);
807
808 checkAndClearExceptionFromCallback(env, __FUNCTION__);
809
810 if (byteArray) {
811 env->DeleteLocalRef(byteArray);
812 }
813 return Void();
814}
815
816jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
817 if (INADDR_NONE == ip) {
818 return NULL;
819 }
820
821 JNIEnv* env = AndroidRuntime::getJNIEnv();
822 jbyteArray byteArray = env->NewByteArray(4);
823 if (byteArray == NULL) {
824 ALOGE("Unable to allocate byte array for IPv4 address");
825 return NULL;
826 }
827
828 jbyte ipv4[4];
829 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
830 memcpy(ipv4, &ip, sizeof(ipv4));
831 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
832 return byteArray;
833}
834
835/*
836 * AGnssRilCallback implements the callback methods required by the AGnssRil
837 * interface.
838 */
839struct AGnssRilCallback : IAGnssRilCallback {
840 Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override;
841 Return<void> requestRefLocCb() override;
842};
843
844Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) {
845 JNIEnv* env = AndroidRuntime::getJNIEnv();
846 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
847 checkAndClearExceptionFromCallback(env, __FUNCTION__);
848 return Void();
849}
850
851Return<void> AGnssRilCallback::requestRefLocCb() {
852 JNIEnv* env = AndroidRuntime::getJNIEnv();
853 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
854 checkAndClearExceptionFromCallback(env, __FUNCTION__);
855 return Void();
856}
857
858static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
859 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
860 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
861 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
862 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
863 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
864 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
865 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
866 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
867 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
868 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
869 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
870 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
871 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
872 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
873 "(IIDDDFFFJIJ)V");
874 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
875 "(IIDDDFFFJ)V");
876 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
877 "(II)V");
878 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
879 "(II)V");
880 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
881 "(II)V");
882 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
883 "(II)V");
884 method_reportMeasurementData = env->GetMethodID(
885 clazz,
886 "reportMeasurementData",
887 "(Landroid/location/GnssMeasurementsEvent;)V");
888 method_reportNavigationMessages = env->GetMethodID(
889 clazz,
890 "reportNavigationMessage",
891 "(Landroid/location/GnssNavigationMessage;)V");
892
893 // TODO(b/31632518)
894 gnssHal = IGnss::getService("gnss");
895 if (gnssHal != nullptr) {
896 auto result = gnssHal->getExtensionXtra([](const sp<IGnssXtra>& xtraIface) {
897 gnssXtraIface = xtraIface;
898 });
899
900 if (!result.getStatus().isOk()) {
901 ALOGD("Unable to get a handle to Xtra");
902 }
903
904 result = gnssHal->getExtensionAGnssRil([](const sp<IAGnssRil>& rilIface) {
905 agnssRilIface = rilIface;
906 });
907
908 if (!result.getStatus().isOk()) {
909 ALOGD("Unable to get a handle to AGnssRil");
910 }
911
912 result = gnssHal->getExtensionAGnss([](const sp<IAGnss>& assistedGnssIface) {
913 agnssIface = assistedGnssIface;
914 });
915
916 if (!result.getStatus().isOk()) {
917 ALOGD("Unable to get a handle to AGnss");
918 }
919
920 result = gnssHal->getExtensionGnssNavigationMessage(
921 [](const sp<IGnssNavigationMessage>& navigationMessageIface) {
922 gnssNavigationMessageIface = navigationMessageIface;
923 });
924
925 if (!result.getStatus().isOk()) {
926 ALOGD("Unable to get a handle to GnssNavigationMessage");
927 }
928
929 result = gnssHal->getExtensionGnssMeasurement([](
930 const sp<IGnssMeasurement>& measurementIface) {
931 gnssMeasurementIface = measurementIface;
932 });
933 if (!result.getStatus().isOk()) {
934 ALOGD("Unable to get a handle to GnssMeasurement");
935 }
936
937 result = gnssHal->getExtensionGnssDebug([](const sp<IGnssDebug>& debugIface) {
938 gnssDebugIface = debugIface;
939 });
940 if (!result.getStatus().isOk()) {
941 ALOGD("Unable to get a handle to GnssDebug");
942 }
943
944 result = gnssHal->getExtensionGnssNi([](const sp<IGnssNi>& niIface) {
945 gnssNiIface = niIface;
946 });
947 if (!result.getStatus().isOk()) {
948 ALOGD("Unable to get a handle to GnssNi");
949 }
950
951 result = gnssHal->getExtensionGnssConfiguration([](const sp<IGnssConfiguration>& configIface) {
952 gnssConfigurationIface = configIface;
953 });
954 if (!result.getStatus().isOk()) {
955 ALOGD("Unable to get a handle to GnssConfiguration");
956 }
957
958 result = gnssHal->getExtensionGnssGeofencing([](const sp<IGnssGeofencing>& geofenceIface) {
959 gnssGeofencingIface = geofenceIface;
960 });
961 if (!result.getStatus().isOk()) {
962 ALOGD("Unable to get a handle to GnssGeofencing");
963 }
964
965 } else {
966 ALOGE("Unable to get GPS service\n");
967 }
968 ProcessState::self()->setThreadPoolMaxThreadCount(0);
969 ProcessState::self()->startThreadPool();
970}
971
972static jboolean android_location_GnssLocationProvider_is_supported(
973 JNIEnv* /* env */, jclass /* clazz */) {
974 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
975}
976
977static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
978 JNIEnv* /* env */, jclass /* clazz */) {
979 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
980}
981
982static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
983 JNIEnv* /* env */, jclass /* jclazz */) {
984 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
985}
986
987static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
988 /*
989 * This must be set before calling into the HAL library.
990 */
991 if (!mCallbacksObj)
992 mCallbacksObj = env->NewGlobalRef(obj);
993
994 sp<IGnssCallback> gnssCbIface = new GnssCallback();
995 /*
996 * Fail if the main interface fails to initialize
997 */
998 if (gnssHal == nullptr) {
999 ALOGE("Unable to Initialize GNSS HAL\n");
1000 return JNI_FALSE;
1001 }
1002
1003 auto result = gnssHal->setCallback(gnssCbIface);
1004 if ((!result) || (!result.getStatus().isOk())) {
1005 ALOGE("SetCallback for Gnss Interface fails\n");
1006 return JNI_FALSE;
1007 }
1008
1009 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1010 if (gnssXtraIface == nullptr) {
1011 ALOGE("Unable to initialize GNSS Xtra interface\n");
1012 }
1013
1014 result = gnssXtraIface->setCallback(gnssXtraCbIface);
1015 if ((!result) || (!result.getStatus().isOk())) {
1016 gnssXtraIface = nullptr;
1017 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1018 }
1019
1020 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1021 if (agnssIface != nullptr) {
1022 agnssIface->setCallback(aGnssCbIface);
1023 } else {
1024 ALOGE("Unable to Initialize AGnss interface\n");
1025 }
1026
1027 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1028 if (gnssGeofencingIface != nullptr) {
1029 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1030 } else {
1031 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1032 }
1033
1034 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1035 if (gnssNiCbIface != nullptr) {
1036 gnssNiIface->setCallback(gnssNiCbIface);
1037 } else {
1038 ALOGE("Unable to initialize GNSS NI interface\n");
1039 }
1040
1041 return JNI_TRUE;
1042}
1043
1044static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1045 if (gnssHal != nullptr) {
1046 gnssHal->cleanup();
1047 }
1048}
1049
1050static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1051 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1052 jint preferred_time) {
1053 if (gnssHal != nullptr) {
1054 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1055 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1056 min_interval,
1057 preferred_accuracy,
1058 preferred_time);
1059 if (!result.getStatus().isOk()) {
1060 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1061 return JNI_FALSE;
1062 } else {
1063 return result;
1064 }
1065 } else {
1066 return JNI_FALSE;
1067 }
1068}
1069
1070static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1071 if (gnssHal != nullptr) {
1072 auto result = gnssHal->start();
1073 if (!result.getStatus().isOk()) {
1074 return JNI_FALSE;
1075 } else {
1076 return result;
1077 }
1078 } else {
1079 return JNI_FALSE;
1080 }
1081}
1082
1083static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1084 if (gnssHal != nullptr) {
1085 auto result = gnssHal->stop();
1086 if (!result.getStatus().isOk()) {
1087 return JNI_FALSE;
1088 } else {
1089 return result;
1090 }
1091 } else {
1092 return JNI_FALSE;
1093 }
1094}
1095static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1096 jobject /* obj */,
1097 jint flags) {
1098 if (gnssHal != nullptr) {
1099 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
1100 if (!result.getStatus().isOk()) {
1101 ALOGE("Error in deleting aiding data");
1102 }
1103 }
1104}
1105
1106/*
1107 * This enum is used by the read_sv_status method to combine the svid,
1108 * constellation and svFlag fields.
1109 */
1110enum ShiftWidth: uint8_t {
1111 SVID_SHIFT_WIDTH = 7,
1112 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1113};
1114
1115static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1116 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
1117 jfloatArray azumArray) {
1118 /*
1119 * This method should only be called from within a call to reportSvStatus.
1120 */
1121 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1122 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1123 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1124 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
1125
1126 /*
1127 * Read GNSS SV info.
1128 */
1129 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1130 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1131 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1132 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1133 static_cast<uint32_t>(info.svFlag);
1134 cn0s[i] = info.cN0Dbhz;
1135 elev[i] = info.elevationDegrees;
1136 azim[i] = info.azimuthDegrees;
1137 }
1138
1139 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1140 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1141 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1142 env->ReleaseFloatArrayElements(azumArray, azim, 0);
1143 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1144}
1145
1146static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1147 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1148 IAGnssRil::AGnssRefLocation location;
1149
1150 if (agnssRilIface == nullptr) {
1151 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1152 return;
1153 }
1154
1155 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1156 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1157 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1158 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1159 location.cellID.mcc = mcc;
1160 location.cellID.mnc = mnc;
1161 location.cellID.lac = lac;
1162 location.cellID.cid = cid;
1163 break;
1164 default:
1165 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1166 return;
1167 break;
1168 }
1169
1170 agnssRilIface->setRefLocation(location);
1171}
1172
1173static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1174 jint type, jstring setid_string) {
1175 if (agnssRilIface == nullptr) {
1176 ALOGE("no AGPS RIL interface in agps_set_id");
1177 return;
1178 }
1179
1180 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1181 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1182 env->ReleaseStringUTFChars(setid_string, setid);
1183}
1184
1185static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1186 jbyteArray nmeaArray, jint buffer_size) {
1187 // this should only be called from within a call to reportNmea
1188 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1189 int length = GnssCallback::sNmeaStringLength;
1190 if (length > buffer_size)
1191 length = buffer_size;
1192 memcpy(nmea, GnssCallback::sNmeaString, length);
1193 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1194 return (jint) length;
1195}
1196
1197static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1198 jlong time, jlong timeReference, jint uncertainty) {
1199 if (gnssHal != nullptr) {
1200 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
1201 if (!result || !result.getStatus().isOk()) {
1202 ALOGE("%s: Gnss injectTime() failed", __func__);
1203 }
1204 }
1205}
1206
1207static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1208 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1209 if (gnssHal != nullptr) {
1210 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
1211 if (!result || !result.getStatus().isOk()) {
1212 ALOGE("%s: Gnss injectLocation() failed", __func__);
1213 }
1214 }
1215}
1216
1217static jboolean android_location_GnssLocationProvider_supports_xtra(
1218 JNIEnv* /* env */, jobject /* obj */) {
1219 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1220}
1221
1222static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1223 jbyteArray data, jint length) {
1224 if (gnssXtraIface == nullptr) {
1225 ALOGE("XTRA Interface not supported");
1226 return;
1227 }
1228
1229 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1230 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1231 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1232}
1233
1234static void android_location_GnssLocationProvider_agps_data_conn_open(
1235 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1236 if (agnssIface == nullptr) {
1237 ALOGE("no AGPS interface in agps_data_conn_open");
1238 return;
1239 }
1240 if (apn == NULL) {
1241 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1242 return;
1243 }
1244
1245 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1246
1247 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
1248 if ((!result) || (!result.getStatus().isOk())) {
1249 ALOGE("%s: Failed to set APN and its IP type", __func__);
1250 }
1251 env->ReleaseStringUTFChars(apn, apnStr);
1252}
1253
1254static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1255 jobject /* obj */) {
1256 if (agnssIface == nullptr) {
1257 ALOGE("%s: AGPS interface not supported", __func__);
1258 return;
1259 }
1260
1261 auto result = agnssIface->dataConnClosed();
1262 if ((!result) || (!result.getStatus().isOk())) {
1263 ALOGE("%s: Failed to close AGnss data connection", __func__);
1264 }
1265}
1266
1267static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1268 jobject /* obj */) {
1269 if (agnssIface == nullptr) {
1270 ALOGE("%s: AGPS interface not supported", __func__);
1271 return;
1272 }
1273
1274 auto result = agnssIface->dataConnFailed();
1275 if ((!result) || (!result.getStatus().isOk())) {
1276 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1277 }
1278}
1279
1280static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1281 jint type, jstring hostname, jint port) {
1282 if (agnssIface == nullptr) {
1283 ALOGE("no AGPS interface in set_agps_server");
1284 return;
1285 }
1286
1287 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1288 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1289 c_hostname,
1290 port);
1291 if ((!result) || (!result.getStatus().isOk())) {
1292 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1293 }
1294
1295 env->ReleaseStringUTFChars(hostname, c_hostname);
1296}
1297
1298static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1299 jobject /* obj */, jint notifId, jint response) {
1300 if (gnssNiIface == nullptr) {
1301 ALOGE("no NI interface in send_ni_response");
1302 return;
1303 }
1304
1305 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1306}
1307
1308static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1309 jobject /* obj */) {
1310 jstring result = NULL;
1311 /*
1312 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1313 */
1314 if (gnssDebugIface != nullptr) {
1315 IGnssDebug::DebugData data;
1316 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1317 data = debugData;
1318 });
1319
1320 std::stringstream internalState;
1321 if (data.position.valid) {
1322 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1323 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1324 << ", altitudeMeters: " << data.position.altitudeMeters
1325 << ", accuracyMeters: " << data.position.accuracyMeters
1326 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1327 }
1328
1329 if (data.time.valid) {
1330 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1331 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1332 }
1333
1334 if (data.satelliteDataArray.size() != 0) {
1335 internalState << "Satellite Data:: ";
1336 }
1337
1338 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1339 internalState << "svid: " << data.satelliteDataArray[i].svid
1340 << ", constellation: "
1341 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1342 << ", ephemerisType: "
1343 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1344 << ", ephemerisAgeSeconds: "
1345 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1346 }
1347 result = env->NewStringUTF(internalState.str().c_str());
1348 }
1349 return result;
1350}
1351
1352static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1353 jobject /* obj */,
1354 jboolean connected,
1355 jint type,
1356 jboolean roaming,
1357 jboolean available,
1358 jstring extraInfo,
1359 jstring apn) {
1360 if (agnssRilIface != nullptr) {
1361 auto result = agnssRilIface->updateNetworkState(connected,
1362 static_cast<IAGnssRil::NetworkType>(type),
1363 roaming);
1364 if ((!result) || (!result.getStatus().isOk())) {
1365 ALOGE("updateNetworkState failed");
1366 }
1367
1368 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1369 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
1370 if ((!result) || (!result.getStatus().isOk())) {
1371 ALOGE("updateNetworkAvailability failed");
1372 }
1373
1374 env->ReleaseStringUTFChars(apn, c_apn);
1375 } else {
1376 ALOGE("AGnssRilInterface does not exist");
1377 }
1378}
1379
1380static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1381 JNIEnv* /* env */, jobject /* obj */) {
1382 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1383}
1384
1385static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1386 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1387 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1388 jint unknown_timer) {
1389 if (gnssGeofencingIface != nullptr) {
1390 auto result = gnssGeofencingIface->addGeofence(
1391 geofenceId, latitude, longitude, radius,
1392 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1393 monitor_transition, notification_responsiveness, unknown_timer);
1394 return boolToJbool(result.getStatus().isOk());
1395 } else {
1396 ALOGE("Geofence Interface not available");
1397 }
1398 return JNI_FALSE;
1399}
1400
1401static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1402 jobject /* obj */, jint geofenceId) {
1403 if (gnssGeofencingIface != nullptr) {
1404 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
1405 return boolToJbool(result.getStatus().isOk());
1406 } else {
1407 ALOGE("Geofence interface not available");
1408 }
1409 return JNI_FALSE;
1410}
1411
1412static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1413 jobject /* obj */, jint geofenceId) {
1414 if (gnssGeofencingIface != nullptr) {
1415 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
1416 return boolToJbool(result.getStatus().isOk());
1417 } else {
1418 ALOGE("Geofence interface not available");
1419 }
1420 return JNI_FALSE;
1421}
1422
1423static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1424 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1425 if (gnssGeofencingIface != nullptr) {
1426 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
1427 return boolToJbool(result.getStatus().isOk());
1428 } else {
1429 ALOGE("Geofence interface not available");
1430 }
1431 return JNI_FALSE;
1432}
1433
Lifu Tang30f95a72016-01-07 23:20:38 -08001434static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001435 JNIEnv* env, jclass clazz) {
1436 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001437 return JNI_TRUE;
1438 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001439
destradaaea8a8a62014-06-23 18:19:03 -07001440 return JNI_FALSE;
1441}
1442
Lifu Tang30f95a72016-01-07 23:20:38 -08001443static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001444 JNIEnv* env,
1445 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001446 if (gnssMeasurementIface == nullptr) {
1447 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001448 return JNI_FALSE;
1449 }
1450
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001451 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1452 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1453 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1454 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1455 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001456 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001457 } else {
1458 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001459 }
1460
1461 return JNI_TRUE;
1462}
1463
Lifu Tang30f95a72016-01-07 23:20:38 -08001464static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001465 JNIEnv* env,
1466 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001467 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001468 ALOGE("Measurement interface not available");
1469 return JNI_FALSE;
1470 }
1471
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001472 auto result = gnssMeasurementIface->close();
1473 return boolToJbool(result.getStatus().isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001474}
1475
Lifu Tang30f95a72016-01-07 23:20:38 -08001476static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001477 JNIEnv* env,
1478 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001479 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001480 return JNI_TRUE;
1481 }
1482 return JNI_FALSE;
1483}
1484
Lifu Tang30f95a72016-01-07 23:20:38 -08001485static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001486 JNIEnv* env,
1487 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001488 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001489 ALOGE("Navigation Message interface is not available.");
1490 return JNI_FALSE;
1491 }
1492
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001493 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1494 new GnssNavigationMessageCallback();
1495 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1496 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1497
1498 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1499 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001500 return JNI_FALSE;
1501 }
1502
1503 return JNI_TRUE;
1504}
1505
Lifu Tang30f95a72016-01-07 23:20:38 -08001506static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001507 JNIEnv* env,
1508 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001509 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001510 ALOGE("Navigation Message interface is not available.");
1511 return JNI_FALSE;
1512 }
1513
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001514 auto result = gnssNavigationMessageIface->close();
1515 return boolToJbool(result.getStatus().isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001516}
1517
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001518static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1519 jobject,
1520 jint emergencySuplPdn) {
1521 if (gnssConfigurationIface == nullptr) {
1522 ALOGE("no GNSS configuration interface available");
1523 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001524 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001525
1526 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
1527 if (result.getStatus().isOk()) {
1528 return result;
1529 } else {
1530 return JNI_FALSE;
1531 }
1532}
1533
1534static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1535 jobject,
1536 jint version) {
1537 if (gnssConfigurationIface == nullptr) {
1538 ALOGE("no GNSS configuration interface available");
1539 return JNI_FALSE;
1540 }
1541 auto result = gnssConfigurationIface->setSuplVersion(version);
1542 if (result.getStatus().isOk()) {
1543 return result;
1544 } else {
1545 return JNI_FALSE;
1546 }
1547}
1548
1549static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1550 jobject,
1551 jint suplEs) {
1552 if (gnssConfigurationIface == nullptr) {
1553 ALOGE("no GNSS configuration interface available");
1554 return JNI_FALSE;
1555 }
1556
1557 auto result = gnssConfigurationIface->setSuplEs(suplEs);
1558 if (result.getStatus().isOk()) {
1559 return result;
1560 } else {
1561 return JNI_FALSE;
1562 }
1563}
1564
1565static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1566 jobject,
1567 jint mode) {
1568 if (gnssConfigurationIface == nullptr) {
1569 ALOGE("no GNSS configuration interface available");
1570 return JNI_FALSE;
1571 }
1572
1573 auto result = gnssConfigurationIface->setSuplMode(mode);
1574 if (result.getStatus().isOk()) {
1575 return result;
1576 } else {
1577 return JNI_FALSE;
1578 }
1579}
1580
1581static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1582 jobject,
1583 jint gpsLock) {
1584 if (gnssConfigurationIface == nullptr) {
1585 ALOGE("no GNSS configuration interface available");
1586 return JNI_FALSE;
1587 }
1588
1589 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
1590 if (result.getStatus().isOk()) {
1591 return result;
1592 } else {
1593 return JNI_FALSE;
1594 }
1595}
1596
1597static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1598 jobject,
1599 jint lppProfile) {
1600 if (gnssConfigurationIface == nullptr) {
1601 ALOGE("no GNSS configuration interface available");
1602 return JNI_FALSE;
1603 }
1604
1605 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1606
1607 if (result.getStatus().isOk()) {
1608 return result;
1609 } else {
1610 return JNI_FALSE;
1611 }
1612}
1613
1614static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1615 jobject,
1616 jint gnssPosProtocol) {
1617 if (gnssConfigurationIface == nullptr) {
1618 ALOGE("no GNSS configuration interface available");
1619 return JNI_FALSE;
1620 }
1621
1622 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
1623 if (result.getStatus().isOk()) {
1624 return result;
1625 } else {
1626 return JNI_FALSE;
1627 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001628}
1629
Daniel Micay76f6a862015-09-19 17:31:01 -04001630static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001631 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 {"class_init_native", "()V", reinterpret_cast<void *>(
1633 android_location_GnssLocationProvider_class_init_native)},
1634 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1635 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001636 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001637 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001638 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001639 reinterpret_cast<void *>(
1640 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1641 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1642 {"native_cleanup", "()V", reinterpret_cast<void *>(
1643 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001644 {"native_set_position_mode",
1645 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001646 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1647 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1648 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001649 {"native_delete_aiding_data",
1650 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001651 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001652 {"native_read_sv_status",
Lifu Tang120480f2016-02-07 18:08:19 -08001653 "([I[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001654 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1655 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1656 android_location_GnssLocationProvider_read_nmea)},
1657 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1658 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001659 {"native_inject_location",
1660 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001661 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1662 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1663 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001664 {"native_inject_xtra_data",
1665 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001666 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001667 {"native_agps_data_conn_open",
1668 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001669 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001670 {"native_agps_data_conn_closed",
1671 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001672 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001673 {"native_agps_data_conn_failed",
1674 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001675 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001676 {"native_agps_set_id",
1677 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001678 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001679 {"native_agps_set_ref_location_cellid",
1680 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001681 reinterpret_cast<void *>(
1682 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001683 {"native_set_agps_server",
1684 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001685 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001686 {"native_send_ni_response",
1687 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001688 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001689 {"native_get_internal_state",
1690 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001691 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001692 {"native_update_network_state",
1693 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001695 {"native_is_geofence_supported",
1696 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001697 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001698 {"native_add_geofence",
1699 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001700 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001701 {"native_remove_geofence",
1702 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001703 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1704 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1705 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001706 {"native_resume_geofence",
1707 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001708 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001709 {"native_is_measurement_supported",
1710 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001711 reinterpret_cast<void *>(
1712 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001713 {"native_start_measurement_collection",
1714 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001715 reinterpret_cast<void *>(
1716 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001717 {"native_stop_measurement_collection",
1718 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001719 reinterpret_cast<void *>(
1720 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001721 {"native_is_navigation_message_supported",
1722 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001723 reinterpret_cast<void *>(
1724 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001725 {"native_start_navigation_message_collection",
1726 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001727 reinterpret_cast<void *>(
1728 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001729 {"native_stop_navigation_message_collection",
1730 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001731 reinterpret_cast<void *>(
1732 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1733 {"native_set_supl_es",
1734 "(I)Z",
1735 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1736 {"native_set_supl_version",
1737 "(I)Z",
1738 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1739 {"native_set_supl_mode",
1740 "(I)Z",
1741 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1742 {"native_set_lpp_profile",
1743 "(I)Z",
1744 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1745 {"native_set_gnss_pos_protocol_select",
1746 "(I)Z",
1747 reinterpret_cast<void *>(
1748 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1749 {"native_set_gps_lock",
1750 "(I)Z",
1751 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1752 {"native_set_emergency_supl_pdn",
1753 "(I)Z",
1754 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755};
1756
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001757int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07001758 return jniRegisterNativeMethods(
1759 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08001760 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07001761 sMethods,
1762 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763}
1764
1765} /* namespace android */