blob: 3e87ea9322b18158bee97791b3e69c883ade6606 [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>
Wyatt Rileyb6a50f02018-05-03 13:59:04 -070041#include <iomanip>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
Mike Lockwoodf602d362010-06-20 14:28:16 -070043static jobject mCallbacksObj = NULL;
44
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045static jmethodID method_reportLocation;
46static jmethodID method_reportStatus;
47static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040048static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040049static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040050static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080051static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080052static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040054static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080055static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020056static jmethodID method_requestRefLocation;
57static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040058static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070059static jmethodID method_reportGeofenceTransition;
60static jmethodID method_reportGeofenceStatus;
61static jmethodID method_reportGeofenceAddStatus;
62static jmethodID method_reportGeofenceRemoveStatus;
63static jmethodID method_reportGeofencePauseStatus;
64static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070065static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070066static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080067static jmethodID method_reportLocationBatch;
Yu-Han Yang52057622018-04-25 00:51:22 -070068static jmethodID method_reportGnssServiceDied;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080070/*
71 * Save a pointer to JavaVm to attach/detach threads executing
72 * callback methods that need to make JNI calls.
73 */
74static JavaVM* sJvm;
75
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070076using android::OK;
77using android::sp;
gomo25208882017-04-15 02:05:25 -070078using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070079using android::status_t;
80using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070082using android::hardware::Return;
83using android::hardware::Void;
84using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070085using android::hardware::hidl_death_recipient;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070086using android::hardware::gnss::V1_0::GnssConstellationType;
Wyatt Rileyfb840922017-11-08 15:07:58 -080087using android::hardware::gnss::V1_0::GnssLocation;
88using android::hardware::gnss::V1_0::GnssLocationFlags;
Wyatt Riley46ac9562018-03-02 20:16:58 -080089
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070090using android::hardware::gnss::V1_0::IAGnss;
91using android::hardware::gnss::V1_0::IAGnssCallback;
92using android::hardware::gnss::V1_0::IAGnssCallback;
93using android::hardware::gnss::V1_0::IAGnssRil;
94using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080095using android::hardware::gnss::V1_0::IGnssBatching;
96using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070097using android::hardware::gnss::V1_0::IGnssDebug;
98using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
99using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700100using android::hardware::gnss::V1_0::IGnssNavigationMessage;
101using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
102using android::hardware::gnss::V1_0::IGnssNi;
103using android::hardware::gnss::V1_0::IGnssNiCallback;
104using android::hardware::gnss::V1_0::IGnssXtra;
105using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800106
Wyatt Rileyfb840922017-11-08 15:07:58 -0800107using android::hardware::gnss::V1_1::IGnssCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800108
109using android::hidl::base::V1_0::IBase;
110
111using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
112using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700113using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
114using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800115using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
116using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
117using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
118using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
119
Wyatt Rileyfb840922017-11-08 15:07:58 -0800120
gomo25208882017-04-15 02:05:25 -0700121struct GnssDeathRecipient : virtual public hidl_death_recipient
122{
123 // hidl_death_recipient interface
124 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700125 ALOGE("IGNSS hidl service failed, trying to recover...");
126
127 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
128 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700129 }
130};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700131
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800132// Must match the value from GnssMeasurement.java
133static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
134
gomo25208882017-04-15 02:05:25 -0700135sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800136sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800137sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700138sp<IGnssXtra> gnssXtraIface = nullptr;
139sp<IAGnssRil> agnssRilIface = nullptr;
140sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
141sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800142sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700143sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700144sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
145sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700146sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800147sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
148sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700149sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400151#define WAKE_LOCK_NAME "GPS"
152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153namespace android {
154
Lifu Tang120480f2016-02-07 18:08:19 -0800155template<class T>
156class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700157 public:
158 // Helper function to call setter on a Java object.
159 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800160 JNIEnv* env,
161 jclass clazz,
162 jobject object,
163 const char* method_name,
164 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700165
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700166 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800167 static const char *const signature_;
168};
Lifu Tange5a0e212016-01-25 18:02:17 -0800169
Lifu Tang120480f2016-02-07 18:08:19 -0800170template<class T>
171void JavaMethodHelper<T>::callJavaMethod(
172 JNIEnv* env,
173 jclass clazz,
174 jobject object,
175 const char* method_name,
176 T value) {
177 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
178 env->CallVoidMethod(object, method, value);
179}
destradaaea8a8a62014-06-23 18:19:03 -0700180
Lifu Tang120480f2016-02-07 18:08:19 -0800181class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700182 public:
183 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800184 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700185 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800186
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700187 template<class T>
188 void callSetter(const char* method_name, T value);
189 template<class T>
190 void callSetter(const char* method_name, T* value, size_t size);
191 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800192
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700193 private:
194 JNIEnv* env_;
195 jclass clazz_;
196 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800197};
198
199JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
200 clazz_ = env_->FindClass(class_name);
201 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
202 object_ = env_->NewObject(clazz_, ctor);
203}
204
Wyatt Rileycf879db2017-01-12 13:57:38 -0800205JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
206 clazz_ = env_->FindClass(class_name);
207 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
208 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
209}
210
Lifu Tang120480f2016-02-07 18:08:19 -0800211JavaObject::~JavaObject() {
212 env_->DeleteLocalRef(clazz_);
213}
214
215template<class T>
216void JavaObject::callSetter(const char* method_name, T value) {
217 JavaMethodHelper<T>::callJavaMethod(
218 env_, clazz_, object_, method_name, value);
219}
220
221template<>
222void JavaObject::callSetter(
223 const char* method_name, uint8_t* value, size_t size) {
224 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700225 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800226 jmethodID method = env_->GetMethodID(
227 clazz_,
228 method_name,
229 "([B)V");
230 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700231 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800232}
233
234jobject JavaObject::get() {
235 return object_;
236}
237
238// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800239template<>
240const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
241template<>
242const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
243template<>
244const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
245template<>
246const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
247template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800248const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
249template<>
250const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800251template<>
252const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
253template<>
254const char *const JavaMethodHelper<float>::signature_ = "(F)V";
255template<>
256const char *const JavaMethodHelper<double>::signature_ = "(D)V";
257template<>
258const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
259
260#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800261
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700262static inline jboolean boolToJbool(bool value) {
263 return value ? JNI_TRUE : JNI_FALSE;
264}
Lifu Tang120480f2016-02-07 18:08:19 -0800265
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700266static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
267 if (env->ExceptionCheck()) {
268 ALOGE("An exception was thrown by callback '%s'.", methodName);
269 LOGE_EX(env);
270 env->ExceptionClear();
271 }
272}
destradaaea8a8a62014-06-23 18:19:03 -0700273
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800274class ScopedJniThreadAttach {
275public:
276 ScopedJniThreadAttach() {
277 /*
278 * attachResult will also be JNI_OK if the thead was already attached to
279 * JNI before the call to AttachCurrentThread().
280 */
281 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
282 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
283 attachResult);
284 }
285
286 ~ScopedJniThreadAttach() {
287 jint detachResult = sJvm->DetachCurrentThread();
288 /*
289 * Return if the thread was already detached. Log error for any other
290 * failure.
291 */
292 if (detachResult == JNI_EDETACHED) {
293 return;
294 }
295
296 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
297 detachResult);
298 }
299
300 JNIEnv* getEnv() {
301 /*
302 * Checking validity of mEnv in case the thread was detached elsewhere.
303 */
304 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
305 return mEnv;
306 }
307
308private:
309 JNIEnv* mEnv = nullptr;
310};
311
312thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
313
314static JNIEnv* getJniEnv() {
315 JNIEnv* env = AndroidRuntime::getJNIEnv();
316
317 /*
318 * If env is nullptr, the thread is not already attached to
319 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
320 * will detach it on thread exit.
321 */
322 if (env == nullptr) {
323 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
324 env = tJniThreadAttacher->getEnv();
325 }
326
327 return env;
328}
329
Wyatt Rileyfb840922017-11-08 15:07:58 -0800330static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800331 JavaObject object(env, "android/location/Location", "gps");
332
333 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800334 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800335 SET(Latitude, location.latitudeDegrees);
336 SET(Longitude, location.longitudeDegrees);
337 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800338 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800339 SET(Altitude, location.altitudeMeters);
340 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800341 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800342 SET(Speed, location.speedMetersPerSec);
343 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800344 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800345 SET(Bearing, location.bearingDegrees);
346 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800347 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800348 SET(Accuracy, location.horizontalAccuracyMeters);
349 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800350 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800351 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
352 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800353 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800354 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
355 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800356 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800357 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
358 }
359 SET(Time, location.timestamp);
360
361 return object.get();
362}
363
Yu-Han Yange7baef32018-02-09 13:58:17 -0800364static GnssLocation createGnssLocation(
365 jint gnssLocationFlags,
366 jdouble latitudeDegrees,
367 jdouble longitudeDegrees,
368 jdouble altitudeMeters,
369 jfloat speedMetersPerSec,
370 jfloat bearingDegrees,
371 jfloat horizontalAccuracyMeters,
372 jfloat verticalAccuracyMeters,
373 jfloat speedAccuracyMetersPerSecond,
374 jfloat bearingAccuracyDegrees,
375 jlong timestamp) {
376 GnssLocation location;
377 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
378 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
379 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
380 location.altitudeMeters = static_cast<double>(altitudeMeters);
381 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
382 location.bearingDegrees = static_cast<float>(bearingDegrees);
383 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
384 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
385 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
386 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
387 location.timestamp = static_cast<uint64_t>(timestamp);
388
389 return location;
390}
391
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700392/*
393 * GnssCallback class implements the callback methods for IGnss interface.
394 */
395struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800396 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700397 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
398 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
399 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
400 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
401 Return<void> gnssAcquireWakelockCb() override;
402 Return<void> gnssReleaseWakelockCb() override;
403 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800404 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700405 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800406
Wyatt Rileyfb840922017-11-08 15:07:58 -0800407 // New in 1.1
408 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
409
Wyatt Riley26465d22018-02-12 13:44:24 -0800410 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700411 static const char* sNmeaString;
412 static size_t sNmeaStringLength;
413};
414
Wyatt Rileyfb840922017-11-08 15:07:58 -0800415Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
416 ALOGD("%s: name=%s\n", __func__, name.c_str());
417
Wyatt Rileyfb840922017-11-08 15:07:58 -0800418 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800419 jstring jstringName = env->NewStringUTF(name.c_str());
420 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800421 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800422
Wyatt Rileyfb840922017-11-08 15:07:58 -0800423 return Void();
424}
425
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700426const char* GnssCallback::sNmeaString = nullptr;
427size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700428
Wyatt Rileyfb840922017-11-08 15:07:58 -0800429Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800430 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800431
432 jobject jLocation = translateLocation(env, location);
433 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800434 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800435
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700436 env->CallVoidMethod(mCallbacksObj,
437 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800438 boolToJbool(hasLatLong),
439 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700440 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800441 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700442 return Void();
443}
444
445Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800446 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700447 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
448 checkAndClearExceptionFromCallback(env, __FUNCTION__);
449 return Void();
450}
451
452Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800453 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700454
Wyatt Riley26465d22018-02-12 13:44:24 -0800455 uint32_t listSize = svStatus.numSvs;
456 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700457 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800458 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700459 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800460 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800461 }
462
Wyatt Riley26465d22018-02-12 13:44:24 -0800463 jintArray svidWithFlagArray = env->NewIntArray(listSize);
464 jfloatArray cn0Array = env->NewFloatArray(listSize);
465 jfloatArray elevArray = env->NewFloatArray(listSize);
466 jfloatArray azimArray = env->NewFloatArray(listSize);
467 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
468
469 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
470 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
471 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
472 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
473 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
474
475 /*
476 * Read GNSS SV info.
477 */
478 for (size_t i = 0; i < listSize; ++i) {
479 enum ShiftWidth: uint8_t {
480 SVID_SHIFT_WIDTH = 8,
481 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
482 };
483
484 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
485 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
486 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
487 static_cast<uint32_t>(info.svFlag);
488 cn0s[i] = info.cN0Dbhz;
489 elev[i] = info.elevationDegrees;
490 azim[i] = info.azimuthDegrees;
491 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800492 }
destradaaea8a8a62014-06-23 18:19:03 -0700493
Wyatt Riley26465d22018-02-12 13:44:24 -0800494 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
495 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
496 env->ReleaseFloatArrayElements(elevArray, elev, 0);
497 env->ReleaseFloatArrayElements(azimArray, azim, 0);
498 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
499
500 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
501 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
502 carrierFreqArray);
503
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700504 checkAndClearExceptionFromCallback(env, __FUNCTION__);
505 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700506}
507
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700508Return<void> GnssCallback::gnssNmeaCb(
509 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800510 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700511 /*
512 * The Java code will call back to read these values.
513 * We do this to avoid creating unnecessary String objects.
514 */
515 sNmeaString = nmea.c_str();
516 sNmeaStringLength = nmea.size();
517
518 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
519 checkAndClearExceptionFromCallback(env, __FUNCTION__);
520 return Void();
521}
522
523Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
524 ALOGD("%s: %du\n", __func__, capabilities);
525
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800526 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700527 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
528 checkAndClearExceptionFromCallback(env, __FUNCTION__);
529 return Void();
530}
531
532Return<void> GnssCallback::gnssAcquireWakelockCb() {
533 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
534 return Void();
535}
536
537Return<void> GnssCallback::gnssReleaseWakelockCb() {
538 release_wake_lock(WAKE_LOCK_NAME);
539 return Void();
540}
541
542Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800543 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700544 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
545 checkAndClearExceptionFromCallback(env, __FUNCTION__);
546 return Void();
547}
548
Yu-Han Yang21988932018-01-23 15:07:37 -0800549Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800550 JNIEnv* env = getJniEnv();
551 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
552 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800553 return Void();
554}
555
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700556Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
557 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
558
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800559 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700560 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
561 info.yearOfHw);
562 checkAndClearExceptionFromCallback(env, __FUNCTION__);
563 return Void();
564}
565
566class GnssXtraCallback : public IGnssXtraCallback {
567 Return<void> downloadRequestCb() override;
568};
569
570/*
571 * GnssXtraCallback class implements the callback methods for the IGnssXtra
572 * interface.
573 */
574Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800575 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700576 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
577 checkAndClearExceptionFromCallback(env, __FUNCTION__);
578 return Void();
579}
580
581/*
582 * GnssGeofenceCallback class implements the callback methods for the
583 * IGnssGeofence interface.
584 */
585struct GnssGeofenceCallback : public IGnssGeofenceCallback {
586 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
587 Return<void> gnssGeofenceTransitionCb(
588 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800589 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700590 GeofenceTransition transition,
591 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
592 Return<void> gnssGeofenceStatusCb(
593 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800594 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700595 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
596 GeofenceStatus status) override;
597 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
598 GeofenceStatus status) override;
599 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
600 GeofenceStatus status) override;
601 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
602 GeofenceStatus status) override;
603};
604
605Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
606 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800607 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700608 GeofenceTransition transition,
609 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800610 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700611
Wyatt Riley5d229832017-02-10 17:06:00 -0800612 jobject jLocation = translateLocation(env, location);
613
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700614 env->CallVoidMethod(mCallbacksObj,
615 method_reportGeofenceTransition,
616 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800617 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700618 transition,
619 timestamp);
620
621 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800622 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700623 return Void();
624}
625
626Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
627 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800628 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800629 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800630
631 jobject jLocation = translateLocation(env, location);
632
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700633 env->CallVoidMethod(mCallbacksObj,
634 method_reportGeofenceStatus,
635 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800636 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700637 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800638 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700639 return Void();
640}
641
642Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
643 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800644 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700645 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
646 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
647 }
648
649 env->CallVoidMethod(mCallbacksObj,
650 method_reportGeofenceAddStatus,
651 geofenceId,
652 status);
653 checkAndClearExceptionFromCallback(env, __FUNCTION__);
654 return Void();
655}
656
657Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
658 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800659 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700660 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
661 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
662 }
663
664 env->CallVoidMethod(mCallbacksObj,
665 method_reportGeofenceRemoveStatus,
666 geofenceId, status);
667 checkAndClearExceptionFromCallback(env, __FUNCTION__);
668 return Void();
669}
670
671Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
672 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800673 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700674 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
675 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
676 }
677
678 env->CallVoidMethod(mCallbacksObj,
679 method_reportGeofencePauseStatus,
680 geofenceId, status);
681 checkAndClearExceptionFromCallback(env, __FUNCTION__);
682 return Void();
683}
684
685Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
686 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800687 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700688 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
689 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
690 }
691
692 env->CallVoidMethod(mCallbacksObj,
693 method_reportGeofenceResumeStatus,
694 geofenceId, status);
695 checkAndClearExceptionFromCallback(env, __FUNCTION__);
696 return Void();
697}
698
699/*
700 * GnssNavigationMessageCallback interface implements the callback methods
701 * required by the IGnssNavigationMessage interface.
702 */
703struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
704 /*
705 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
706 * follow.
707 */
708 Return<void> gnssNavigationMessageCb(
709 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
710};
711
712Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
713 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800714 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700715
716 size_t dataLength = message.data.size();
717
718 std::vector<uint8_t> navigationData = message.data;
719 uint8_t* data = &(navigationData[0]);
720 if (dataLength == 0 || data == NULL) {
721 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
722 dataLength);
723 return Void();
724 }
725
726 JavaObject object(env, "android/location/GnssNavigationMessage");
727 SET(Type, static_cast<int32_t>(message.type));
728 SET(Svid, static_cast<int32_t>(message.svid));
729 SET(MessageId, static_cast<int32_t>(message.messageId));
730 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
731 object.callSetter("setData", data, dataLength);
732 SET(Status, static_cast<int32_t>(message.status));
733
734 jobject navigationMessage = object.get();
735 env->CallVoidMethod(mCallbacksObj,
736 method_reportNavigationMessages,
737 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800738 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700739 env->DeleteLocalRef(navigationMessage);
740 return Void();
741}
742
743/*
744 * GnssMeasurementCallback implements the callback methods required for the
745 * GnssMeasurement interface.
746 */
Wyatt Riley46ac9562018-03-02 20:16:58 -0800747struct GnssMeasurementCallback : public IGnssMeasurementCallback_V1_1 {
748 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800749 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700750 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800751 void translateGnssMeasurement_V1_0(
752 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800753 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700754 jobjectArray translateGnssMeasurements(
755 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800756 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800757 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700758 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800759 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800760 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700761 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
762};
763
764
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800765Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800766 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800767 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700768
769 jobject clock;
770 jobjectArray measurementArray;
771
772 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800773
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700774 measurementArray = translateGnssMeasurements(
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800775 env, data.measurements.data(), NULL, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700776 setMeasurementData(env, clock, measurementArray);
777
778 env->DeleteLocalRef(clock);
779 env->DeleteLocalRef(measurementArray);
780 return Void();
781}
782
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800783Return<void> GnssMeasurementCallback::GnssMeasurementCb(
784 const IGnssMeasurementCallback_V1_0::GnssData& data) {
785 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800786
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800787 jobject clock;
788 jobjectArray measurementArray;
789
790 clock = translateGnssClock(env, &data.clock);
791 measurementArray = translateGnssMeasurements(
792 env, NULL, data.measurements.data(), data.measurementCount);
793 setMeasurementData(env, clock, measurementArray);
794
795 env->DeleteLocalRef(clock);
796 env->DeleteLocalRef(measurementArray);
797 return Void();
798}
799
800// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
801void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
802 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800803 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700804 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700805
806 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800807 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700808 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800809 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700810 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800811 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700812 measurement->receivedSvTimeUncertaintyInNs);
813 SET(Cn0DbHz, measurement->cN0DbHz);
814 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800815 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700816 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800817 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800818 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
WyattRiley948dd6d2018-10-31 06:56:09 -0700819 ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700820 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800821 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700822 measurement->accumulatedDeltaRangeUncertaintyM);
823
824 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
825 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
826 }
827
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800828 // Intentionally not copying deprecated fields of carrierCycles,
829 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700830
831 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
832
833 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
834 SET(SnrInDb, measurement->snrDb);
835 }
Lifu Tang120480f2016-02-07 18:08:19 -0800836
gomo4402af62017-01-11 13:20:13 -0800837 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800838 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800839 }
Lifu Tang120480f2016-02-07 18:08:19 -0800840}
841
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700842jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800843 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700844 JavaObject object(env, "android/location/GnssClock");
845
846 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
847 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
848 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
849 }
850
851 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
852 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
853 }
854
855 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
856 SET(FullBiasNanos, clock->fullBiasNs);
857 }
858
859 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
860 SET(BiasNanos, clock->biasNs);
861 }
862
863 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
864 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
865 }
866
867 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
868 SET(DriftNanosPerSecond, clock->driftNsps);
869 }
870
871 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
872 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
873 }
874
875 SET(TimeNanos, clock->timeNs);
876 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
877
878 return object.get();
879}
880
881jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800882 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800883 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
884 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800885 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700886 return NULL;
887 }
888
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700889 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800890 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800891 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800892 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700893 NULL /* initialElement */);
894
Lifu Tang120480f2016-02-07 18:08:19 -0800895 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800896 JavaObject object(env, "android/location/GnssMeasurement");
Wyatt Riley46ac9562018-03-02 20:16:58 -0800897 if (measurements_v1_1 != NULL) {
898 translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800899
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800900 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800901 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800902 (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
903 ADR_STATE_HALF_CYCLE_REPORTED));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800904 } else {
905 translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
906 }
907
908 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700909 }
910
Lifu Tang818aa2c2016-02-01 01:52:00 -0800911 env->DeleteLocalRef(gnssMeasurementClass);
912 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700913}
914
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700915void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
916 jobjectArray measurementArray) {
917 jclass gnssMeasurementsEventClass =
918 env->FindClass("android/location/GnssMeasurementsEvent");
919 jmethodID gnssMeasurementsEventCtor =
920 env->GetMethodID(
921 gnssMeasurementsEventClass,
922 "<init>",
923 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800924
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700925 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
926 gnssMeasurementsEventCtor,
927 clock,
928 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800929
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700930 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
931 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800932 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800933 env->DeleteLocalRef(gnssMeasurementsEventClass);
934 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700935}
936
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700937/*
938 * GnssNiCallback implements callback methods required by the IGnssNi interface.
939 */
940struct GnssNiCallback : public IGnssNiCallback {
941 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
942 override;
destradaaea8a8a62014-06-23 18:19:03 -0700943};
944
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700945Return<void> GnssNiCallback::niNotifyCb(
946 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800947 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700948 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
949 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
950
951 if (requestorId && text) {
952 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
953 notification.notificationId, notification.niType,
954 notification.notifyFlags, notification.timeoutSec,
955 notification.defaultResponse, requestorId, text,
956 notification.requestorIdEncoding,
957 notification.notificationIdEncoding);
958 } else {
959 ALOGE("%s: OOM Error\n", __func__);
960 }
961
962 if (requestorId) {
963 env->DeleteLocalRef(requestorId);
964 }
965
966 if (text) {
967 env->DeleteLocalRef(text);
968 }
969 checkAndClearExceptionFromCallback(env, __FUNCTION__);
970 return Void();
971}
972
973/*
974 * AGnssCallback implements callback methods required by the IAGnss interface.
975 */
976struct AGnssCallback : public IAGnssCallback {
977 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
978 Return<void> agnssStatusIpV6Cb(
979 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
980
981 Return<void> agnssStatusIpV4Cb(
982 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
983 private:
984 jbyteArray convertToIpV4(uint32_t ip);
985};
986
987Return<void> AGnssCallback::agnssStatusIpV6Cb(
988 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800989 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700990 jbyteArray byteArray = NULL;
991 bool isSupported = false;
992
993 byteArray = env->NewByteArray(16);
994 if (byteArray != NULL) {
995 env->SetByteArrayRegion(byteArray, 0, 16,
996 (const jbyte*)(agps_status.ipV6Addr.data()));
997 isSupported = true;
998 } else {
999 ALOGE("Unable to allocate byte array for IPv6 address.");
1000 }
1001
1002 IF_ALOGD() {
1003 // log the IP for reference in case there is a bogus value pushed by HAL
1004 char str[INET6_ADDRSTRLEN];
1005 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1006 ALOGD("AGPS IP is v6: %s", str);
1007 }
1008
1009 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1010 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1011 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1012 agps_status.type, agps_status.status, byteArray);
1013
1014 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1015
1016 if (byteArray) {
1017 env->DeleteLocalRef(byteArray);
1018 }
1019
1020 return Void();
1021}
1022
1023Return<void> AGnssCallback::agnssStatusIpV4Cb(
1024 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001025 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001026 jbyteArray byteArray = NULL;
1027
1028 uint32_t ipAddr = agps_status.ipV4Addr;
1029 byteArray = convertToIpV4(ipAddr);
1030
1031 IF_ALOGD() {
1032 /*
1033 * log the IP for reference in case there is a bogus value pushed by
1034 * HAL.
1035 */
1036 char str[INET_ADDRSTRLEN];
1037 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1038 ALOGD("AGPS IP is v4: %s", str);
1039 }
1040
1041 jsize byteArrayLength =
1042 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1043 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1044 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1045 agps_status.type, agps_status.status, byteArray);
1046
1047 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1048
1049 if (byteArray) {
1050 env->DeleteLocalRef(byteArray);
1051 }
1052 return Void();
1053}
1054
1055jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1056 if (INADDR_NONE == ip) {
1057 return NULL;
1058 }
1059
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001060 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001061 jbyteArray byteArray = env->NewByteArray(4);
1062 if (byteArray == NULL) {
1063 ALOGE("Unable to allocate byte array for IPv4 address");
1064 return NULL;
1065 }
1066
1067 jbyte ipv4[4];
1068 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1069 memcpy(ipv4, &ip, sizeof(ipv4));
1070 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1071 return byteArray;
1072}
1073
1074/*
1075 * AGnssRilCallback implements the callback methods required by the AGnssRil
1076 * interface.
1077 */
1078struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001079 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001080 Return<void> requestRefLocCb() override;
1081};
1082
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001083Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001084 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001085 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1086 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1087 return Void();
1088}
1089
1090Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001091 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001092 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1093 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1094 return Void();
1095}
1096
Wyatt Rileycf879db2017-01-12 13:57:38 -08001097/*
1098 * GnssBatchingCallback interface implements the callback methods
1099 * required by the IGnssBatching interface.
1100 */
1101struct GnssBatchingCallback : public IGnssBatchingCallback {
1102 /*
1103 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1104 * follow.
1105 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001106 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001107 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001108};
1109
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001110Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001111 JNIEnv* env = getJniEnv();
1112
1113 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1114 env->FindClass("android/location/Location"), nullptr);
1115
1116 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001117 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001118 env->SetObjectArrayElement(jLocations, i, jLocation);
1119 env->DeleteLocalRef(jLocation);
1120 }
1121
1122 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1123 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1124
1125 env->DeleteLocalRef(jLocations);
1126
1127 return Void();
1128}
1129
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001130static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001131 gnssHal_V1_1 = IGnss_V1_1::getService();
1132 if (gnssHal_V1_1 == nullptr) {
1133 ALOGD("gnssHal 1.1 was null, trying 1.0");
1134 gnssHal = IGnss_V1_0::getService();
1135 } else {
1136 gnssHal = gnssHal_V1_1;
1137 }
1138}
1139
1140static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001141 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1142 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001143 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001144 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001145 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1146 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1147 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1148 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001149 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1150 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001151 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1152 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1153 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001154 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001155 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1156 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1157 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1158 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001159 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001160 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001161 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001162 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1163 "(II)V");
1164 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1165 "(II)V");
1166 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1167 "(II)V");
1168 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1169 "(II)V");
1170 method_reportMeasurementData = env->GetMethodID(
1171 clazz,
1172 "reportMeasurementData",
1173 "(Landroid/location/GnssMeasurementsEvent;)V");
1174 method_reportNavigationMessages = env->GetMethodID(
1175 clazz,
1176 "reportNavigationMessage",
1177 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001178 method_reportLocationBatch = env->GetMethodID(
1179 clazz,
1180 "reportLocationBatch",
1181 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001182 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001183
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001184 /*
1185 * Save a pointer to JVM.
1186 */
1187 jint jvmStatus = env->GetJavaVM(&sJvm);
1188 if (jvmStatus != JNI_OK) {
1189 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1190 }
1191
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001192 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001193 gnssHalDeathRecipient = new GnssDeathRecipient();
1194 hardware::Return<bool> linked = gnssHal->linkToDeath(
1195 gnssHalDeathRecipient, /*cookie*/ 0);
1196 if (!linked.isOk()) {
1197 ALOGE("Transaction error in linking to GnssHAL death: %s",
1198 linked.description().c_str());
1199 } else if (!linked) {
1200 ALOGW("Unable to link to GnssHal death notifications");
1201 } else {
1202 ALOGD("Link to death notification successful");
1203 }
1204
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001205 auto gnssXtra = gnssHal->getExtensionXtra();
1206 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001207 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001208 } else {
1209 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001210 }
1211
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001212 auto gnssRil = gnssHal->getExtensionAGnssRil();
1213 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001214 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001215 } else {
1216 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217 }
1218
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001219 auto gnssAgnss = gnssHal->getExtensionAGnss();
1220 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001221 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001222 } else {
1223 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001224 }
1225
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001226 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1227 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001228 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001229 } else {
1230 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001231 }
1232
gomo48f1a642017-11-10 20:35:46 -08001233 if (gnssHal_V1_1 != nullptr) {
1234 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1235 if (!gnssMeasurement.isOk()) {
1236 ALOGD("Unable to get a handle to GnssMeasurement");
1237 } else {
1238 gnssMeasurementIface_V1_1 = gnssMeasurement;
1239 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1240 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001241 } else {
gomo48f1a642017-11-10 20:35:46 -08001242 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1243 if (!gnssMeasurement_V1_0.isOk()) {
1244 ALOGD("Unable to get a handle to GnssMeasurement");
1245 } else {
1246 gnssMeasurementIface = gnssMeasurement_V1_0;
1247 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001248 }
1249
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001250 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1251 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001252 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001253 } else {
1254 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001255 }
1256
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001257 auto gnssNi = gnssHal->getExtensionGnssNi();
1258 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001259 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001260 } else {
1261 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001262 }
1263
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001264 if (gnssHal_V1_1 != nullptr) {
1265 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1266 if (!gnssConfiguration.isOk()) {
1267 ALOGD("Unable to get a handle to GnssConfiguration");
1268 } else {
1269 gnssConfigurationIface_V1_1 = gnssConfiguration;
1270 gnssConfigurationIface = gnssConfigurationIface_V1_1;
1271 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001272 } else {
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001273 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1274 if (!gnssConfiguration_V1_0.isOk()) {
1275 ALOGD("Unable to get a handle to GnssConfiguration");
1276 } else {
1277 gnssConfigurationIface = gnssConfiguration_V1_0;
1278 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001279 }
1280
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001281 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1282 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001283 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001284 } else {
1285 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001286 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001287
1288 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1289 if (!gnssBatching.isOk()) {
1290 ALOGD("Unable to get a handle to gnssBatching");
1291 } else {
1292 gnssBatchingIface = gnssBatching;
1293 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001294 } else {
1295 ALOGE("Unable to get GPS service\n");
1296 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001297}
1298
1299static jboolean android_location_GnssLocationProvider_is_supported(
1300 JNIEnv* /* env */, jclass /* clazz */) {
1301 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1302}
1303
1304static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1305 JNIEnv* /* env */, jclass /* clazz */) {
1306 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1307}
1308
1309static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1310 JNIEnv* /* env */, jclass /* jclazz */) {
1311 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1312}
1313
1314static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1315 /*
1316 * This must be set before calling into the HAL library.
1317 */
1318 if (!mCallbacksObj)
1319 mCallbacksObj = env->NewGlobalRef(obj);
1320
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001321 /*
1322 * Fail if the main interface fails to initialize
1323 */
1324 if (gnssHal == nullptr) {
1325 ALOGE("Unable to Initialize GNSS HAL\n");
1326 return JNI_FALSE;
1327 }
1328
Wyatt Rileyfb840922017-11-08 15:07:58 -08001329 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1330
1331 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001332 if (gnssHal_V1_1 != nullptr) {
1333 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001334 } else {
1335 result = gnssHal->setCallback(gnssCbIface);
1336 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001337 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001338 ALOGE("SetCallback for Gnss Interface fails\n");
1339 return JNI_FALSE;
1340 }
1341
1342 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1343 if (gnssXtraIface == nullptr) {
1344 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001345 } else {
1346 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001347 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001348 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001349 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001350 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001351 }
1352
1353 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1354 if (agnssIface != nullptr) {
1355 agnssIface->setCallback(aGnssCbIface);
1356 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001357 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001358 }
1359
1360 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1361 if (gnssGeofencingIface != nullptr) {
1362 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1363 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001364 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001365 }
1366
1367 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001368 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001369 gnssNiIface->setCallback(gnssNiCbIface);
1370 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001371 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001372 }
1373
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001374 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1375 if (agnssRilIface != nullptr) {
1376 agnssRilIface->setCallback(aGnssRilCbIface);
1377 } else {
1378 ALOGI("Unable to Initialize AGnss Ril interface\n");
1379 }
1380
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001381 return JNI_TRUE;
1382}
1383
1384static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1385 if (gnssHal != nullptr) {
1386 gnssHal->cleanup();
1387 }
1388}
1389
1390static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1391 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001392 jint preferred_time, jboolean low_power_mode) {
1393 Return<bool> result = false;
1394 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001395 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1396 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1397 min_interval,
1398 preferred_accuracy,
1399 preferred_time,
1400 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001401 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001402 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1403 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1404 min_interval,
1405 preferred_accuracy,
1406 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001407 }
1408 if (!result.isOk()) {
1409 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1410 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001411 } else {
gomo48f1a642017-11-10 20:35:46 -08001412 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001413 }
1414}
1415
1416static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1417 if (gnssHal != nullptr) {
1418 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001419 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001420 return JNI_FALSE;
1421 } else {
1422 return result;
1423 }
1424 } else {
1425 return JNI_FALSE;
1426 }
1427}
1428
1429static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1430 if (gnssHal != nullptr) {
1431 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001432 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001433 return JNI_FALSE;
1434 } else {
1435 return result;
1436 }
1437 } else {
1438 return JNI_FALSE;
1439 }
1440}
1441static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1442 jobject /* obj */,
1443 jint flags) {
1444 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001445 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001446 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001447 ALOGE("Error in deleting aiding data");
1448 }
1449 }
1450}
1451
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001452static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1453 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1454 IAGnssRil::AGnssRefLocation location;
1455
1456 if (agnssRilIface == nullptr) {
1457 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1458 return;
1459 }
1460
1461 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1462 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1463 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1464 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1465 location.cellID.mcc = mcc;
1466 location.cellID.mnc = mnc;
1467 location.cellID.lac = lac;
1468 location.cellID.cid = cid;
1469 break;
1470 default:
1471 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1472 return;
1473 break;
1474 }
1475
1476 agnssRilIface->setRefLocation(location);
1477}
1478
1479static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1480 jint type, jstring setid_string) {
1481 if (agnssRilIface == nullptr) {
1482 ALOGE("no AGPS RIL interface in agps_set_id");
1483 return;
1484 }
1485
1486 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1487 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1488 env->ReleaseStringUTFChars(setid_string, setid);
1489}
1490
1491static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1492 jbyteArray nmeaArray, jint buffer_size) {
1493 // this should only be called from within a call to reportNmea
1494 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1495 int length = GnssCallback::sNmeaStringLength;
1496 if (length > buffer_size)
1497 length = buffer_size;
1498 memcpy(nmea, GnssCallback::sNmeaString, length);
1499 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1500 return (jint) length;
1501}
1502
1503static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1504 jlong time, jlong timeReference, jint uncertainty) {
1505 if (gnssHal != nullptr) {
1506 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001507 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001508 ALOGE("%s: Gnss injectTime() failed", __func__);
1509 }
1510 }
1511}
1512
Yu-Han Yange7baef32018-02-09 13:58:17 -08001513static void android_location_GnssLocationProvider_inject_best_location(
1514 JNIEnv*,
1515 jobject,
1516 jint gnssLocationFlags,
1517 jdouble latitudeDegrees,
1518 jdouble longitudeDegrees,
1519 jdouble altitudeMeters,
1520 jfloat speedMetersPerSec,
1521 jfloat bearingDegrees,
1522 jfloat horizontalAccuracyMeters,
1523 jfloat verticalAccuracyMeters,
1524 jfloat speedAccuracyMetersPerSecond,
1525 jfloat bearingAccuracyDegrees,
1526 jlong timestamp) {
1527 if (gnssHal_V1_1 != nullptr) {
1528 GnssLocation location = createGnssLocation(
1529 gnssLocationFlags,
1530 latitudeDegrees,
1531 longitudeDegrees,
1532 altitudeMeters,
1533 speedMetersPerSec,
1534 bearingDegrees,
1535 horizontalAccuracyMeters,
1536 verticalAccuracyMeters,
1537 speedAccuracyMetersPerSecond,
1538 bearingAccuracyDegrees,
1539 timestamp);
1540 auto result = gnssHal_V1_1->injectBestLocation(location);
1541 if (!result.isOk() || !result) {
1542 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1543 }
1544 } else {
1545 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1546 }
1547}
1548
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001549static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1550 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1551 if (gnssHal != nullptr) {
1552 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001553 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001554 ALOGE("%s: Gnss injectLocation() failed", __func__);
1555 }
1556 }
1557}
1558
1559static jboolean android_location_GnssLocationProvider_supports_xtra(
1560 JNIEnv* /* env */, jobject /* obj */) {
1561 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1562}
1563
1564static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1565 jbyteArray data, jint length) {
1566 if (gnssXtraIface == nullptr) {
1567 ALOGE("XTRA Interface not supported");
1568 return;
1569 }
1570
1571 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1572 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1573 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1574}
1575
1576static void android_location_GnssLocationProvider_agps_data_conn_open(
1577 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1578 if (agnssIface == nullptr) {
1579 ALOGE("no AGPS interface in agps_data_conn_open");
1580 return;
1581 }
1582 if (apn == NULL) {
1583 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1584 return;
1585 }
1586
1587 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1588
1589 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001590 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001591 ALOGE("%s: Failed to set APN and its IP type", __func__);
1592 }
1593 env->ReleaseStringUTFChars(apn, apnStr);
1594}
1595
1596static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1597 jobject /* obj */) {
1598 if (agnssIface == nullptr) {
1599 ALOGE("%s: AGPS interface not supported", __func__);
1600 return;
1601 }
1602
1603 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001604 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001605 ALOGE("%s: Failed to close AGnss data connection", __func__);
1606 }
1607}
1608
1609static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1610 jobject /* obj */) {
1611 if (agnssIface == nullptr) {
1612 ALOGE("%s: AGPS interface not supported", __func__);
1613 return;
1614 }
1615
1616 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001617 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001618 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1619 }
1620}
1621
1622static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1623 jint type, jstring hostname, jint port) {
1624 if (agnssIface == nullptr) {
1625 ALOGE("no AGPS interface in set_agps_server");
1626 return;
1627 }
1628
1629 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1630 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1631 c_hostname,
1632 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001633 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001634 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1635 }
1636
1637 env->ReleaseStringUTFChars(hostname, c_hostname);
1638}
1639
1640static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1641 jobject /* obj */, jint notifId, jint response) {
1642 if (gnssNiIface == nullptr) {
1643 ALOGE("no NI interface in send_ni_response");
1644 return;
1645 }
1646
1647 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1648}
1649
1650static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1651 jobject /* obj */) {
1652 jstring result = NULL;
1653 /*
1654 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1655 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001656
1657 std::stringstream internalState;
1658
1659 if (gnssDebugIface == nullptr) {
1660 internalState << "Gnss Debug Interface not available" << std::endl;
1661 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001662 IGnssDebug::DebugData data;
1663 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1664 data = debugData;
1665 });
1666
Wyatt Riley268c6e02017-03-29 10:21:46 -07001667 internalState << "Gnss Location Data:: ";
1668 if (!data.position.valid) {
1669 internalState << "not valid";
1670 } else {
1671 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001672 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1673 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001674 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1675 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001676 << ", horizontalAccuracyMeters: "
1677 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001678 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001679 << ", speedAccuracyMetersPerSecond: "
1680 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001681 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001682 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001684 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001685
Wyatt Riley268c6e02017-03-29 10:21:46 -07001686 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1687 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1688 << ", frequencyUncertaintyNsPerSec: "
1689 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001690
1691 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001692 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1693 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 }
1695
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001696 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1697 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
1698 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
1699 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001700 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001701 internalState << "constell: "
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001702 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001703 << ", svid: " << std::setw(3) << data.satelliteDataArray[i].svid
1704 << ", serverPredAvail: "
Wyatt Riley268c6e02017-03-29 10:21:46 -07001705 << data.satelliteDataArray[i].serverPredictionIsAvailable
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001706 << ", serverPredAgeSec: " << std::setw(7)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001707 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001708 << ", ephType: "
1709 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1710 << ", ephSource: "
1711 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1712 << ", ephHealth: "
1713 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1714 << ", ephAgeSec: " << std::setw(7)
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001715 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1716 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001718
1719 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001720 return result;
1721}
1722
1723static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1724 jobject /* obj */,
1725 jboolean connected,
1726 jint type,
1727 jboolean roaming,
1728 jboolean available,
1729 jstring extraInfo,
1730 jstring apn) {
1731 if (agnssRilIface != nullptr) {
1732 auto result = agnssRilIface->updateNetworkState(connected,
1733 static_cast<IAGnssRil::NetworkType>(type),
1734 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001735 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001736 ALOGE("updateNetworkState failed");
1737 }
1738
1739 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1740 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001741 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001742 ALOGE("updateNetworkAvailability failed");
1743 }
1744
1745 env->ReleaseStringUTFChars(apn, c_apn);
1746 } else {
1747 ALOGE("AGnssRilInterface does not exist");
1748 }
1749}
1750
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001751static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001752 JNIEnv* /* env */, jobject /* obj */) {
1753 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1754}
1755
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001756static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001757 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1758 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1759 jint unknown_timer) {
1760 if (gnssGeofencingIface != nullptr) {
1761 auto result = gnssGeofencingIface->addGeofence(
1762 geofenceId, latitude, longitude, radius,
1763 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1764 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001765 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 } else {
1767 ALOGE("Geofence Interface not available");
1768 }
1769 return JNI_FALSE;
1770}
1771
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001772static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001773 jobject /* obj */, jint geofenceId) {
1774 if (gnssGeofencingIface != nullptr) {
1775 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001776 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001777 } else {
1778 ALOGE("Geofence interface not available");
1779 }
1780 return JNI_FALSE;
1781}
1782
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001783static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001784 jobject /* obj */, jint geofenceId) {
1785 if (gnssGeofencingIface != nullptr) {
1786 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001787 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001788 } else {
1789 ALOGE("Geofence interface not available");
1790 }
1791 return JNI_FALSE;
1792}
1793
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001794static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001795 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1796 if (gnssGeofencingIface != nullptr) {
1797 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001798 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001799 } else {
1800 ALOGE("Geofence interface not available");
1801 }
1802 return JNI_FALSE;
1803}
1804
Yu-Han Yang8de21502018-04-23 01:40:25 -07001805static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001806 JNIEnv* env, jclass clazz) {
1807 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001808 return JNI_TRUE;
1809 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001810
destradaaea8a8a62014-06-23 18:19:03 -07001811 return JNI_FALSE;
1812}
1813
Yu-Han Yang8de21502018-04-23 01:40:25 -07001814static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001815 JNIEnv* /* env */,
1816 jobject /* obj */,
1817 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001818 if (gnssMeasurementIface == nullptr) {
1819 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001820 return JNI_FALSE;
1821 }
1822
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001823 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001824 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1825 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1826 if (gnssMeasurementIface_V1_1 != nullptr) {
1827 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1828 enableFullTracking);
1829 } else {
1830 if (enableFullTracking == JNI_TRUE) {
1831 // full tracking mode not supported in 1.0 HAL
1832 return JNI_FALSE;
1833 }
1834 result = gnssMeasurementIface->setCallback(cbIface);
1835 }
1836
1837 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001838 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1839 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001840 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001841 } else {
1842 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001843 }
1844
1845 return JNI_TRUE;
1846}
1847
Yu-Han Yang8de21502018-04-23 01:40:25 -07001848static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001849 JNIEnv* env,
1850 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001851 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001852 ALOGE("Measurement interface not available");
1853 return JNI_FALSE;
1854 }
1855
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001856 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001857 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001858}
1859
Yu-Han Yang23d92162018-04-19 06:03:00 -07001860static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001861 JNIEnv* env,
1862 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001863 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001864 return JNI_TRUE;
1865 }
1866 return JNI_FALSE;
1867}
1868
Yu-Han Yang23d92162018-04-19 06:03:00 -07001869static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001870 JNIEnv* env,
1871 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001872 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001873 ALOGE("Navigation Message interface is not available.");
1874 return JNI_FALSE;
1875 }
1876
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001877 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1878 new GnssNavigationMessageCallback();
1879 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1880 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1881
1882 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1883 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001884 return JNI_FALSE;
1885 }
1886
1887 return JNI_TRUE;
1888}
1889
Yu-Han Yang23d92162018-04-19 06:03:00 -07001890static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001891 JNIEnv* env,
1892 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001893 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001894 ALOGE("Navigation Message interface is not available.");
1895 return JNI_FALSE;
1896 }
1897
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001898 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001899 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001900}
1901
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001902static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1903 jobject,
1904 jint emergencySuplPdn) {
1905 if (gnssConfigurationIface == nullptr) {
1906 ALOGE("no GNSS configuration interface available");
1907 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001908 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001909
1910 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001911 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001912 return result;
1913 } else {
1914 return JNI_FALSE;
1915 }
1916}
1917
1918static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1919 jobject,
1920 jint version) {
1921 if (gnssConfigurationIface == nullptr) {
1922 ALOGE("no GNSS configuration interface available");
1923 return JNI_FALSE;
1924 }
1925 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001926 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001927 return result;
1928 } else {
1929 return JNI_FALSE;
1930 }
1931}
1932
1933static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1934 jobject,
1935 jint suplEs) {
1936 if (gnssConfigurationIface == nullptr) {
1937 ALOGE("no GNSS configuration interface available");
1938 return JNI_FALSE;
1939 }
1940
1941 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001942 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001943 return result;
1944 } else {
1945 return JNI_FALSE;
1946 }
1947}
1948
1949static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1950 jobject,
1951 jint mode) {
1952 if (gnssConfigurationIface == nullptr) {
1953 ALOGE("no GNSS configuration interface available");
1954 return JNI_FALSE;
1955 }
1956
1957 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001958 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001959 return result;
1960 } else {
1961 return JNI_FALSE;
1962 }
1963}
1964
1965static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1966 jobject,
1967 jint gpsLock) {
1968 if (gnssConfigurationIface == nullptr) {
1969 ALOGE("no GNSS configuration interface available");
1970 return JNI_FALSE;
1971 }
1972
1973 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001974 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001975 return result;
1976 } else {
1977 return JNI_FALSE;
1978 }
1979}
1980
1981static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1982 jobject,
1983 jint lppProfile) {
1984 if (gnssConfigurationIface == nullptr) {
1985 ALOGE("no GNSS configuration interface available");
1986 return JNI_FALSE;
1987 }
1988
1989 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1990
Steven Morelandd002a8b2017-01-03 17:18:24 -08001991 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001992 return result;
1993 } else {
1994 return JNI_FALSE;
1995 }
1996}
1997
1998static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1999 jobject,
2000 jint gnssPosProtocol) {
2001 if (gnssConfigurationIface == nullptr) {
2002 ALOGE("no GNSS configuration interface available");
2003 return JNI_FALSE;
2004 }
2005
2006 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002007 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002008 return result;
2009 } else {
2010 return JNI_FALSE;
2011 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002012}
2013
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002014static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
2015 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2016 if (gnssConfigurationIface_V1_1 == nullptr) {
2017 ALOGI("No GNSS Satellite Blacklist interface available");
2018 return JNI_FALSE;
2019 }
2020
2021 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
2022 if (NULL == constellation_array) {
2023 ALOGI("GetIntArrayElements returns NULL.");
2024 return JNI_FALSE;
2025 }
2026 jsize length = env->GetArrayLength(constellations);
2027
2028 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
2029 if (NULL == sv_id_array) {
2030 ALOGI("GetIntArrayElements returns NULL.");
2031 return JNI_FALSE;
2032 }
2033
2034 if (length != env->GetArrayLength(sv_ids)) {
2035 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2036 return JNI_FALSE;
2037 }
2038
2039 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2040 sources.resize(length);
2041
2042 for (int i = 0; i < length; i++) {
2043 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2044 sources[i].svid = sv_id_array[i];
2045 }
2046
2047 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2048 if (result.isOk()) {
2049 return result;
2050 } else {
2051 return JNI_FALSE;
2052 }
2053}
2054
2055
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002056static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002057 if (gnssBatchingIface == nullptr) {
2058 return 0; // batching not supported, size = 0
2059 }
2060 auto result = gnssBatchingIface->getBatchSize();
2061 if (result.isOk()) {
2062 return static_cast<jint>(result);
2063 } else {
2064 return 0; // failure in binder, don't support batching
2065 }
2066}
2067
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002068static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002069 if (gnssBatchingIface == nullptr) {
2070 return JNI_FALSE; // batching not supported
2071 }
2072 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2073
2074 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2075}
2076
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002077static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002078 if (gnssBatchingIface == nullptr) {
2079 return; // batching not supported
2080 }
2081 gnssBatchingIface->cleanup();
2082}
2083
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002084static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002085 jlong periodNanos, jboolean wakeOnFifoFull) {
2086 if (gnssBatchingIface == nullptr) {
2087 return JNI_FALSE; // batching not supported
2088 }
2089
2090 IGnssBatching::Options options;
2091 options.periodNanos = periodNanos;
2092 if (wakeOnFifoFull) {
2093 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2094 } else {
2095 options.flags = 0;
2096 }
2097
2098 return static_cast<jboolean>(gnssBatchingIface->start(options));
2099}
2100
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002101static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002102 if (gnssBatchingIface == nullptr) {
2103 return; // batching not supported
2104 }
2105
2106 gnssBatchingIface->flush();
2107}
2108
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002109static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002110 if (gnssBatchingIface == nullptr) {
2111 return JNI_FALSE; // batching not supported
2112 }
2113
2114 return gnssBatchingIface->stop();
2115}
2116
Daniel Micay76f6a862015-09-19 17:31:01 -04002117static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002119 {"class_init_native", "()V", reinterpret_cast<void *>(
2120 android_location_GnssLocationProvider_class_init_native)},
2121 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2122 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002123 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002124 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002125 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002126 reinterpret_cast<void *>(
2127 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002128 {"native_init_once", "()V", reinterpret_cast<void *>(
2129 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002130 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2131 {"native_cleanup", "()V", reinterpret_cast<void *>(
2132 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002133 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002134 "(IIIIIZ)Z",
2135 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002136 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2137 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002138 {"native_delete_aiding_data",
2139 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002140 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002141 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2142 android_location_GnssLocationProvider_read_nmea)},
2143 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2144 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002145 {"native_inject_best_location",
2146 "(IDDDFFFFFFJ)V",
2147 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002148 {"native_inject_location",
2149 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002150 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2151 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2152 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002153 {"native_inject_xtra_data",
2154 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002155 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002156 {"native_agps_data_conn_open",
2157 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002158 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002159 {"native_agps_data_conn_closed",
2160 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002161 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002162 {"native_agps_data_conn_failed",
2163 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002164 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002165 {"native_agps_set_id",
2166 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002167 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002168 {"native_agps_set_ref_location_cellid",
2169 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002170 reinterpret_cast<void *>(
2171 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002172 {"native_set_agps_server",
2173 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002174 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002175 {"native_send_ni_response",
2176 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002177 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002178 {"native_get_internal_state",
2179 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002180 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002181 {"native_update_network_state",
2182 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002183 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002184 {"native_set_supl_es",
2185 "(I)Z",
2186 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2187 {"native_set_supl_version",
2188 "(I)Z",
2189 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2190 {"native_set_supl_mode",
2191 "(I)Z",
2192 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2193 {"native_set_lpp_profile",
2194 "(I)Z",
2195 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2196 {"native_set_gnss_pos_protocol_select",
2197 "(I)Z",
2198 reinterpret_cast<void *>(
2199 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2200 {"native_set_gps_lock",
2201 "(I)Z",
2202 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2203 {"native_set_emergency_supl_pdn",
2204 "(I)Z",
2205 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002206 {"native_set_satellite_blacklist",
2207 "([I[I)Z",
2208 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002209};
2210
2211static const JNINativeMethod sMethodsBatching[] = {
2212 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002213 {"native_get_batch_size",
2214 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002215 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002216 {"native_start_batch",
2217 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002218 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002219 {"native_flush_batch",
2220 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002221 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002222 {"native_stop_batch",
2223 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002224 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002225 {"native_init_batching",
2226 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002227 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002228 {"native_cleanup_batching",
2229 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002230 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231};
2232
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002233static const JNINativeMethod sGeofenceMethods[] = {
2234 /* name, signature, funcPtr */
2235 {"native_is_geofence_supported",
2236 "()Z",
2237 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2238 {"native_add_geofence",
2239 "(IDDDIIII)Z",
2240 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2241 {"native_remove_geofence",
2242 "(I)Z",
2243 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2244 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2245 android_location_GnssGeofenceProvider_pause_geofence)},
2246 {"native_resume_geofence",
2247 "(II)Z",
2248 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2249};
2250
Yu-Han Yang8de21502018-04-23 01:40:25 -07002251static const JNINativeMethod sMeasurementMethods[] = {
2252 /* name, signature, funcPtr */
2253 {"native_is_measurement_supported",
2254 "()Z",
2255 reinterpret_cast<void *>(
2256 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2257 {"native_start_measurement_collection",
2258 "(Z)Z",
2259 reinterpret_cast<void *>(
2260 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2261 {"native_stop_measurement_collection",
2262 "()Z",
2263 reinterpret_cast<void *>(
2264 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2265};
2266
Yu-Han Yang23d92162018-04-19 06:03:00 -07002267static const JNINativeMethod sNavigationMessageMethods[] = {
2268 /* name, signature, funcPtr */
2269 {"native_is_navigation_message_supported",
2270 "()Z",
2271 reinterpret_cast<void *>(
2272 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2273 {"native_start_navigation_message_collection",
2274 "()Z",
2275 reinterpret_cast<void *>(
2276 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2277 {"native_stop_navigation_message_collection",
2278 "()Z",
2279 reinterpret_cast<void *>(
2280 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2281};
2282
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002283int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002284 jniRegisterNativeMethods(
2285 env,
2286 "com/android/server/location/GnssBatchingProvider",
2287 sMethodsBatching,
2288 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002289 jniRegisterNativeMethods(
2290 env,
2291 "com/android/server/location/GnssGeofenceProvider",
2292 sGeofenceMethods,
2293 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002294 jniRegisterNativeMethods(
2295 env,
2296 "com/android/server/location/GnssMeasurementsProvider",
2297 sMeasurementMethods,
2298 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002299 jniRegisterNativeMethods(
2300 env,
2301 "com/android/server/location/GnssNavigationMessageProvider",
2302 sNavigationMessageMethods,
2303 NELEM(sNavigationMessageMethods));
destradaaea8a8a62014-06-23 18:19:03 -07002304 return jniRegisterNativeMethods(
2305 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002306 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002307 sMethods,
2308 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002309}
2310
2311} /* namespace android */