blob: 1578562a4faff8a3d14cf84b3f51eb9ffe745b8e [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;
Wyatt Rileycf879db2017-01-12 13:57:38 -080061static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080063/*
64 * Save a pointer to JavaVm to attach/detach threads executing
65 * callback methods that need to make JNI calls.
66 */
67static JavaVM* sJvm;
68
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070069using android::OK;
70using android::sp;
71using android::status_t;
72using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070074using android::hardware::Return;
75using android::hardware::Void;
76using android::hardware::hidl_vec;
Lifu Tang30f95a72016-01-07 23:20:38 -080077
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070078using android::hardware::gnss::V1_0::IAGnss;
79using android::hardware::gnss::V1_0::IAGnssCallback;
80using android::hardware::gnss::V1_0::IAGnssCallback;
81using android::hardware::gnss::V1_0::IAGnssRil;
82using android::hardware::gnss::V1_0::IAGnssRilCallback;
83using android::hardware::gnss::V1_0::IGnss;
Wyatt Rileycf879db2017-01-12 13:57:38 -080084using android::hardware::gnss::V1_0::IGnssBatching;
85using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070086using android::hardware::gnss::V1_0::IGnssCallback;
87using android::hardware::gnss::V1_0::IGnssConfiguration;
88using android::hardware::gnss::V1_0::IGnssDebug;
89using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
90using android::hardware::gnss::V1_0::IGnssGeofencing;
91using android::hardware::gnss::V1_0::IGnssMeasurement;
92using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
93using android::hardware::gnss::V1_0::IGnssNavigationMessage;
94using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
95using android::hardware::gnss::V1_0::IGnssNi;
96using android::hardware::gnss::V1_0::IGnssNiCallback;
97using android::hardware::gnss::V1_0::IGnssXtra;
98using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Riley49d98912016-05-17 16:14:48 -070099
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700100
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700101sp<IGnss> gnssHal = nullptr;
102sp<IGnssXtra> gnssXtraIface = nullptr;
103sp<IAGnssRil> agnssRilIface = nullptr;
104sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
105sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800106sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700107sp<IGnssDebug> gnssDebugIface = nullptr;
108sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
109sp<IGnssNi> gnssNiIface = nullptr;
110sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
111sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400113#define WAKE_LOCK_NAME "GPS"
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115namespace android {
116
Lifu Tang120480f2016-02-07 18:08:19 -0800117template<class T>
118class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700119 public:
120 // Helper function to call setter on a Java object.
121 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800122 JNIEnv* env,
123 jclass clazz,
124 jobject object,
125 const char* method_name,
126 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700127
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700128 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800129 static const char *const signature_;
130};
Lifu Tange5a0e212016-01-25 18:02:17 -0800131
Lifu Tang120480f2016-02-07 18:08:19 -0800132template<class T>
133void JavaMethodHelper<T>::callJavaMethod(
134 JNIEnv* env,
135 jclass clazz,
136 jobject object,
137 const char* method_name,
138 T value) {
139 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
140 env->CallVoidMethod(object, method, value);
141}
destradaaea8a8a62014-06-23 18:19:03 -0700142
Lifu Tang120480f2016-02-07 18:08:19 -0800143class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144 public:
145 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800146 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700147 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800148
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700149 template<class T>
150 void callSetter(const char* method_name, T value);
151 template<class T>
152 void callSetter(const char* method_name, T* value, size_t size);
153 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800154
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700155 private:
156 JNIEnv* env_;
157 jclass clazz_;
158 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800159};
160
161JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
162 clazz_ = env_->FindClass(class_name);
163 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
164 object_ = env_->NewObject(clazz_, ctor);
165}
166
Wyatt Rileycf879db2017-01-12 13:57:38 -0800167JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
168 clazz_ = env_->FindClass(class_name);
169 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
170 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
171}
172
Lifu Tang120480f2016-02-07 18:08:19 -0800173JavaObject::~JavaObject() {
174 env_->DeleteLocalRef(clazz_);
175}
176
177template<class T>
178void JavaObject::callSetter(const char* method_name, T value) {
179 JavaMethodHelper<T>::callJavaMethod(
180 env_, clazz_, object_, method_name, value);
181}
182
183template<>
184void JavaObject::callSetter(
185 const char* method_name, uint8_t* value, size_t size) {
186 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700187 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800188 jmethodID method = env_->GetMethodID(
189 clazz_,
190 method_name,
191 "([B)V");
192 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700193 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800194}
195
196jobject JavaObject::get() {
197 return object_;
198}
199
200// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800201template<>
202const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
203template<>
204const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
205template<>
206const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
207template<>
208const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
209template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800210const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
211template<>
212const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800213template<>
214const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
215template<>
216const char *const JavaMethodHelper<float>::signature_ = "(F)V";
217template<>
218const char *const JavaMethodHelper<double>::signature_ = "(D)V";
219template<>
220const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
221
222#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800223
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700224static inline jboolean boolToJbool(bool value) {
225 return value ? JNI_TRUE : JNI_FALSE;
226}
Lifu Tang120480f2016-02-07 18:08:19 -0800227
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700228static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
229 if (env->ExceptionCheck()) {
230 ALOGE("An exception was thrown by callback '%s'.", methodName);
231 LOGE_EX(env);
232 env->ExceptionClear();
233 }
234}
destradaaea8a8a62014-06-23 18:19:03 -0700235
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800236class ScopedJniThreadAttach {
237public:
238 ScopedJniThreadAttach() {
239 /*
240 * attachResult will also be JNI_OK if the thead was already attached to
241 * JNI before the call to AttachCurrentThread().
242 */
243 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
244 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
245 attachResult);
246 }
247
248 ~ScopedJniThreadAttach() {
249 jint detachResult = sJvm->DetachCurrentThread();
250 /*
251 * Return if the thread was already detached. Log error for any other
252 * failure.
253 */
254 if (detachResult == JNI_EDETACHED) {
255 return;
256 }
257
258 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
259 detachResult);
260 }
261
262 JNIEnv* getEnv() {
263 /*
264 * Checking validity of mEnv in case the thread was detached elsewhere.
265 */
266 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
267 return mEnv;
268 }
269
270private:
271 JNIEnv* mEnv = nullptr;
272};
273
274thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
275
276static JNIEnv* getJniEnv() {
277 JNIEnv* env = AndroidRuntime::getJNIEnv();
278
279 /*
280 * If env is nullptr, the thread is not already attached to
281 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
282 * will detach it on thread exit.
283 */
284 if (env == nullptr) {
285 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
286 env = tJniThreadAttacher->getEnv();
287 }
288
289 return env;
290}
291
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700292/*
293 * GnssCallback class implements the callback methods for IGnss interface.
294 */
295struct GnssCallback : public IGnssCallback {
296 Return<void> gnssLocationCb(
297 const android::hardware::gnss::V1_0::GnssLocation& location) override;
298 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
299 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
300 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
301 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
302 Return<void> gnssAcquireWakelockCb() override;
303 Return<void> gnssReleaseWakelockCb() override;
304 Return<void> gnssRequestTimeCb() override;
305 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800306
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700307 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
308 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
309 static size_t sGnssSvListSize;
310
311 static const char* sNmeaString;
312 static size_t sNmeaStringLength;
313};
314
315IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
316 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
317const char* GnssCallback::sNmeaString = nullptr;
318size_t GnssCallback::sNmeaStringLength = 0;
319size_t GnssCallback::sGnssSvListSize = 0;
320
321Return<void> GnssCallback::gnssLocationCb(
322 const ::android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800323 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700324 env->CallVoidMethod(mCallbacksObj,
325 method_reportLocation,
326 location.gnssLocationFlags,
327 static_cast<jdouble>(location.latitudeDegrees),
328 static_cast<jdouble>(location.longitudeDegrees),
329 static_cast<jdouble>(location.altitudeMeters),
330 static_cast<jfloat>(location.speedMetersPerSec),
331 static_cast<jfloat>(location.bearingDegrees),
gomo4402af62017-01-11 13:20:13 -0800332 static_cast<jfloat>(location.horizontalAccuracyMeters),
333 static_cast<jfloat>(location.verticalAccuracyMeters),
334 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
335 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700336 static_cast<jlong>(location.timestamp));
337 checkAndClearExceptionFromCallback(env, __FUNCTION__);
338 return Void();
339}
340
341Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800342 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700343 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
344 checkAndClearExceptionFromCallback(env, __FUNCTION__);
345 return Void();
346}
347
348Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800349 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700350
351 sGnssSvListSize = svStatus.numSvs;
352 if (sGnssSvListSize > static_cast<uint32_t>(
353 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
354 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
355 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
356 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800357 }
358
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700359 // Copy GNSS SV info into sGnssSvList, if any.
360 if (svStatus.numSvs > 0) {
361 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800362 }
destradaaea8a8a62014-06-23 18:19:03 -0700363
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700364 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
365 checkAndClearExceptionFromCallback(env, __FUNCTION__);
366 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700367}
368
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700369Return<void> GnssCallback::gnssNmeaCb(
370 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800371 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700372 /*
373 * The Java code will call back to read these values.
374 * We do this to avoid creating unnecessary String objects.
375 */
376 sNmeaString = nmea.c_str();
377 sNmeaStringLength = nmea.size();
378
379 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
380 checkAndClearExceptionFromCallback(env, __FUNCTION__);
381 return Void();
382}
383
384Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
385 ALOGD("%s: %du\n", __func__, capabilities);
386
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800387 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700388 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
389 checkAndClearExceptionFromCallback(env, __FUNCTION__);
390 return Void();
391}
392
393Return<void> GnssCallback::gnssAcquireWakelockCb() {
394 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
395 return Void();
396}
397
398Return<void> GnssCallback::gnssReleaseWakelockCb() {
399 release_wake_lock(WAKE_LOCK_NAME);
400 return Void();
401}
402
403Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800404 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700405 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
406 checkAndClearExceptionFromCallback(env, __FUNCTION__);
407 return Void();
408}
409
410Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
411 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
412
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800413 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700414 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
415 info.yearOfHw);
416 checkAndClearExceptionFromCallback(env, __FUNCTION__);
417 return Void();
418}
419
420class GnssXtraCallback : public IGnssXtraCallback {
421 Return<void> downloadRequestCb() override;
422};
423
424/*
425 * GnssXtraCallback class implements the callback methods for the IGnssXtra
426 * interface.
427 */
428Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800429 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700430 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
431 checkAndClearExceptionFromCallback(env, __FUNCTION__);
432 return Void();
433}
434
435/*
436 * GnssGeofenceCallback class implements the callback methods for the
437 * IGnssGeofence interface.
438 */
439struct GnssGeofenceCallback : public IGnssGeofenceCallback {
440 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
441 Return<void> gnssGeofenceTransitionCb(
442 int32_t geofenceId,
443 const android::hardware::gnss::V1_0::GnssLocation& location,
444 GeofenceTransition transition,
445 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
446 Return<void> gnssGeofenceStatusCb(
447 GeofenceAvailability status,
448 const android::hardware::gnss::V1_0::GnssLocation& location) override;
449 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
450 GeofenceStatus status) override;
451 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
452 GeofenceStatus status) override;
453 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
454 GeofenceStatus status) override;
455 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
456 GeofenceStatus status) override;
457};
458
459Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
460 int32_t geofenceId,
461 const android::hardware::gnss::V1_0::GnssLocation& location,
462 GeofenceTransition transition,
463 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800464 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700465
466 env->CallVoidMethod(mCallbacksObj,
467 method_reportGeofenceTransition,
468 geofenceId,
469 location.gnssLocationFlags,
470 static_cast<jdouble>(location.latitudeDegrees),
471 static_cast<jdouble>(location.longitudeDegrees),
472 static_cast<jdouble>(location.altitudeMeters),
473 static_cast<jfloat>(location.speedMetersPerSec),
474 static_cast<jfloat>(location.bearingDegrees),
gomo4402af62017-01-11 13:20:13 -0800475 static_cast<jfloat>(location.horizontalAccuracyMeters),
476 static_cast<jfloat>(location.verticalAccuracyMeters),
477 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
478 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700479 static_cast<jlong>(location.timestamp),
480 transition,
481 timestamp);
482
483 checkAndClearExceptionFromCallback(env, __FUNCTION__);
484 return Void();
485}
486
487Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
488 GeofenceAvailability status,
489 const android::hardware::gnss::V1_0::GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800490 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700491 env->CallVoidMethod(mCallbacksObj,
492 method_reportGeofenceStatus,
493 status,
494 location.gnssLocationFlags,
495 static_cast<jdouble>(location.latitudeDegrees),
496 static_cast<jdouble>(location.longitudeDegrees),
497 static_cast<jdouble>(location.altitudeMeters),
498 static_cast<jfloat>(location.speedMetersPerSec),
499 static_cast<jfloat>(location.bearingDegrees),
gomo4402af62017-01-11 13:20:13 -0800500 static_cast<jfloat>(location.horizontalAccuracyMeters),
501 static_cast<jfloat>(location.verticalAccuracyMeters),
502 static_cast<jfloat>(location.speedAccuracyMetersPerSecond),
503 static_cast<jfloat>(location.bearingAccuracyDegrees),
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700504 static_cast<jlong>(location.timestamp));
505 checkAndClearExceptionFromCallback(env, __FUNCTION__);
506 return Void();
507}
508
509Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
510 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800511 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700512 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
513 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
514 }
515
516 env->CallVoidMethod(mCallbacksObj,
517 method_reportGeofenceAddStatus,
518 geofenceId,
519 status);
520 checkAndClearExceptionFromCallback(env, __FUNCTION__);
521 return Void();
522}
523
524Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
525 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800526 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700527 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
528 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
529 }
530
531 env->CallVoidMethod(mCallbacksObj,
532 method_reportGeofenceRemoveStatus,
533 geofenceId, status);
534 checkAndClearExceptionFromCallback(env, __FUNCTION__);
535 return Void();
536}
537
538Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
539 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800540 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700541 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
542 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
543 }
544
545 env->CallVoidMethod(mCallbacksObj,
546 method_reportGeofencePauseStatus,
547 geofenceId, status);
548 checkAndClearExceptionFromCallback(env, __FUNCTION__);
549 return Void();
550}
551
552Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
553 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800554 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700555 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
556 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
557 }
558
559 env->CallVoidMethod(mCallbacksObj,
560 method_reportGeofenceResumeStatus,
561 geofenceId, status);
562 checkAndClearExceptionFromCallback(env, __FUNCTION__);
563 return Void();
564}
565
566/*
567 * GnssNavigationMessageCallback interface implements the callback methods
568 * required by the IGnssNavigationMessage interface.
569 */
570struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
571 /*
572 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
573 * follow.
574 */
575 Return<void> gnssNavigationMessageCb(
576 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
577};
578
579Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
580 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800581 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700582
583 size_t dataLength = message.data.size();
584
585 std::vector<uint8_t> navigationData = message.data;
586 uint8_t* data = &(navigationData[0]);
587 if (dataLength == 0 || data == NULL) {
588 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
589 dataLength);
590 return Void();
591 }
592
593 JavaObject object(env, "android/location/GnssNavigationMessage");
594 SET(Type, static_cast<int32_t>(message.type));
595 SET(Svid, static_cast<int32_t>(message.svid));
596 SET(MessageId, static_cast<int32_t>(message.messageId));
597 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
598 object.callSetter("setData", data, dataLength);
599 SET(Status, static_cast<int32_t>(message.status));
600
601 jobject navigationMessage = object.get();
602 env->CallVoidMethod(mCallbacksObj,
603 method_reportNavigationMessages,
604 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800605 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700606 env->DeleteLocalRef(navigationMessage);
607 return Void();
608}
609
610/*
611 * GnssMeasurementCallback implements the callback methods required for the
612 * GnssMeasurement interface.
613 */
614struct GnssMeasurementCallback : public IGnssMeasurementCallback {
615 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
616 private:
617 jobject translateGnssMeasurement(
618 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
619 jobject translateGnssClock(
620 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
621 jobjectArray translateGnssMeasurements(
622 JNIEnv* env,
623 const IGnssMeasurementCallback::GnssMeasurement* measurements,
624 size_t count);
625 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
626};
627
628
629Return<void> GnssMeasurementCallback::GnssMeasurementCb(
630 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800631 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700632
633 jobject clock;
634 jobjectArray measurementArray;
635
636 clock = translateGnssClock(env, &data.clock);
637 measurementArray = translateGnssMeasurements(
638 env, data.measurements.data(), data.measurementCount);
639 setMeasurementData(env, clock, measurementArray);
640
641 env->DeleteLocalRef(clock);
642 env->DeleteLocalRef(measurementArray);
643 return Void();
644}
645
646jobject GnssMeasurementCallback::translateGnssMeasurement(
647 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800648 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800649
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700650 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700651
652 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800653 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700654 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800655 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700656 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800657 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700658 measurement->receivedSvTimeUncertaintyInNs);
659 SET(Cn0DbHz, measurement->cN0DbHz);
660 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800661 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700662 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800663 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700664 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
665 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800666 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700667 measurement->accumulatedDeltaRangeUncertaintyM);
668
669 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
670 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
671 }
672
673 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
674 SET(CarrierPhase, measurement->carrierPhase);
675 }
676
677 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
678 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
679 }
680
681 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
682
683 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
684 SET(SnrInDb, measurement->snrDb);
685 }
Lifu Tang120480f2016-02-07 18:08:19 -0800686
gomo4402af62017-01-11 13:20:13 -0800687 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800688 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800689 }
690
Lifu Tang120480f2016-02-07 18:08:19 -0800691 return object.get();
692}
693
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700694jobject GnssMeasurementCallback::translateGnssClock(
695 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
696 JavaObject object(env, "android/location/GnssClock");
697
698 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
699 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
700 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
701 }
702
703 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
704 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
705 }
706
707 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
708 SET(FullBiasNanos, clock->fullBiasNs);
709 }
710
711 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
712 SET(BiasNanos, clock->biasNs);
713 }
714
715 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
716 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
717 }
718
719 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
720 SET(DriftNanosPerSecond, clock->driftNsps);
721 }
722
723 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
724 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
725 }
726
727 SET(TimeNanos, clock->timeNs);
728 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
729
730 return object.get();
731}
732
733jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
734 const IGnssMeasurementCallback::GnssMeasurement*
735 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800736 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700737 return NULL;
738 }
739
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700740 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800741 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800742 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800743 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700744 NULL /* initialElement */);
745
Lifu Tang120480f2016-02-07 18:08:19 -0800746 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700747 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800748 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800749 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800750 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
751 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700752 }
753
Lifu Tang818aa2c2016-02-01 01:52:00 -0800754 env->DeleteLocalRef(gnssMeasurementClass);
755 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700756}
757
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700758void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
759 jobjectArray measurementArray) {
760 jclass gnssMeasurementsEventClass =
761 env->FindClass("android/location/GnssMeasurementsEvent");
762 jmethodID gnssMeasurementsEventCtor =
763 env->GetMethodID(
764 gnssMeasurementsEventClass,
765 "<init>",
766 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800767
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700768 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
769 gnssMeasurementsEventCtor,
770 clock,
771 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800772
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700773 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
774 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800775 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800776 env->DeleteLocalRef(gnssMeasurementsEventClass);
777 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700778}
779
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700780/*
781 * GnssNiCallback implements callback methods required by the IGnssNi interface.
782 */
783struct GnssNiCallback : public IGnssNiCallback {
784 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
785 override;
destradaaea8a8a62014-06-23 18:19:03 -0700786};
787
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700788Return<void> GnssNiCallback::niNotifyCb(
789 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800790 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700791 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
792 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
793
794 if (requestorId && text) {
795 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
796 notification.notificationId, notification.niType,
797 notification.notifyFlags, notification.timeoutSec,
798 notification.defaultResponse, requestorId, text,
799 notification.requestorIdEncoding,
800 notification.notificationIdEncoding);
801 } else {
802 ALOGE("%s: OOM Error\n", __func__);
803 }
804
805 if (requestorId) {
806 env->DeleteLocalRef(requestorId);
807 }
808
809 if (text) {
810 env->DeleteLocalRef(text);
811 }
812 checkAndClearExceptionFromCallback(env, __FUNCTION__);
813 return Void();
814}
815
816/*
817 * AGnssCallback implements callback methods required by the IAGnss interface.
818 */
819struct AGnssCallback : public IAGnssCallback {
820 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
821 Return<void> agnssStatusIpV6Cb(
822 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
823
824 Return<void> agnssStatusIpV4Cb(
825 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
826 private:
827 jbyteArray convertToIpV4(uint32_t ip);
828};
829
830Return<void> AGnssCallback::agnssStatusIpV6Cb(
831 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800832 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700833 jbyteArray byteArray = NULL;
834 bool isSupported = false;
835
836 byteArray = env->NewByteArray(16);
837 if (byteArray != NULL) {
838 env->SetByteArrayRegion(byteArray, 0, 16,
839 (const jbyte*)(agps_status.ipV6Addr.data()));
840 isSupported = true;
841 } else {
842 ALOGE("Unable to allocate byte array for IPv6 address.");
843 }
844
845 IF_ALOGD() {
846 // log the IP for reference in case there is a bogus value pushed by HAL
847 char str[INET6_ADDRSTRLEN];
848 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
849 ALOGD("AGPS IP is v6: %s", str);
850 }
851
852 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
853 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
854 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
855 agps_status.type, agps_status.status, byteArray);
856
857 checkAndClearExceptionFromCallback(env, __FUNCTION__);
858
859 if (byteArray) {
860 env->DeleteLocalRef(byteArray);
861 }
862
863 return Void();
864}
865
866Return<void> AGnssCallback::agnssStatusIpV4Cb(
867 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800868 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700869 jbyteArray byteArray = NULL;
870
871 uint32_t ipAddr = agps_status.ipV4Addr;
872 byteArray = convertToIpV4(ipAddr);
873
874 IF_ALOGD() {
875 /*
876 * log the IP for reference in case there is a bogus value pushed by
877 * HAL.
878 */
879 char str[INET_ADDRSTRLEN];
880 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
881 ALOGD("AGPS IP is v4: %s", str);
882 }
883
884 jsize byteArrayLength =
885 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
886 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
887 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
888 agps_status.type, agps_status.status, byteArray);
889
890 checkAndClearExceptionFromCallback(env, __FUNCTION__);
891
892 if (byteArray) {
893 env->DeleteLocalRef(byteArray);
894 }
895 return Void();
896}
897
898jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
899 if (INADDR_NONE == ip) {
900 return NULL;
901 }
902
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800903 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700904 jbyteArray byteArray = env->NewByteArray(4);
905 if (byteArray == NULL) {
906 ALOGE("Unable to allocate byte array for IPv4 address");
907 return NULL;
908 }
909
910 jbyte ipv4[4];
911 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
912 memcpy(ipv4, &ip, sizeof(ipv4));
913 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
914 return byteArray;
915}
916
917/*
918 * AGnssRilCallback implements the callback methods required by the AGnssRil
919 * interface.
920 */
921struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800922 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700923 Return<void> requestRefLocCb() override;
924};
925
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800926Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800927 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700928 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
929 checkAndClearExceptionFromCallback(env, __FUNCTION__);
930 return Void();
931}
932
933Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800934 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700935 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
936 checkAndClearExceptionFromCallback(env, __FUNCTION__);
937 return Void();
938}
939
Wyatt Rileycf879db2017-01-12 13:57:38 -0800940/*
941 * GnssBatchingCallback interface implements the callback methods
942 * required by the IGnssBatching interface.
943 */
944struct GnssBatchingCallback : public IGnssBatchingCallback {
945 /*
946 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
947 * follow.
948 */
949 Return<void> gnssLocationBatchCb(
950 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations)
951 override;
952 private:
953 jobject translateLocation(
954 JNIEnv* env, const hardware::gnss::V1_0::GnssLocation* location);
955};
956
957Return<void> GnssBatchingCallback::gnssLocationBatchCb(
958 const ::android::hardware::hidl_vec<hardware::gnss::V1_0::GnssLocation> & locations) {
959 JNIEnv* env = getJniEnv();
960
961 jobjectArray jLocations = env->NewObjectArray(locations.size(),
962 env->FindClass("android/location/Location"), nullptr);
963
964 for (uint16_t i = 0; i < locations.size(); ++i) {
965 jobject jLocation = translateLocation(env, &locations[i]);
966 env->SetObjectArrayElement(jLocations, i, jLocation);
967 env->DeleteLocalRef(jLocation);
968 }
969
970 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
971 checkAndClearExceptionFromCallback(env, __FUNCTION__);
972
973 env->DeleteLocalRef(jLocations);
974
975 return Void();
976}
977
978// TODO: Use this common code to translate location for Geofencing and regular Location
979jobject GnssBatchingCallback::translateLocation(
980 JNIEnv* env, const hardware::gnss::V1_0::GnssLocation* location) {
981 JavaObject object(env, "android/location/Location", "gps");
982
983 uint16_t flags = static_cast<uint32_t>(location->gnssLocationFlags);
984 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_LAT_LONG) {
985 SET(Latitude, location->latitudeDegrees);
986 SET(Longitude, location->longitudeDegrees);
987 }
988 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_ALTITUDE) {
989 SET(Altitude, location->altitudeMeters);
990 }
991 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED) {
992 SET(Speed, location->speedMetersPerSec);
993 }
994 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING) {
995 SET(Bearing, location->bearingDegrees);
996 }
997 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
998 SET(Accuracy, location->horizontalAccuracyMeters);
999 }
1000 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
1001 SET(VerticalAccuracyMeters, location->verticalAccuracyMeters);
1002 }
1003 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
1004 SET(SpeedAccuracyMetersPerSecond, location->speedAccuracyMetersPerSecond);
1005 }
1006 if (flags & hardware::gnss::V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
1007 SET(BearingAccuracyDegrees, location->bearingAccuracyDegrees);
1008 }
1009 SET(Time, location->timestamp);
1010
1011 return object.get();
1012}
1013
1014
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001015static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
gomo4402af62017-01-11 13:20:13 -08001016 method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFFFFJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001017 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1018 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1019 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1020 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1021 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1022 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1023 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1024 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1025 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1026 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1027 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1028 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1029 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
gomo4402af62017-01-11 13:20:13 -08001030 "(IIDDDFFFFFFJIJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001031 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
gomo4402af62017-01-11 13:20:13 -08001032 "(IIDDDFFFFFFJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001033 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1034 "(II)V");
1035 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1036 "(II)V");
1037 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1038 "(II)V");
1039 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1040 "(II)V");
1041 method_reportMeasurementData = env->GetMethodID(
1042 clazz,
1043 "reportMeasurementData",
1044 "(Landroid/location/GnssMeasurementsEvent;)V");
1045 method_reportNavigationMessages = env->GetMethodID(
1046 clazz,
1047 "reportNavigationMessage",
1048 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001049 method_reportLocationBatch = env->GetMethodID(
1050 clazz,
1051 "reportLocationBatch",
1052 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001053
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001054 /*
1055 * Save a pointer to JVM.
1056 */
1057 jint jvmStatus = env->GetJavaVM(&sJvm);
1058 if (jvmStatus != JNI_OK) {
1059 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1060 }
1061
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001062 // TODO(b/31632518)
1063 gnssHal = IGnss::getService("gnss");
1064 if (gnssHal != nullptr) {
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001065 auto gnssXtra = gnssHal->getExtensionXtra();
1066 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001067 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001068 } else {
1069 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001070 }
1071
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001072 auto gnssRil = gnssHal->getExtensionAGnssRil();
1073 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001075 } else {
1076 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001077 }
1078
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001079 auto gnssAgnss = gnssHal->getExtensionAGnss();
1080 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001081 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001082 } else {
1083 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001084 }
1085
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001086 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1087 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001088 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001089 } else {
1090 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001091 }
1092
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001093 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
1094 if (!gnssMeasurement.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001095 ALOGD("Unable to get a handle to GnssMeasurement");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001096 } else {
1097 gnssMeasurementIface = gnssMeasurement;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001098 }
1099
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001100 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1101 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001102 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001103 } else {
1104 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001105 }
1106
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001107 auto gnssNi = gnssHal->getExtensionGnssNi();
1108 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001109 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001110 } else {
1111 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001112 }
1113
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001114 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1115 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001116 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001117 } else {
1118 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001119 }
1120
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001121 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1122 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001123 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001124 } else {
1125 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001126 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001127
1128 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1129 if (!gnssBatching.isOk()) {
1130 ALOGD("Unable to get a handle to gnssBatching");
1131 } else {
1132 gnssBatchingIface = gnssBatching;
1133 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001134 } else {
1135 ALOGE("Unable to get GPS service\n");
1136 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001137}
1138
1139static jboolean android_location_GnssLocationProvider_is_supported(
1140 JNIEnv* /* env */, jclass /* clazz */) {
1141 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1142}
1143
1144static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1145 JNIEnv* /* env */, jclass /* clazz */) {
1146 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1147}
1148
1149static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1150 JNIEnv* /* env */, jclass /* jclazz */) {
1151 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1152}
1153
1154static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1155 /*
1156 * This must be set before calling into the HAL library.
1157 */
1158 if (!mCallbacksObj)
1159 mCallbacksObj = env->NewGlobalRef(obj);
1160
1161 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1162 /*
1163 * Fail if the main interface fails to initialize
1164 */
1165 if (gnssHal == nullptr) {
1166 ALOGE("Unable to Initialize GNSS HAL\n");
1167 return JNI_FALSE;
1168 }
1169
1170 auto result = gnssHal->setCallback(gnssCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001171 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001172 ALOGE("SetCallback for Gnss Interface fails\n");
1173 return JNI_FALSE;
1174 }
1175
1176 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1177 if (gnssXtraIface == nullptr) {
1178 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001179 } else {
1180 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001181 if ((!result) || (!result.isOk())) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001182 gnssXtraIface = nullptr;
1183 ALOGE("SetCallback for Gnss Xtra Interface fails\n");
1184 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001185 }
1186
1187 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1188 if (agnssIface != nullptr) {
1189 agnssIface->setCallback(aGnssCbIface);
1190 } else {
1191 ALOGE("Unable to Initialize AGnss interface\n");
1192 }
1193
1194 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1195 if (gnssGeofencingIface != nullptr) {
1196 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1197 } else {
1198 ALOGE("Unable to initialize GNSS Geofencing interface\n");
1199 }
1200
1201 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
1202 if (gnssNiCbIface != nullptr) {
1203 gnssNiIface->setCallback(gnssNiCbIface);
1204 } else {
1205 ALOGE("Unable to initialize GNSS NI interface\n");
1206 }
1207
1208 return JNI_TRUE;
1209}
1210
1211static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1212 if (gnssHal != nullptr) {
1213 gnssHal->cleanup();
1214 }
1215}
1216
1217static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1218 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
1219 jint preferred_time) {
1220 if (gnssHal != nullptr) {
1221 auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1222 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1223 min_interval,
1224 preferred_accuracy,
1225 preferred_time);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001226 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001227 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1228 return JNI_FALSE;
1229 } else {
1230 return result;
1231 }
1232 } else {
1233 return JNI_FALSE;
1234 }
1235}
1236
1237static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1238 if (gnssHal != nullptr) {
1239 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001240 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001241 return JNI_FALSE;
1242 } else {
1243 return result;
1244 }
1245 } else {
1246 return JNI_FALSE;
1247 }
1248}
1249
1250static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1251 if (gnssHal != nullptr) {
1252 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001253 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001254 return JNI_FALSE;
1255 } else {
1256 return result;
1257 }
1258 } else {
1259 return JNI_FALSE;
1260 }
1261}
1262static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1263 jobject /* obj */,
1264 jint flags) {
1265 if (gnssHal != nullptr) {
1266 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001267 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001268 ALOGE("Error in deleting aiding data");
1269 }
1270 }
1271}
1272
1273/*
1274 * This enum is used by the read_sv_status method to combine the svid,
1275 * constellation and svFlag fields.
1276 */
1277enum ShiftWidth: uint8_t {
1278 SVID_SHIFT_WIDTH = 7,
1279 CONSTELLATION_TYPE_SHIFT_WIDTH = 3
1280};
1281
1282static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1283 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001284 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001285 /*
1286 * This method should only be called from within a call to reportSvStatus.
1287 */
1288 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1289 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1290 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1291 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001292 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001293
1294 /*
1295 * Read GNSS SV info.
1296 */
1297 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1298 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1299 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1300 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1301 static_cast<uint32_t>(info.svFlag);
1302 cn0s[i] = info.cN0Dbhz;
1303 elev[i] = info.elevationDegrees;
1304 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001305 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001306 }
1307
1308 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1309 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1310 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1311 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001312 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001313 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1314}
1315
1316static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1317 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1318 IAGnssRil::AGnssRefLocation location;
1319
1320 if (agnssRilIface == nullptr) {
1321 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1322 return;
1323 }
1324
1325 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1326 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1327 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1328 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1329 location.cellID.mcc = mcc;
1330 location.cellID.mnc = mnc;
1331 location.cellID.lac = lac;
1332 location.cellID.cid = cid;
1333 break;
1334 default:
1335 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1336 return;
1337 break;
1338 }
1339
1340 agnssRilIface->setRefLocation(location);
1341}
1342
1343static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1344 jint type, jstring setid_string) {
1345 if (agnssRilIface == nullptr) {
1346 ALOGE("no AGPS RIL interface in agps_set_id");
1347 return;
1348 }
1349
1350 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1351 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1352 env->ReleaseStringUTFChars(setid_string, setid);
1353}
1354
1355static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1356 jbyteArray nmeaArray, jint buffer_size) {
1357 // this should only be called from within a call to reportNmea
1358 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1359 int length = GnssCallback::sNmeaStringLength;
1360 if (length > buffer_size)
1361 length = buffer_size;
1362 memcpy(nmea, GnssCallback::sNmeaString, length);
1363 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1364 return (jint) length;
1365}
1366
1367static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1368 jlong time, jlong timeReference, jint uncertainty) {
1369 if (gnssHal != nullptr) {
1370 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001371 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001372 ALOGE("%s: Gnss injectTime() failed", __func__);
1373 }
1374 }
1375}
1376
1377static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1378 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1379 if (gnssHal != nullptr) {
1380 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001381 if (!result || !result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001382 ALOGE("%s: Gnss injectLocation() failed", __func__);
1383 }
1384 }
1385}
1386
1387static jboolean android_location_GnssLocationProvider_supports_xtra(
1388 JNIEnv* /* env */, jobject /* obj */) {
1389 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1390}
1391
1392static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1393 jbyteArray data, jint length) {
1394 if (gnssXtraIface == nullptr) {
1395 ALOGE("XTRA Interface not supported");
1396 return;
1397 }
1398
1399 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1400 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1401 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1402}
1403
1404static void android_location_GnssLocationProvider_agps_data_conn_open(
1405 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1406 if (agnssIface == nullptr) {
1407 ALOGE("no AGPS interface in agps_data_conn_open");
1408 return;
1409 }
1410 if (apn == NULL) {
1411 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1412 return;
1413 }
1414
1415 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1416
1417 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001418 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001419 ALOGE("%s: Failed to set APN and its IP type", __func__);
1420 }
1421 env->ReleaseStringUTFChars(apn, apnStr);
1422}
1423
1424static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1425 jobject /* obj */) {
1426 if (agnssIface == nullptr) {
1427 ALOGE("%s: AGPS interface not supported", __func__);
1428 return;
1429 }
1430
1431 auto result = agnssIface->dataConnClosed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001432 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001433 ALOGE("%s: Failed to close AGnss data connection", __func__);
1434 }
1435}
1436
1437static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1438 jobject /* obj */) {
1439 if (agnssIface == nullptr) {
1440 ALOGE("%s: AGPS interface not supported", __func__);
1441 return;
1442 }
1443
1444 auto result = agnssIface->dataConnFailed();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001445 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001446 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1447 }
1448}
1449
1450static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1451 jint type, jstring hostname, jint port) {
1452 if (agnssIface == nullptr) {
1453 ALOGE("no AGPS interface in set_agps_server");
1454 return;
1455 }
1456
1457 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1458 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1459 c_hostname,
1460 port);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001461 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001462 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1463 }
1464
1465 env->ReleaseStringUTFChars(hostname, c_hostname);
1466}
1467
1468static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1469 jobject /* obj */, jint notifId, jint response) {
1470 if (gnssNiIface == nullptr) {
1471 ALOGE("no NI interface in send_ni_response");
1472 return;
1473 }
1474
1475 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1476}
1477
1478static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1479 jobject /* obj */) {
1480 jstring result = NULL;
1481 /*
1482 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1483 */
1484 if (gnssDebugIface != nullptr) {
1485 IGnssDebug::DebugData data;
1486 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1487 data = debugData;
1488 });
1489
1490 std::stringstream internalState;
1491 if (data.position.valid) {
1492 internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
1493 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1494 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001495 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1496 << ", bearingDegrees: " << data.position.bearingDegrees
1497 << ", horizontalAccuracyMeters: " << data.position.horizontalAccuracyMeters
1498 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
1499 << ", speedAccuracyMetersPerSecond: " << data.position.speedAccuracyMetersPerSecond
1500 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001501 << ", ageSeconds: " << data.position.ageSeconds << std::endl;
1502 }
1503
1504 if (data.time.valid) {
1505 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1506 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
1507 }
1508
1509 if (data.satelliteDataArray.size() != 0) {
1510 internalState << "Satellite Data:: ";
1511 }
1512
1513 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1514 internalState << "svid: " << data.satelliteDataArray[i].svid
1515 << ", constellation: "
1516 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1517 << ", ephemerisType: "
1518 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1519 << ", ephemerisAgeSeconds: "
1520 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1521 }
1522 result = env->NewStringUTF(internalState.str().c_str());
1523 }
1524 return result;
1525}
1526
1527static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1528 jobject /* obj */,
1529 jboolean connected,
1530 jint type,
1531 jboolean roaming,
1532 jboolean available,
1533 jstring extraInfo,
1534 jstring apn) {
1535 if (agnssRilIface != nullptr) {
1536 auto result = agnssRilIface->updateNetworkState(connected,
1537 static_cast<IAGnssRil::NetworkType>(type),
1538 roaming);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001539 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001540 ALOGE("updateNetworkState failed");
1541 }
1542
1543 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1544 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001545 if ((!result) || (!result.isOk())) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001546 ALOGE("updateNetworkAvailability failed");
1547 }
1548
1549 env->ReleaseStringUTFChars(apn, c_apn);
1550 } else {
1551 ALOGE("AGnssRilInterface does not exist");
1552 }
1553}
1554
1555static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1556 JNIEnv* /* env */, jobject /* obj */) {
1557 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1558}
1559
1560static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1561 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1562 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1563 jint unknown_timer) {
1564 if (gnssGeofencingIface != nullptr) {
1565 auto result = gnssGeofencingIface->addGeofence(
1566 geofenceId, latitude, longitude, radius,
1567 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1568 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001569 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001570 } else {
1571 ALOGE("Geofence Interface not available");
1572 }
1573 return JNI_FALSE;
1574}
1575
1576static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1577 jobject /* obj */, jint geofenceId) {
1578 if (gnssGeofencingIface != nullptr) {
1579 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001580 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001581 } else {
1582 ALOGE("Geofence interface not available");
1583 }
1584 return JNI_FALSE;
1585}
1586
1587static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1588 jobject /* obj */, jint geofenceId) {
1589 if (gnssGeofencingIface != nullptr) {
1590 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001591 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001592 } else {
1593 ALOGE("Geofence interface not available");
1594 }
1595 return JNI_FALSE;
1596}
1597
1598static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1599 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1600 if (gnssGeofencingIface != nullptr) {
1601 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001602 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 } else {
1604 ALOGE("Geofence interface not available");
1605 }
1606 return JNI_FALSE;
1607}
1608
Lifu Tang30f95a72016-01-07 23:20:38 -08001609static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001610 JNIEnv* env, jclass clazz) {
1611 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001612 return JNI_TRUE;
1613 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614
destradaaea8a8a62014-06-23 18:19:03 -07001615 return JNI_FALSE;
1616}
1617
Lifu Tang30f95a72016-01-07 23:20:38 -08001618static jboolean android_location_GnssLocationProvider_start_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001619 JNIEnv* env,
1620 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001621 if (gnssMeasurementIface == nullptr) {
1622 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001623 return JNI_FALSE;
1624 }
1625
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001626 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
1627 IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
1628 if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
1629 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1630 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001631 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 } else {
1633 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001634 }
1635
1636 return JNI_TRUE;
1637}
1638
Lifu Tang30f95a72016-01-07 23:20:38 -08001639static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001640 JNIEnv* env,
1641 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001642 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001643 ALOGE("Measurement interface not available");
1644 return JNI_FALSE;
1645 }
1646
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001648 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001649}
1650
Lifu Tang30f95a72016-01-07 23:20:38 -08001651static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001652 JNIEnv* env,
1653 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001654 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001655 return JNI_TRUE;
1656 }
1657 return JNI_FALSE;
1658}
1659
Lifu Tang30f95a72016-01-07 23:20:38 -08001660static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001661 JNIEnv* env,
1662 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001663 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001664 ALOGE("Navigation Message interface is not available.");
1665 return JNI_FALSE;
1666 }
1667
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001668 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1669 new GnssNavigationMessageCallback();
1670 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1671 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1672
1673 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1674 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001675 return JNI_FALSE;
1676 }
1677
1678 return JNI_TRUE;
1679}
1680
Lifu Tang30f95a72016-01-07 23:20:38 -08001681static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001682 JNIEnv* env,
1683 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001684 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001685 ALOGE("Navigation Message interface is not available.");
1686 return JNI_FALSE;
1687 }
1688
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001689 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001690 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001691}
1692
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1694 jobject,
1695 jint emergencySuplPdn) {
1696 if (gnssConfigurationIface == nullptr) {
1697 ALOGE("no GNSS configuration interface available");
1698 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001699 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001700
1701 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001702 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001703 return result;
1704 } else {
1705 return JNI_FALSE;
1706 }
1707}
1708
1709static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1710 jobject,
1711 jint version) {
1712 if (gnssConfigurationIface == nullptr) {
1713 ALOGE("no GNSS configuration interface available");
1714 return JNI_FALSE;
1715 }
1716 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001717 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001718 return result;
1719 } else {
1720 return JNI_FALSE;
1721 }
1722}
1723
1724static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1725 jobject,
1726 jint suplEs) {
1727 if (gnssConfigurationIface == nullptr) {
1728 ALOGE("no GNSS configuration interface available");
1729 return JNI_FALSE;
1730 }
1731
1732 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001733 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001734 return result;
1735 } else {
1736 return JNI_FALSE;
1737 }
1738}
1739
1740static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1741 jobject,
1742 jint mode) {
1743 if (gnssConfigurationIface == nullptr) {
1744 ALOGE("no GNSS configuration interface available");
1745 return JNI_FALSE;
1746 }
1747
1748 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001749 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 return result;
1751 } else {
1752 return JNI_FALSE;
1753 }
1754}
1755
1756static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1757 jobject,
1758 jint gpsLock) {
1759 if (gnssConfigurationIface == nullptr) {
1760 ALOGE("no GNSS configuration interface available");
1761 return JNI_FALSE;
1762 }
1763
1764 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001765 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 return result;
1767 } else {
1768 return JNI_FALSE;
1769 }
1770}
1771
1772static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1773 jobject,
1774 jint lppProfile) {
1775 if (gnssConfigurationIface == nullptr) {
1776 ALOGE("no GNSS configuration interface available");
1777 return JNI_FALSE;
1778 }
1779
1780 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1781
Steven Morelandd002a8b2017-01-03 17:18:24 -08001782 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001783 return result;
1784 } else {
1785 return JNI_FALSE;
1786 }
1787}
1788
1789static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1790 jobject,
1791 jint gnssPosProtocol) {
1792 if (gnssConfigurationIface == nullptr) {
1793 ALOGE("no GNSS configuration interface available");
1794 return JNI_FALSE;
1795 }
1796
1797 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001798 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001799 return result;
1800 } else {
1801 return JNI_FALSE;
1802 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001803}
1804
Wyatt Rileycf879db2017-01-12 13:57:38 -08001805static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1806 if (gnssBatchingIface == nullptr) {
1807 return 0; // batching not supported, size = 0
1808 }
1809 auto result = gnssBatchingIface->getBatchSize();
1810 if (result.isOk()) {
1811 return static_cast<jint>(result);
1812 } else {
1813 return 0; // failure in binder, don't support batching
1814 }
1815}
1816
1817static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1818 if (gnssBatchingIface == nullptr) {
1819 return JNI_FALSE; // batching not supported
1820 }
1821 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1822
1823 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1824}
1825
1826static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1827 if (gnssBatchingIface == nullptr) {
1828 return; // batching not supported
1829 }
1830 gnssBatchingIface->cleanup();
1831}
1832
1833static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1834 jlong periodNanos, jboolean wakeOnFifoFull) {
1835 if (gnssBatchingIface == nullptr) {
1836 return JNI_FALSE; // batching not supported
1837 }
1838
1839 IGnssBatching::Options options;
1840 options.periodNanos = periodNanos;
1841 if (wakeOnFifoFull) {
1842 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1843 } else {
1844 options.flags = 0;
1845 }
1846
1847 return static_cast<jboolean>(gnssBatchingIface->start(options));
1848}
1849
1850static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1851 if (gnssBatchingIface == nullptr) {
1852 return; // batching not supported
1853 }
1854
1855 gnssBatchingIface->flush();
1856}
1857
1858static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1859 if (gnssBatchingIface == nullptr) {
1860 return JNI_FALSE; // batching not supported
1861 }
1862
1863 return gnssBatchingIface->stop();
1864}
1865
Daniel Micay76f6a862015-09-19 17:31:01 -04001866static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001868 {"class_init_native", "()V", reinterpret_cast<void *>(
1869 android_location_GnssLocationProvider_class_init_native)},
1870 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1871 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001872 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001873 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001874 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001875 reinterpret_cast<void *>(
1876 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1877 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1878 {"native_cleanup", "()V", reinterpret_cast<void *>(
1879 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001880 {"native_set_position_mode",
1881 "(IIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001882 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
1883 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1884 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001885 {"native_delete_aiding_data",
1886 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001887 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001888 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001889 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001890 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1891 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1892 android_location_GnssLocationProvider_read_nmea)},
1893 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1894 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001895 {"native_inject_location",
1896 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001897 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1898 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1899 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001900 {"native_inject_xtra_data",
1901 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001902 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001903 {"native_agps_data_conn_open",
1904 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001905 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07001906 {"native_agps_data_conn_closed",
1907 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001908 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07001909 {"native_agps_data_conn_failed",
1910 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001911 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07001912 {"native_agps_set_id",
1913 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001914 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07001915 {"native_agps_set_ref_location_cellid",
1916 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001917 reinterpret_cast<void *>(
1918 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07001919 {"native_set_agps_server",
1920 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001921 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07001922 {"native_send_ni_response",
1923 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001924 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07001925 {"native_get_internal_state",
1926 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001927 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001928 {"native_update_network_state",
1929 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001930 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07001931 {"native_is_geofence_supported",
1932 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001933 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001934 {"native_add_geofence",
1935 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001936 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001937 {"native_remove_geofence",
1938 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001939 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
1940 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
1941 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001942 {"native_resume_geofence",
1943 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001944 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07001945 {"native_is_measurement_supported",
1946 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001947 reinterpret_cast<void *>(
1948 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07001949 {"native_start_measurement_collection",
1950 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001951 reinterpret_cast<void *>(
1952 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07001953 {"native_stop_measurement_collection",
1954 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001955 reinterpret_cast<void *>(
1956 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001957 {"native_is_navigation_message_supported",
1958 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001959 reinterpret_cast<void *>(
1960 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07001961 {"native_start_navigation_message_collection",
1962 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001963 reinterpret_cast<void *>(
1964 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07001965 {"native_stop_navigation_message_collection",
1966 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001967 reinterpret_cast<void *>(
1968 android_location_GnssLocationProvider_stop_navigation_message_collection)},
1969 {"native_set_supl_es",
1970 "(I)Z",
1971 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
1972 {"native_set_supl_version",
1973 "(I)Z",
1974 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
1975 {"native_set_supl_mode",
1976 "(I)Z",
1977 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
1978 {"native_set_lpp_profile",
1979 "(I)Z",
1980 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
1981 {"native_set_gnss_pos_protocol_select",
1982 "(I)Z",
1983 reinterpret_cast<void *>(
1984 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
1985 {"native_set_gps_lock",
1986 "(I)Z",
1987 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
1988 {"native_set_emergency_supl_pdn",
1989 "(I)Z",
1990 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08001991 {"native_get_batch_size",
1992 "()I",
1993 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
1994 {"native_init_batching",
1995 "()Z",
1996 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
1997 {"native_start_batch",
1998 "(JZ)Z",
1999 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2000 {"native_flush_batch",
2001 "()V",
2002 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2003 {"native_stop_batch",
2004 "()Z",
2005 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2006 {"native_init_batching",
2007 "()Z",
2008 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2009 {"native_cleanup_batching",
2010 "()V",
2011 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012};
2013
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002014int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002015 return jniRegisterNativeMethods(
2016 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002017 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002018 sMethods,
2019 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020}
2021
2022} /* namespace android */