blob: 288f3509b3937b433cd75b089a5e5edee2eddec1 [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
gomo48f1a642017-11-10 20:35:46 -080021#include <android/hardware/gnss/1.0/IGnss.h>
Wyatt Rileyfb840922017-11-08 15:07:58 -080022#include <android/hardware/gnss/1.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070023
gomo48f1a642017-11-10 20:35:46 -080024#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
25#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070026#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#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;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080051static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040053static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080054static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020055static jmethodID method_requestRefLocation;
56static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040057static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070058static jmethodID method_reportGeofenceTransition;
59static jmethodID method_reportGeofenceStatus;
60static jmethodID method_reportGeofenceAddStatus;
61static jmethodID method_reportGeofenceRemoveStatus;
62static jmethodID method_reportGeofencePauseStatus;
63static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070064static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070065static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080066static jmethodID method_reportLocationBatch;
Yu-Han Yang52057622018-04-25 00:51:22 -070067static jmethodID method_reportGnssServiceDied;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080069/*
70 * Save a pointer to JavaVm to attach/detach threads executing
71 * callback methods that need to make JNI calls.
72 */
73static JavaVM* sJvm;
74
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070075using android::OK;
76using android::sp;
gomo25208882017-04-15 02:05:25 -070077using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070078using android::status_t;
79using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070081using android::hardware::Return;
82using android::hardware::Void;
83using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070084using android::hardware::hidl_death_recipient;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070085using android::hardware::gnss::V1_0::GnssConstellationType;
Wyatt Rileyfb840922017-11-08 15:07:58 -080086using android::hardware::gnss::V1_0::GnssLocation;
87using android::hardware::gnss::V1_0::GnssLocationFlags;
Wyatt Riley46ac9562018-03-02 20:16:58 -080088
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070089using android::hardware::gnss::V1_0::IAGnss;
90using android::hardware::gnss::V1_0::IAGnssCallback;
91using android::hardware::gnss::V1_0::IAGnssCallback;
92using android::hardware::gnss::V1_0::IAGnssRil;
93using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080094using android::hardware::gnss::V1_0::IGnssBatching;
95using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070096using android::hardware::gnss::V1_0::IGnssDebug;
97using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
98using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070099using android::hardware::gnss::V1_0::IGnssNavigationMessage;
100using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
101using android::hardware::gnss::V1_0::IGnssNi;
102using android::hardware::gnss::V1_0::IGnssNiCallback;
103using android::hardware::gnss::V1_0::IGnssXtra;
104using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800105
Wyatt Rileyfb840922017-11-08 15:07:58 -0800106using android::hardware::gnss::V1_1::IGnssCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800107
108using android::hidl::base::V1_0::IBase;
109
110using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
111using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700112using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
113using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800114using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
115using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
116using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
117using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
118
Wyatt Rileyfb840922017-11-08 15:07:58 -0800119
gomo25208882017-04-15 02:05:25 -0700120struct GnssDeathRecipient : virtual public hidl_death_recipient
121{
122 // hidl_death_recipient interface
123 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700124 ALOGE("IGNSS hidl service failed, trying to recover...");
125
126 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
127 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700128 }
129};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700130
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800131// Must match the value from GnssMeasurement.java
132static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
133
gomo25208882017-04-15 02:05:25 -0700134sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800135sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800136sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700137sp<IGnssXtra> gnssXtraIface = nullptr;
138sp<IAGnssRil> agnssRilIface = nullptr;
139sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
140sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800141sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700142sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700143sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
144sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700145sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800146sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
147sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700148sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400150#define WAKE_LOCK_NAME "GPS"
151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152namespace android {
153
Lifu Tang120480f2016-02-07 18:08:19 -0800154template<class T>
155class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700156 public:
157 // Helper function to call setter on a Java object.
158 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800159 JNIEnv* env,
160 jclass clazz,
161 jobject object,
162 const char* method_name,
163 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700164
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700165 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800166 static const char *const signature_;
167};
Lifu Tange5a0e212016-01-25 18:02:17 -0800168
Lifu Tang120480f2016-02-07 18:08:19 -0800169template<class T>
170void JavaMethodHelper<T>::callJavaMethod(
171 JNIEnv* env,
172 jclass clazz,
173 jobject object,
174 const char* method_name,
175 T value) {
176 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
177 env->CallVoidMethod(object, method, value);
178}
destradaaea8a8a62014-06-23 18:19:03 -0700179
Lifu Tang120480f2016-02-07 18:08:19 -0800180class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700181 public:
182 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800183 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700184 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800185
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700186 template<class T>
187 void callSetter(const char* method_name, T value);
188 template<class T>
189 void callSetter(const char* method_name, T* value, size_t size);
190 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800191
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700192 private:
193 JNIEnv* env_;
194 jclass clazz_;
195 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800196};
197
198JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
199 clazz_ = env_->FindClass(class_name);
200 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
201 object_ = env_->NewObject(clazz_, ctor);
202}
203
Wyatt Rileycf879db2017-01-12 13:57:38 -0800204JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
205 clazz_ = env_->FindClass(class_name);
206 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
207 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
208}
209
Lifu Tang120480f2016-02-07 18:08:19 -0800210JavaObject::~JavaObject() {
211 env_->DeleteLocalRef(clazz_);
212}
213
214template<class T>
215void JavaObject::callSetter(const char* method_name, T value) {
216 JavaMethodHelper<T>::callJavaMethod(
217 env_, clazz_, object_, method_name, value);
218}
219
220template<>
221void JavaObject::callSetter(
222 const char* method_name, uint8_t* value, size_t size) {
223 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700224 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800225 jmethodID method = env_->GetMethodID(
226 clazz_,
227 method_name,
228 "([B)V");
229 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700230 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800231}
232
233jobject JavaObject::get() {
234 return object_;
235}
236
237// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800238template<>
239const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
240template<>
241const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
242template<>
243const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
244template<>
245const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
246template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800247const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
248template<>
249const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800250template<>
251const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
252template<>
253const char *const JavaMethodHelper<float>::signature_ = "(F)V";
254template<>
255const char *const JavaMethodHelper<double>::signature_ = "(D)V";
256template<>
257const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
258
259#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800260
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700261static inline jboolean boolToJbool(bool value) {
262 return value ? JNI_TRUE : JNI_FALSE;
263}
Lifu Tang120480f2016-02-07 18:08:19 -0800264
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700265static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
266 if (env->ExceptionCheck()) {
267 ALOGE("An exception was thrown by callback '%s'.", methodName);
268 LOGE_EX(env);
269 env->ExceptionClear();
270 }
271}
destradaaea8a8a62014-06-23 18:19:03 -0700272
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800273class ScopedJniThreadAttach {
274public:
275 ScopedJniThreadAttach() {
276 /*
277 * attachResult will also be JNI_OK if the thead was already attached to
278 * JNI before the call to AttachCurrentThread().
279 */
280 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
281 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
282 attachResult);
283 }
284
285 ~ScopedJniThreadAttach() {
286 jint detachResult = sJvm->DetachCurrentThread();
287 /*
288 * Return if the thread was already detached. Log error for any other
289 * failure.
290 */
291 if (detachResult == JNI_EDETACHED) {
292 return;
293 }
294
295 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
296 detachResult);
297 }
298
299 JNIEnv* getEnv() {
300 /*
301 * Checking validity of mEnv in case the thread was detached elsewhere.
302 */
303 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
304 return mEnv;
305 }
306
307private:
308 JNIEnv* mEnv = nullptr;
309};
310
311thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
312
313static JNIEnv* getJniEnv() {
314 JNIEnv* env = AndroidRuntime::getJNIEnv();
315
316 /*
317 * If env is nullptr, the thread is not already attached to
318 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
319 * will detach it on thread exit.
320 */
321 if (env == nullptr) {
322 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
323 env = tJniThreadAttacher->getEnv();
324 }
325
326 return env;
327}
328
Wyatt Rileyfb840922017-11-08 15:07:58 -0800329static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800330 JavaObject object(env, "android/location/Location", "gps");
331
332 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800333 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800334 SET(Latitude, location.latitudeDegrees);
335 SET(Longitude, location.longitudeDegrees);
336 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800337 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800338 SET(Altitude, location.altitudeMeters);
339 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800340 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800341 SET(Speed, location.speedMetersPerSec);
342 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800343 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800344 SET(Bearing, location.bearingDegrees);
345 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800346 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800347 SET(Accuracy, location.horizontalAccuracyMeters);
348 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800349 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800350 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
351 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800352 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800353 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
354 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800355 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800356 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
357 }
358 SET(Time, location.timestamp);
359
360 return object.get();
361}
362
Yu-Han Yange7baef32018-02-09 13:58:17 -0800363static GnssLocation createGnssLocation(
364 jint gnssLocationFlags,
365 jdouble latitudeDegrees,
366 jdouble longitudeDegrees,
367 jdouble altitudeMeters,
368 jfloat speedMetersPerSec,
369 jfloat bearingDegrees,
370 jfloat horizontalAccuracyMeters,
371 jfloat verticalAccuracyMeters,
372 jfloat speedAccuracyMetersPerSecond,
373 jfloat bearingAccuracyDegrees,
374 jlong timestamp) {
375 GnssLocation location;
376 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
377 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
378 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
379 location.altitudeMeters = static_cast<double>(altitudeMeters);
380 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
381 location.bearingDegrees = static_cast<float>(bearingDegrees);
382 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
383 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
384 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
385 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
386 location.timestamp = static_cast<uint64_t>(timestamp);
387
388 return location;
389}
390
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700391/*
392 * GnssCallback class implements the callback methods for IGnss interface.
393 */
394struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800395 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700396 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
397 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
398 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
399 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
400 Return<void> gnssAcquireWakelockCb() override;
401 Return<void> gnssReleaseWakelockCb() override;
402 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800403 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700404 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800405
Wyatt Rileyfb840922017-11-08 15:07:58 -0800406 // New in 1.1
407 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
408
Wyatt Riley26465d22018-02-12 13:44:24 -0800409 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700410 static const char* sNmeaString;
411 static size_t sNmeaStringLength;
412};
413
Wyatt Rileyfb840922017-11-08 15:07:58 -0800414Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
415 ALOGD("%s: name=%s\n", __func__, name.c_str());
416
Wyatt Rileyfb840922017-11-08 15:07:58 -0800417 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800418 jstring jstringName = env->NewStringUTF(name.c_str());
419 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800420 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800421
Wyatt Rileyfb840922017-11-08 15:07:58 -0800422 return Void();
423}
424
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700425const char* GnssCallback::sNmeaString = nullptr;
426size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700427
Wyatt Rileyfb840922017-11-08 15:07:58 -0800428Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800429 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800430
431 jobject jLocation = translateLocation(env, location);
432 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800433 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800434
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700435 env->CallVoidMethod(mCallbacksObj,
436 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800437 boolToJbool(hasLatLong),
438 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700439 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800440 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700441 return Void();
442}
443
444Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800445 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700446 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
447 checkAndClearExceptionFromCallback(env, __FUNCTION__);
448 return Void();
449}
450
451Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800452 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700453
Wyatt Riley26465d22018-02-12 13:44:24 -0800454 uint32_t listSize = svStatus.numSvs;
455 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700456 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800457 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700458 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800459 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800460 }
461
Wyatt Riley26465d22018-02-12 13:44:24 -0800462 jintArray svidWithFlagArray = env->NewIntArray(listSize);
463 jfloatArray cn0Array = env->NewFloatArray(listSize);
464 jfloatArray elevArray = env->NewFloatArray(listSize);
465 jfloatArray azimArray = env->NewFloatArray(listSize);
466 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
467
468 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
469 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
470 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
471 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
472 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
473
474 /*
475 * Read GNSS SV info.
476 */
477 for (size_t i = 0; i < listSize; ++i) {
478 enum ShiftWidth: uint8_t {
479 SVID_SHIFT_WIDTH = 8,
480 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
481 };
482
483 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
484 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
485 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
486 static_cast<uint32_t>(info.svFlag);
487 cn0s[i] = info.cN0Dbhz;
488 elev[i] = info.elevationDegrees;
489 azim[i] = info.azimuthDegrees;
490 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800491 }
destradaaea8a8a62014-06-23 18:19:03 -0700492
Wyatt Riley26465d22018-02-12 13:44:24 -0800493 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
494 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
495 env->ReleaseFloatArrayElements(elevArray, elev, 0);
496 env->ReleaseFloatArrayElements(azimArray, azim, 0);
497 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
498
499 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
500 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
501 carrierFreqArray);
502
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700503 checkAndClearExceptionFromCallback(env, __FUNCTION__);
504 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700505}
506
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700507Return<void> GnssCallback::gnssNmeaCb(
508 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800509 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700510 /*
511 * The Java code will call back to read these values.
512 * We do this to avoid creating unnecessary String objects.
513 */
514 sNmeaString = nmea.c_str();
515 sNmeaStringLength = nmea.size();
516
517 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
518 checkAndClearExceptionFromCallback(env, __FUNCTION__);
519 return Void();
520}
521
522Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
523 ALOGD("%s: %du\n", __func__, capabilities);
524
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800525 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700526 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
527 checkAndClearExceptionFromCallback(env, __FUNCTION__);
528 return Void();
529}
530
531Return<void> GnssCallback::gnssAcquireWakelockCb() {
532 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
533 return Void();
534}
535
536Return<void> GnssCallback::gnssReleaseWakelockCb() {
537 release_wake_lock(WAKE_LOCK_NAME);
538 return Void();
539}
540
541Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800542 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700543 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
544 checkAndClearExceptionFromCallback(env, __FUNCTION__);
545 return Void();
546}
547
Yu-Han Yang21988932018-01-23 15:07:37 -0800548Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800549 JNIEnv* env = getJniEnv();
550 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
551 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800552 return Void();
553}
554
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700555Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
556 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
557
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800558 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700559 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
560 info.yearOfHw);
561 checkAndClearExceptionFromCallback(env, __FUNCTION__);
562 return Void();
563}
564
565class GnssXtraCallback : public IGnssXtraCallback {
566 Return<void> downloadRequestCb() override;
567};
568
569/*
570 * GnssXtraCallback class implements the callback methods for the IGnssXtra
571 * interface.
572 */
573Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800574 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700575 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
576 checkAndClearExceptionFromCallback(env, __FUNCTION__);
577 return Void();
578}
579
580/*
581 * GnssGeofenceCallback class implements the callback methods for the
582 * IGnssGeofence interface.
583 */
584struct GnssGeofenceCallback : public IGnssGeofenceCallback {
585 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
586 Return<void> gnssGeofenceTransitionCb(
587 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800588 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700589 GeofenceTransition transition,
590 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
591 Return<void> gnssGeofenceStatusCb(
592 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800593 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700594 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
595 GeofenceStatus status) override;
596 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
597 GeofenceStatus status) override;
598 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
599 GeofenceStatus status) override;
600 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
601 GeofenceStatus status) override;
602};
603
604Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
605 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800606 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700607 GeofenceTransition transition,
608 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800609 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700610
Wyatt Riley5d229832017-02-10 17:06:00 -0800611 jobject jLocation = translateLocation(env, location);
612
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700613 env->CallVoidMethod(mCallbacksObj,
614 method_reportGeofenceTransition,
615 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800616 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700617 transition,
618 timestamp);
619
620 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800621 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700622 return Void();
623}
624
625Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
626 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800627 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800628 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800629
630 jobject jLocation = translateLocation(env, location);
631
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700632 env->CallVoidMethod(mCallbacksObj,
633 method_reportGeofenceStatus,
634 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800635 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700636 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800637 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700638 return Void();
639}
640
641Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
642 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800643 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700644 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
645 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
646 }
647
648 env->CallVoidMethod(mCallbacksObj,
649 method_reportGeofenceAddStatus,
650 geofenceId,
651 status);
652 checkAndClearExceptionFromCallback(env, __FUNCTION__);
653 return Void();
654}
655
656Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
657 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800658 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700659 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
660 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
661 }
662
663 env->CallVoidMethod(mCallbacksObj,
664 method_reportGeofenceRemoveStatus,
665 geofenceId, status);
666 checkAndClearExceptionFromCallback(env, __FUNCTION__);
667 return Void();
668}
669
670Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
671 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800672 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700673 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
674 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
675 }
676
677 env->CallVoidMethod(mCallbacksObj,
678 method_reportGeofencePauseStatus,
679 geofenceId, status);
680 checkAndClearExceptionFromCallback(env, __FUNCTION__);
681 return Void();
682}
683
684Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
685 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800686 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700687 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
688 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
689 }
690
691 env->CallVoidMethod(mCallbacksObj,
692 method_reportGeofenceResumeStatus,
693 geofenceId, status);
694 checkAndClearExceptionFromCallback(env, __FUNCTION__);
695 return Void();
696}
697
698/*
699 * GnssNavigationMessageCallback interface implements the callback methods
700 * required by the IGnssNavigationMessage interface.
701 */
702struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
703 /*
704 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
705 * follow.
706 */
707 Return<void> gnssNavigationMessageCb(
708 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
709};
710
711Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
712 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800713 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700714
715 size_t dataLength = message.data.size();
716
717 std::vector<uint8_t> navigationData = message.data;
718 uint8_t* data = &(navigationData[0]);
719 if (dataLength == 0 || data == NULL) {
720 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
721 dataLength);
722 return Void();
723 }
724
725 JavaObject object(env, "android/location/GnssNavigationMessage");
726 SET(Type, static_cast<int32_t>(message.type));
727 SET(Svid, static_cast<int32_t>(message.svid));
728 SET(MessageId, static_cast<int32_t>(message.messageId));
729 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
730 object.callSetter("setData", data, dataLength);
731 SET(Status, static_cast<int32_t>(message.status));
732
733 jobject navigationMessage = object.get();
734 env->CallVoidMethod(mCallbacksObj,
735 method_reportNavigationMessages,
736 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800737 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700738 env->DeleteLocalRef(navigationMessage);
739 return Void();
740}
741
742/*
743 * GnssMeasurementCallback implements the callback methods required for the
744 * GnssMeasurement interface.
745 */
Wyatt Riley46ac9562018-03-02 20:16:58 -0800746struct GnssMeasurementCallback : public IGnssMeasurementCallback_V1_1 {
747 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800748 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700749 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800750 void translateGnssMeasurement_V1_0(
751 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800752 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700753 jobjectArray translateGnssMeasurements(
754 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800755 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800756 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700757 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800758 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800759 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700760 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
761};
762
763
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800764Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800765 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800766 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700767
768 jobject clock;
769 jobjectArray measurementArray;
770
771 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800772
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700773 measurementArray = translateGnssMeasurements(
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800774 env, data.measurements.data(), NULL, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700775 setMeasurementData(env, clock, measurementArray);
776
777 env->DeleteLocalRef(clock);
778 env->DeleteLocalRef(measurementArray);
779 return Void();
780}
781
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800782Return<void> GnssMeasurementCallback::GnssMeasurementCb(
783 const IGnssMeasurementCallback_V1_0::GnssData& data) {
784 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800785
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800786 jobject clock;
787 jobjectArray measurementArray;
788
789 clock = translateGnssClock(env, &data.clock);
790 measurementArray = translateGnssMeasurements(
791 env, NULL, data.measurements.data(), data.measurementCount);
792 setMeasurementData(env, clock, measurementArray);
793
794 env->DeleteLocalRef(clock);
795 env->DeleteLocalRef(measurementArray);
796 return Void();
797}
798
799// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
800void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
801 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800802 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700803 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700804
805 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800806 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700807 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800808 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700809 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800810 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700811 measurement->receivedSvTimeUncertaintyInNs);
812 SET(Cn0DbHz, measurement->cN0DbHz);
813 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800814 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700815 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800816 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800817 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
818 !ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700819 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800820 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700821 measurement->accumulatedDeltaRangeUncertaintyM);
822
823 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
824 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
825 }
826
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800827 // Intentionally not copying deprecated fields of carrierCycles,
828 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700829
830 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
831
832 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
833 SET(SnrInDb, measurement->snrDb);
834 }
Lifu Tang120480f2016-02-07 18:08:19 -0800835
gomo4402af62017-01-11 13:20:13 -0800836 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800837 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800838 }
Lifu Tang120480f2016-02-07 18:08:19 -0800839}
840
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700841jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800842 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700843 JavaObject object(env, "android/location/GnssClock");
844
845 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
846 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
847 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
848 }
849
850 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
851 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
852 }
853
854 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
855 SET(FullBiasNanos, clock->fullBiasNs);
856 }
857
858 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
859 SET(BiasNanos, clock->biasNs);
860 }
861
862 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
863 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
864 }
865
866 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
867 SET(DriftNanosPerSecond, clock->driftNsps);
868 }
869
870 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
871 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
872 }
873
874 SET(TimeNanos, clock->timeNs);
875 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
876
877 return object.get();
878}
879
880jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800881 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800882 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
883 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800884 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700885 return NULL;
886 }
887
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700888 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800889 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800890 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800891 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700892 NULL /* initialElement */);
893
Lifu Tang120480f2016-02-07 18:08:19 -0800894 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800895 JavaObject object(env, "android/location/GnssMeasurement");
Wyatt Riley46ac9562018-03-02 20:16:58 -0800896 if (measurements_v1_1 != NULL) {
897 translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800898
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800899 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800900 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800901 (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
902 ADR_STATE_HALF_CYCLE_REPORTED));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800903 } else {
904 translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
905 }
906
907 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700908 }
909
Lifu Tang818aa2c2016-02-01 01:52:00 -0800910 env->DeleteLocalRef(gnssMeasurementClass);
911 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700912}
913
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700914void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
915 jobjectArray measurementArray) {
916 jclass gnssMeasurementsEventClass =
917 env->FindClass("android/location/GnssMeasurementsEvent");
918 jmethodID gnssMeasurementsEventCtor =
919 env->GetMethodID(
920 gnssMeasurementsEventClass,
921 "<init>",
922 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800923
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700924 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
925 gnssMeasurementsEventCtor,
926 clock,
927 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800928
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700929 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
930 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800931 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800932 env->DeleteLocalRef(gnssMeasurementsEventClass);
933 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700934}
935
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700936/*
937 * GnssNiCallback implements callback methods required by the IGnssNi interface.
938 */
939struct GnssNiCallback : public IGnssNiCallback {
940 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
941 override;
destradaaea8a8a62014-06-23 18:19:03 -0700942};
943
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700944Return<void> GnssNiCallback::niNotifyCb(
945 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800946 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700947 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
948 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
949
950 if (requestorId && text) {
951 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
952 notification.notificationId, notification.niType,
953 notification.notifyFlags, notification.timeoutSec,
954 notification.defaultResponse, requestorId, text,
955 notification.requestorIdEncoding,
956 notification.notificationIdEncoding);
957 } else {
958 ALOGE("%s: OOM Error\n", __func__);
959 }
960
961 if (requestorId) {
962 env->DeleteLocalRef(requestorId);
963 }
964
965 if (text) {
966 env->DeleteLocalRef(text);
967 }
968 checkAndClearExceptionFromCallback(env, __FUNCTION__);
969 return Void();
970}
971
972/*
973 * AGnssCallback implements callback methods required by the IAGnss interface.
974 */
975struct AGnssCallback : public IAGnssCallback {
976 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
977 Return<void> agnssStatusIpV6Cb(
978 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
979
980 Return<void> agnssStatusIpV4Cb(
981 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
982 private:
983 jbyteArray convertToIpV4(uint32_t ip);
984};
985
986Return<void> AGnssCallback::agnssStatusIpV6Cb(
987 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800988 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700989 jbyteArray byteArray = NULL;
990 bool isSupported = false;
991
992 byteArray = env->NewByteArray(16);
993 if (byteArray != NULL) {
994 env->SetByteArrayRegion(byteArray, 0, 16,
995 (const jbyte*)(agps_status.ipV6Addr.data()));
996 isSupported = true;
997 } else {
998 ALOGE("Unable to allocate byte array for IPv6 address.");
999 }
1000
1001 IF_ALOGD() {
1002 // log the IP for reference in case there is a bogus value pushed by HAL
1003 char str[INET6_ADDRSTRLEN];
1004 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1005 ALOGD("AGPS IP is v6: %s", str);
1006 }
1007
1008 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1009 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1010 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1011 agps_status.type, agps_status.status, byteArray);
1012
1013 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1014
1015 if (byteArray) {
1016 env->DeleteLocalRef(byteArray);
1017 }
1018
1019 return Void();
1020}
1021
1022Return<void> AGnssCallback::agnssStatusIpV4Cb(
1023 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001024 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001025 jbyteArray byteArray = NULL;
1026
1027 uint32_t ipAddr = agps_status.ipV4Addr;
1028 byteArray = convertToIpV4(ipAddr);
1029
1030 IF_ALOGD() {
1031 /*
1032 * log the IP for reference in case there is a bogus value pushed by
1033 * HAL.
1034 */
1035 char str[INET_ADDRSTRLEN];
1036 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1037 ALOGD("AGPS IP is v4: %s", str);
1038 }
1039
1040 jsize byteArrayLength =
1041 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1042 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1043 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1044 agps_status.type, agps_status.status, byteArray);
1045
1046 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1047
1048 if (byteArray) {
1049 env->DeleteLocalRef(byteArray);
1050 }
1051 return Void();
1052}
1053
1054jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1055 if (INADDR_NONE == ip) {
1056 return NULL;
1057 }
1058
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001059 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001060 jbyteArray byteArray = env->NewByteArray(4);
1061 if (byteArray == NULL) {
1062 ALOGE("Unable to allocate byte array for IPv4 address");
1063 return NULL;
1064 }
1065
1066 jbyte ipv4[4];
1067 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1068 memcpy(ipv4, &ip, sizeof(ipv4));
1069 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1070 return byteArray;
1071}
1072
1073/*
1074 * AGnssRilCallback implements the callback methods required by the AGnssRil
1075 * interface.
1076 */
1077struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001078 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001079 Return<void> requestRefLocCb() override;
1080};
1081
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001082Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001083 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001084 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1085 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1086 return Void();
1087}
1088
1089Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001090 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001091 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1092 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1093 return Void();
1094}
1095
Wyatt Rileycf879db2017-01-12 13:57:38 -08001096/*
1097 * GnssBatchingCallback interface implements the callback methods
1098 * required by the IGnssBatching interface.
1099 */
1100struct GnssBatchingCallback : public IGnssBatchingCallback {
1101 /*
1102 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1103 * follow.
1104 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001105 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001106 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001107};
1108
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001109Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001110 JNIEnv* env = getJniEnv();
1111
1112 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1113 env->FindClass("android/location/Location"), nullptr);
1114
1115 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001116 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001117 env->SetObjectArrayElement(jLocations, i, jLocation);
1118 env->DeleteLocalRef(jLocation);
1119 }
1120
1121 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1122 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1123
1124 env->DeleteLocalRef(jLocations);
1125
1126 return Void();
1127}
1128
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001129static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001130 gnssHal_V1_1 = IGnss_V1_1::getService();
1131 if (gnssHal_V1_1 == nullptr) {
1132 ALOGD("gnssHal 1.1 was null, trying 1.0");
1133 gnssHal = IGnss_V1_0::getService();
1134 } else {
1135 gnssHal = gnssHal_V1_1;
1136 }
1137}
1138
1139static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001140 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1141 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001142 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001143 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001144 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1145 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1146 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1147 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001148 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1149 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001150 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1151 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1152 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001153 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001154 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1155 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1156 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1157 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001158 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001159 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001160 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001161 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1162 "(II)V");
1163 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1164 "(II)V");
1165 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1166 "(II)V");
1167 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1168 "(II)V");
1169 method_reportMeasurementData = env->GetMethodID(
1170 clazz,
1171 "reportMeasurementData",
1172 "(Landroid/location/GnssMeasurementsEvent;)V");
1173 method_reportNavigationMessages = env->GetMethodID(
1174 clazz,
1175 "reportNavigationMessage",
1176 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001177 method_reportLocationBatch = env->GetMethodID(
1178 clazz,
1179 "reportLocationBatch",
1180 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001181 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001182
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001183 /*
1184 * Save a pointer to JVM.
1185 */
1186 jint jvmStatus = env->GetJavaVM(&sJvm);
1187 if (jvmStatus != JNI_OK) {
1188 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1189 }
1190
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001191 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001192 gnssHalDeathRecipient = new GnssDeathRecipient();
1193 hardware::Return<bool> linked = gnssHal->linkToDeath(
1194 gnssHalDeathRecipient, /*cookie*/ 0);
1195 if (!linked.isOk()) {
1196 ALOGE("Transaction error in linking to GnssHAL death: %s",
1197 linked.description().c_str());
1198 } else if (!linked) {
1199 ALOGW("Unable to link to GnssHal death notifications");
1200 } else {
1201 ALOGD("Link to death notification successful");
1202 }
1203
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001204 auto gnssXtra = gnssHal->getExtensionXtra();
1205 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001206 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001207 } else {
1208 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001209 }
1210
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001211 auto gnssRil = gnssHal->getExtensionAGnssRil();
1212 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001213 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001214 } else {
1215 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001216 }
1217
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001218 auto gnssAgnss = gnssHal->getExtensionAGnss();
1219 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001220 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001221 } else {
1222 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001223 }
1224
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001225 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1226 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001227 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001228 } else {
1229 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001230 }
1231
gomo48f1a642017-11-10 20:35:46 -08001232 if (gnssHal_V1_1 != nullptr) {
1233 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1234 if (!gnssMeasurement.isOk()) {
1235 ALOGD("Unable to get a handle to GnssMeasurement");
1236 } else {
1237 gnssMeasurementIface_V1_1 = gnssMeasurement;
1238 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1239 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001240 } else {
gomo48f1a642017-11-10 20:35:46 -08001241 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1242 if (!gnssMeasurement_V1_0.isOk()) {
1243 ALOGD("Unable to get a handle to GnssMeasurement");
1244 } else {
1245 gnssMeasurementIface = gnssMeasurement_V1_0;
1246 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001247 }
1248
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001249 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1250 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001251 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001252 } else {
1253 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001254 }
1255
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001256 auto gnssNi = gnssHal->getExtensionGnssNi();
1257 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001258 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001259 } else {
1260 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001261 }
1262
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001263 if (gnssHal_V1_1 != nullptr) {
1264 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1265 if (!gnssConfiguration.isOk()) {
1266 ALOGD("Unable to get a handle to GnssConfiguration");
1267 } else {
1268 gnssConfigurationIface_V1_1 = gnssConfiguration;
1269 gnssConfigurationIface = gnssConfigurationIface_V1_1;
1270 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001271 } else {
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001272 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1273 if (!gnssConfiguration_V1_0.isOk()) {
1274 ALOGD("Unable to get a handle to GnssConfiguration");
1275 } else {
1276 gnssConfigurationIface = gnssConfiguration_V1_0;
1277 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001278 }
1279
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001280 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1281 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001282 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001283 } else {
1284 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001285 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001286
1287 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1288 if (!gnssBatching.isOk()) {
1289 ALOGD("Unable to get a handle to gnssBatching");
1290 } else {
1291 gnssBatchingIface = gnssBatching;
1292 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001293 } else {
1294 ALOGE("Unable to get GPS service\n");
1295 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001296}
1297
1298static jboolean android_location_GnssLocationProvider_is_supported(
1299 JNIEnv* /* env */, jclass /* clazz */) {
1300 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1301}
1302
1303static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1304 JNIEnv* /* env */, jclass /* clazz */) {
1305 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1306}
1307
1308static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1309 JNIEnv* /* env */, jclass /* jclazz */) {
1310 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1311}
1312
1313static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1314 /*
1315 * This must be set before calling into the HAL library.
1316 */
1317 if (!mCallbacksObj)
1318 mCallbacksObj = env->NewGlobalRef(obj);
1319
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001320 /*
1321 * Fail if the main interface fails to initialize
1322 */
1323 if (gnssHal == nullptr) {
1324 ALOGE("Unable to Initialize GNSS HAL\n");
1325 return JNI_FALSE;
1326 }
1327
Wyatt Rileyfb840922017-11-08 15:07:58 -08001328 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1329
1330 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001331 if (gnssHal_V1_1 != nullptr) {
1332 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001333 } else {
1334 result = gnssHal->setCallback(gnssCbIface);
1335 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001336 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001337 ALOGE("SetCallback for Gnss Interface fails\n");
1338 return JNI_FALSE;
1339 }
1340
1341 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1342 if (gnssXtraIface == nullptr) {
1343 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001344 } else {
1345 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001346 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001347 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001348 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001349 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001350 }
1351
1352 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1353 if (agnssIface != nullptr) {
1354 agnssIface->setCallback(aGnssCbIface);
1355 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001356 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001357 }
1358
1359 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1360 if (gnssGeofencingIface != nullptr) {
1361 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1362 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001363 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001364 }
1365
1366 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001367 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001368 gnssNiIface->setCallback(gnssNiCbIface);
1369 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001370 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001371 }
1372
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001373 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1374 if (agnssRilIface != nullptr) {
1375 agnssRilIface->setCallback(aGnssRilCbIface);
1376 } else {
1377 ALOGI("Unable to Initialize AGnss Ril interface\n");
1378 }
1379
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001380 return JNI_TRUE;
1381}
1382
1383static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1384 if (gnssHal != nullptr) {
1385 gnssHal->cleanup();
1386 }
1387}
1388
1389static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1390 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001391 jint preferred_time, jboolean low_power_mode) {
1392 Return<bool> result = false;
1393 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001394 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1395 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1396 min_interval,
1397 preferred_accuracy,
1398 preferred_time,
1399 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001400 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001401 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1402 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1403 min_interval,
1404 preferred_accuracy,
1405 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001406 }
1407 if (!result.isOk()) {
1408 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1409 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001410 } else {
gomo48f1a642017-11-10 20:35:46 -08001411 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001412 }
1413}
1414
1415static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1416 if (gnssHal != nullptr) {
1417 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001418 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001419 return JNI_FALSE;
1420 } else {
1421 return result;
1422 }
1423 } else {
1424 return JNI_FALSE;
1425 }
1426}
1427
1428static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1429 if (gnssHal != nullptr) {
1430 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001431 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432 return JNI_FALSE;
1433 } else {
1434 return result;
1435 }
1436 } else {
1437 return JNI_FALSE;
1438 }
1439}
1440static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1441 jobject /* obj */,
1442 jint flags) {
1443 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001444 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001445 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001446 ALOGE("Error in deleting aiding data");
1447 }
1448 }
1449}
1450
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001451static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1452 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1453 IAGnssRil::AGnssRefLocation location;
1454
1455 if (agnssRilIface == nullptr) {
1456 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1457 return;
1458 }
1459
1460 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1461 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1462 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1463 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1464 location.cellID.mcc = mcc;
1465 location.cellID.mnc = mnc;
1466 location.cellID.lac = lac;
1467 location.cellID.cid = cid;
1468 break;
1469 default:
1470 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1471 return;
1472 break;
1473 }
1474
1475 agnssRilIface->setRefLocation(location);
1476}
1477
1478static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1479 jint type, jstring setid_string) {
1480 if (agnssRilIface == nullptr) {
1481 ALOGE("no AGPS RIL interface in agps_set_id");
1482 return;
1483 }
1484
1485 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1486 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1487 env->ReleaseStringUTFChars(setid_string, setid);
1488}
1489
1490static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1491 jbyteArray nmeaArray, jint buffer_size) {
1492 // this should only be called from within a call to reportNmea
1493 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1494 int length = GnssCallback::sNmeaStringLength;
1495 if (length > buffer_size)
1496 length = buffer_size;
1497 memcpy(nmea, GnssCallback::sNmeaString, length);
1498 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1499 return (jint) length;
1500}
1501
1502static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1503 jlong time, jlong timeReference, jint uncertainty) {
1504 if (gnssHal != nullptr) {
1505 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001506 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001507 ALOGE("%s: Gnss injectTime() failed", __func__);
1508 }
1509 }
1510}
1511
Yu-Han Yange7baef32018-02-09 13:58:17 -08001512static void android_location_GnssLocationProvider_inject_best_location(
1513 JNIEnv*,
1514 jobject,
1515 jint gnssLocationFlags,
1516 jdouble latitudeDegrees,
1517 jdouble longitudeDegrees,
1518 jdouble altitudeMeters,
1519 jfloat speedMetersPerSec,
1520 jfloat bearingDegrees,
1521 jfloat horizontalAccuracyMeters,
1522 jfloat verticalAccuracyMeters,
1523 jfloat speedAccuracyMetersPerSecond,
1524 jfloat bearingAccuracyDegrees,
1525 jlong timestamp) {
1526 if (gnssHal_V1_1 != nullptr) {
1527 GnssLocation location = createGnssLocation(
1528 gnssLocationFlags,
1529 latitudeDegrees,
1530 longitudeDegrees,
1531 altitudeMeters,
1532 speedMetersPerSec,
1533 bearingDegrees,
1534 horizontalAccuracyMeters,
1535 verticalAccuracyMeters,
1536 speedAccuracyMetersPerSecond,
1537 bearingAccuracyDegrees,
1538 timestamp);
1539 auto result = gnssHal_V1_1->injectBestLocation(location);
1540 if (!result.isOk() || !result) {
1541 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1542 }
1543 } else {
1544 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1545 }
1546}
1547
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001548static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1549 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1550 if (gnssHal != nullptr) {
1551 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001552 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001553 ALOGE("%s: Gnss injectLocation() failed", __func__);
1554 }
1555 }
1556}
1557
1558static jboolean android_location_GnssLocationProvider_supports_xtra(
1559 JNIEnv* /* env */, jobject /* obj */) {
1560 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1561}
1562
1563static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1564 jbyteArray data, jint length) {
1565 if (gnssXtraIface == nullptr) {
1566 ALOGE("XTRA Interface not supported");
1567 return;
1568 }
1569
1570 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1571 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1572 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1573}
1574
1575static void android_location_GnssLocationProvider_agps_data_conn_open(
1576 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1577 if (agnssIface == nullptr) {
1578 ALOGE("no AGPS interface in agps_data_conn_open");
1579 return;
1580 }
1581 if (apn == NULL) {
1582 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1583 return;
1584 }
1585
1586 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1587
1588 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001589 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001590 ALOGE("%s: Failed to set APN and its IP type", __func__);
1591 }
1592 env->ReleaseStringUTFChars(apn, apnStr);
1593}
1594
1595static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1596 jobject /* obj */) {
1597 if (agnssIface == nullptr) {
1598 ALOGE("%s: AGPS interface not supported", __func__);
1599 return;
1600 }
1601
1602 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001603 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001604 ALOGE("%s: Failed to close AGnss data connection", __func__);
1605 }
1606}
1607
1608static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1609 jobject /* obj */) {
1610 if (agnssIface == nullptr) {
1611 ALOGE("%s: AGPS interface not supported", __func__);
1612 return;
1613 }
1614
1615 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001616 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001617 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1618 }
1619}
1620
1621static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1622 jint type, jstring hostname, jint port) {
1623 if (agnssIface == nullptr) {
1624 ALOGE("no AGPS interface in set_agps_server");
1625 return;
1626 }
1627
1628 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1629 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1630 c_hostname,
1631 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001632 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001633 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1634 }
1635
1636 env->ReleaseStringUTFChars(hostname, c_hostname);
1637}
1638
1639static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1640 jobject /* obj */, jint notifId, jint response) {
1641 if (gnssNiIface == nullptr) {
1642 ALOGE("no NI interface in send_ni_response");
1643 return;
1644 }
1645
1646 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1647}
1648
1649static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1650 jobject /* obj */) {
1651 jstring result = NULL;
1652 /*
1653 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1654 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001655
1656 std::stringstream internalState;
1657
1658 if (gnssDebugIface == nullptr) {
1659 internalState << "Gnss Debug Interface not available" << std::endl;
1660 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001661 IGnssDebug::DebugData data;
1662 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1663 data = debugData;
1664 });
1665
Wyatt Riley268c6e02017-03-29 10:21:46 -07001666 internalState << "Gnss Location Data:: ";
1667 if (!data.position.valid) {
1668 internalState << "not valid";
1669 } else {
1670 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001671 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1672 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001673 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1674 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001675 << ", horizontalAccuracyMeters: "
1676 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001677 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001678 << ", speedAccuracyMetersPerSecond: "
1679 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001680 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001681 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001682 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001683 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001684
Wyatt Riley268c6e02017-03-29 10:21:46 -07001685 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1686 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1687 << ", frequencyUncertaintyNsPerSec: "
1688 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001689
1690 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001691 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1692 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693 }
1694
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001695 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1696 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1697 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1698 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001699 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1700 internalState << "svid: " << data.satelliteDataArray[i].svid
1701 << ", constellation: "
1702 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1703 << ", ephemerisType: "
1704 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001705 << ", ephemerisSource: "
1706 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1707 << ", ephemerisHealth: "
1708 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1709 << ", serverPredictionIsAvailable: "
1710 << data.satelliteDataArray[i].serverPredictionIsAvailable
1711 << ", serverPredictionAgeSeconds: "
1712 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001713 << ", ephemerisAgeSeconds: "
1714 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1715 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001716 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001717
1718 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001719 return result;
1720}
1721
1722static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1723 jobject /* obj */,
1724 jboolean connected,
1725 jint type,
1726 jboolean roaming,
1727 jboolean available,
1728 jstring extraInfo,
1729 jstring apn) {
1730 if (agnssRilIface != nullptr) {
1731 auto result = agnssRilIface->updateNetworkState(connected,
1732 static_cast<IAGnssRil::NetworkType>(type),
1733 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001734 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001735 ALOGE("updateNetworkState failed");
1736 }
1737
1738 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1739 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001740 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001741 ALOGE("updateNetworkAvailability failed");
1742 }
1743
1744 env->ReleaseStringUTFChars(apn, c_apn);
1745 } else {
1746 ALOGE("AGnssRilInterface does not exist");
1747 }
1748}
1749
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001750static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001751 JNIEnv* /* env */, jobject /* obj */) {
1752 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1753}
1754
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001755static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001756 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1757 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1758 jint unknown_timer) {
1759 if (gnssGeofencingIface != nullptr) {
1760 auto result = gnssGeofencingIface->addGeofence(
1761 geofenceId, latitude, longitude, radius,
1762 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1763 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001764 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001765 } else {
1766 ALOGE("Geofence Interface not available");
1767 }
1768 return JNI_FALSE;
1769}
1770
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001771static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001772 jobject /* obj */, jint geofenceId) {
1773 if (gnssGeofencingIface != nullptr) {
1774 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001775 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001776 } else {
1777 ALOGE("Geofence interface not available");
1778 }
1779 return JNI_FALSE;
1780}
1781
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001782static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001783 jobject /* obj */, jint geofenceId) {
1784 if (gnssGeofencingIface != nullptr) {
1785 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001786 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001787 } else {
1788 ALOGE("Geofence interface not available");
1789 }
1790 return JNI_FALSE;
1791}
1792
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001793static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001794 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1795 if (gnssGeofencingIface != nullptr) {
1796 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001797 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001798 } else {
1799 ALOGE("Geofence interface not available");
1800 }
1801 return JNI_FALSE;
1802}
1803
Yu-Han Yang8de21502018-04-23 01:40:25 -07001804static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001805 JNIEnv* env, jclass clazz) {
1806 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001807 return JNI_TRUE;
1808 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001809
destradaaea8a8a62014-06-23 18:19:03 -07001810 return JNI_FALSE;
1811}
1812
Yu-Han Yang8de21502018-04-23 01:40:25 -07001813static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001814 JNIEnv* /* env */,
1815 jobject /* obj */,
1816 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001817 if (gnssMeasurementIface == nullptr) {
1818 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001819 return JNI_FALSE;
1820 }
1821
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001822 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001823 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1824 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1825 if (gnssMeasurementIface_V1_1 != nullptr) {
1826 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1827 enableFullTracking);
1828 } else {
1829 if (enableFullTracking == JNI_TRUE) {
1830 // full tracking mode not supported in 1.0 HAL
1831 return JNI_FALSE;
1832 }
1833 result = gnssMeasurementIface->setCallback(cbIface);
1834 }
1835
1836 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001837 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1838 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001839 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001840 } else {
1841 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001842 }
1843
1844 return JNI_TRUE;
1845}
1846
Yu-Han Yang8de21502018-04-23 01:40:25 -07001847static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001848 JNIEnv* env,
1849 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001850 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001851 ALOGE("Measurement interface not available");
1852 return JNI_FALSE;
1853 }
1854
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001855 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001856 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001857}
1858
Yu-Han Yang23d92162018-04-19 06:03:00 -07001859static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001860 JNIEnv* env,
1861 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001862 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001863 return JNI_TRUE;
1864 }
1865 return JNI_FALSE;
1866}
1867
Yu-Han Yang23d92162018-04-19 06:03:00 -07001868static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001869 JNIEnv* env,
1870 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001871 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001872 ALOGE("Navigation Message interface is not available.");
1873 return JNI_FALSE;
1874 }
1875
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001876 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1877 new GnssNavigationMessageCallback();
1878 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1879 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1880
1881 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1882 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001883 return JNI_FALSE;
1884 }
1885
1886 return JNI_TRUE;
1887}
1888
Yu-Han Yang23d92162018-04-19 06:03:00 -07001889static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001890 JNIEnv* env,
1891 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001892 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001893 ALOGE("Navigation Message interface is not available.");
1894 return JNI_FALSE;
1895 }
1896
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001897 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001898 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001899}
1900
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001901static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1902 jobject,
1903 jint emergencySuplPdn) {
1904 if (gnssConfigurationIface == nullptr) {
1905 ALOGE("no GNSS configuration interface available");
1906 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001907 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001908
1909 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001910 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001911 return result;
1912 } else {
1913 return JNI_FALSE;
1914 }
1915}
1916
1917static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1918 jobject,
1919 jint version) {
1920 if (gnssConfigurationIface == nullptr) {
1921 ALOGE("no GNSS configuration interface available");
1922 return JNI_FALSE;
1923 }
1924 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001925 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001926 return result;
1927 } else {
1928 return JNI_FALSE;
1929 }
1930}
1931
1932static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1933 jobject,
1934 jint suplEs) {
1935 if (gnssConfigurationIface == nullptr) {
1936 ALOGE("no GNSS configuration interface available");
1937 return JNI_FALSE;
1938 }
1939
1940 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001941 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001942 return result;
1943 } else {
1944 return JNI_FALSE;
1945 }
1946}
1947
1948static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1949 jobject,
1950 jint mode) {
1951 if (gnssConfigurationIface == nullptr) {
1952 ALOGE("no GNSS configuration interface available");
1953 return JNI_FALSE;
1954 }
1955
1956 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001957 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001958 return result;
1959 } else {
1960 return JNI_FALSE;
1961 }
1962}
1963
1964static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1965 jobject,
1966 jint gpsLock) {
1967 if (gnssConfigurationIface == nullptr) {
1968 ALOGE("no GNSS configuration interface available");
1969 return JNI_FALSE;
1970 }
1971
1972 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001973 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001974 return result;
1975 } else {
1976 return JNI_FALSE;
1977 }
1978}
1979
1980static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1981 jobject,
1982 jint lppProfile) {
1983 if (gnssConfigurationIface == nullptr) {
1984 ALOGE("no GNSS configuration interface available");
1985 return JNI_FALSE;
1986 }
1987
1988 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1989
Steven Morelandd002a8b2017-01-03 17:18:24 -08001990 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001991 return result;
1992 } else {
1993 return JNI_FALSE;
1994 }
1995}
1996
1997static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1998 jobject,
1999 jint gnssPosProtocol) {
2000 if (gnssConfigurationIface == nullptr) {
2001 ALOGE("no GNSS configuration interface available");
2002 return JNI_FALSE;
2003 }
2004
2005 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002006 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002007 return result;
2008 } else {
2009 return JNI_FALSE;
2010 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002011}
2012
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002013static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
2014 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2015 if (gnssConfigurationIface_V1_1 == nullptr) {
2016 ALOGI("No GNSS Satellite Blacklist interface available");
2017 return JNI_FALSE;
2018 }
2019
2020 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
2021 if (NULL == constellation_array) {
2022 ALOGI("GetIntArrayElements returns NULL.");
2023 return JNI_FALSE;
2024 }
2025 jsize length = env->GetArrayLength(constellations);
2026
2027 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
2028 if (NULL == sv_id_array) {
2029 ALOGI("GetIntArrayElements returns NULL.");
2030 return JNI_FALSE;
2031 }
2032
2033 if (length != env->GetArrayLength(sv_ids)) {
2034 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2035 return JNI_FALSE;
2036 }
2037
2038 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2039 sources.resize(length);
2040
2041 for (int i = 0; i < length; i++) {
2042 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2043 sources[i].svid = sv_id_array[i];
2044 }
2045
2046 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2047 if (result.isOk()) {
2048 return result;
2049 } else {
2050 return JNI_FALSE;
2051 }
2052}
2053
2054
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002055static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002056 if (gnssBatchingIface == nullptr) {
2057 return 0; // batching not supported, size = 0
2058 }
2059 auto result = gnssBatchingIface->getBatchSize();
2060 if (result.isOk()) {
2061 return static_cast<jint>(result);
2062 } else {
2063 return 0; // failure in binder, don't support batching
2064 }
2065}
2066
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002067static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002068 if (gnssBatchingIface == nullptr) {
2069 return JNI_FALSE; // batching not supported
2070 }
2071 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2072
2073 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2074}
2075
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002076static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002077 if (gnssBatchingIface == nullptr) {
2078 return; // batching not supported
2079 }
2080 gnssBatchingIface->cleanup();
2081}
2082
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002083static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002084 jlong periodNanos, jboolean wakeOnFifoFull) {
2085 if (gnssBatchingIface == nullptr) {
2086 return JNI_FALSE; // batching not supported
2087 }
2088
2089 IGnssBatching::Options options;
2090 options.periodNanos = periodNanos;
2091 if (wakeOnFifoFull) {
2092 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2093 } else {
2094 options.flags = 0;
2095 }
2096
2097 return static_cast<jboolean>(gnssBatchingIface->start(options));
2098}
2099
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002100static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002101 if (gnssBatchingIface == nullptr) {
2102 return; // batching not supported
2103 }
2104
2105 gnssBatchingIface->flush();
2106}
2107
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002108static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002109 if (gnssBatchingIface == nullptr) {
2110 return JNI_FALSE; // batching not supported
2111 }
2112
2113 return gnssBatchingIface->stop();
2114}
2115
Daniel Micay76f6a862015-09-19 17:31:01 -04002116static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002118 {"class_init_native", "()V", reinterpret_cast<void *>(
2119 android_location_GnssLocationProvider_class_init_native)},
2120 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2121 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002122 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002123 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002124 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002125 reinterpret_cast<void *>(
2126 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002127 {"native_init_once", "()V", reinterpret_cast<void *>(
2128 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002129 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2130 {"native_cleanup", "()V", reinterpret_cast<void *>(
2131 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002132 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002133 "(IIIIIZ)Z",
2134 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002135 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2136 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002137 {"native_delete_aiding_data",
2138 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002139 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002140 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2141 android_location_GnssLocationProvider_read_nmea)},
2142 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2143 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002144 {"native_inject_best_location",
2145 "(IDDDFFFFFFJ)V",
2146 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002147 {"native_inject_location",
2148 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002149 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2150 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2151 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002152 {"native_inject_xtra_data",
2153 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002154 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002155 {"native_agps_data_conn_open",
2156 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002157 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002158 {"native_agps_data_conn_closed",
2159 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002160 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002161 {"native_agps_data_conn_failed",
2162 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002163 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002164 {"native_agps_set_id",
2165 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002166 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002167 {"native_agps_set_ref_location_cellid",
2168 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002169 reinterpret_cast<void *>(
2170 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002171 {"native_set_agps_server",
2172 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002173 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002174 {"native_send_ni_response",
2175 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002176 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002177 {"native_get_internal_state",
2178 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002179 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002180 {"native_update_network_state",
2181 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002182 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002183 {"native_set_supl_es",
2184 "(I)Z",
2185 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2186 {"native_set_supl_version",
2187 "(I)Z",
2188 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2189 {"native_set_supl_mode",
2190 "(I)Z",
2191 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2192 {"native_set_lpp_profile",
2193 "(I)Z",
2194 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2195 {"native_set_gnss_pos_protocol_select",
2196 "(I)Z",
2197 reinterpret_cast<void *>(
2198 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2199 {"native_set_gps_lock",
2200 "(I)Z",
2201 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2202 {"native_set_emergency_supl_pdn",
2203 "(I)Z",
2204 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002205 {"native_set_satellite_blacklist",
2206 "([I[I)Z",
2207 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002208};
2209
2210static const JNINativeMethod sMethodsBatching[] = {
2211 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002212 {"native_get_batch_size",
2213 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002214 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002215 {"native_start_batch",
2216 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002217 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002218 {"native_flush_batch",
2219 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002220 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002221 {"native_stop_batch",
2222 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002223 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002224 {"native_init_batching",
2225 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002226 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002227 {"native_cleanup_batching",
2228 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002229 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230};
2231
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002232static const JNINativeMethod sGeofenceMethods[] = {
2233 /* name, signature, funcPtr */
2234 {"native_is_geofence_supported",
2235 "()Z",
2236 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2237 {"native_add_geofence",
2238 "(IDDDIIII)Z",
2239 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2240 {"native_remove_geofence",
2241 "(I)Z",
2242 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2243 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2244 android_location_GnssGeofenceProvider_pause_geofence)},
2245 {"native_resume_geofence",
2246 "(II)Z",
2247 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2248};
2249
Yu-Han Yang8de21502018-04-23 01:40:25 -07002250static const JNINativeMethod sMeasurementMethods[] = {
2251 /* name, signature, funcPtr */
2252 {"native_is_measurement_supported",
2253 "()Z",
2254 reinterpret_cast<void *>(
2255 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2256 {"native_start_measurement_collection",
2257 "(Z)Z",
2258 reinterpret_cast<void *>(
2259 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2260 {"native_stop_measurement_collection",
2261 "()Z",
2262 reinterpret_cast<void *>(
2263 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2264};
2265
Yu-Han Yang23d92162018-04-19 06:03:00 -07002266static const JNINativeMethod sNavigationMessageMethods[] = {
2267 /* name, signature, funcPtr */
2268 {"native_is_navigation_message_supported",
2269 "()Z",
2270 reinterpret_cast<void *>(
2271 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2272 {"native_start_navigation_message_collection",
2273 "()Z",
2274 reinterpret_cast<void *>(
2275 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2276 {"native_stop_navigation_message_collection",
2277 "()Z",
2278 reinterpret_cast<void *>(
2279 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2280};
2281
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002282int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002283 jniRegisterNativeMethods(
2284 env,
2285 "com/android/server/location/GnssBatchingProvider",
2286 sMethodsBatching,
2287 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002288 jniRegisterNativeMethods(
2289 env,
2290 "com/android/server/location/GnssGeofenceProvider",
2291 sGeofenceMethods,
2292 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002293 jniRegisterNativeMethods(
2294 env,
2295 "com/android/server/location/GnssMeasurementsProvider",
2296 sMeasurementMethods,
2297 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002298 jniRegisterNativeMethods(
2299 env,
2300 "com/android/server/location/GnssNavigationMessageProvider",
2301 sNavigationMessageMethods,
2302 NELEM(sNavigationMessageMethods));
destradaaea8a8a62014-06-23 18:19:03 -07002303 return jniRegisterNativeMethods(
2304 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002305 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002306 sMethods,
2307 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308}
2309
2310} /* namespace android */