blob: 92160053804dcb83df0801a7a23ffcd25f27da8c [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
WyattRiley840c0b22018-10-31 09:03:53 -070043static jobject mCallbacksObj = nullptr;
Mike Lockwoodf602d362010-06-20 14:28:16 -070044
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]);
WyattRiley840c0b22018-10-31 09:03:53 -0700720 if (dataLength == 0 || data == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700721 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(
WyattRiley840c0b22018-10-31 09:03:53 -0700752 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(
WyattRiley840c0b22018-10-31 09:03:53 -0700775 env, data.measurements.data(), nullptr, 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(
WyattRiley840c0b22018-10-31 09:03:53 -0700792 env, nullptr, data.measurements.data(), data.measurementCount);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800793 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(
WyattRiley840c0b22018-10-31 09:03:53 -0700802 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) {
WyattRiley840c0b22018-10-31 09:03:53 -0700886 return nullptr;
destradaaea8a8a62014-06-23 18:19:03 -0700887 }
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,
WyattRiley840c0b22018-10-31 09:03:53 -0700893 nullptr /* initialElement */);
destradaaea8a8a62014-06-23 18:19:03 -0700894
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");
WyattRiley840c0b22018-10-31 09:03:53 -0700897 if (measurements_v1_1 != nullptr) {
898 translateGnssMeasurement_V1_0(&(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 {
WyattRiley840c0b22018-10-31 09:03:53 -0700905 translateGnssMeasurement_V1_0(&(measurements_v1_0[i]), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800906 }
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();
WyattRiley840c0b22018-10-31 09:03:53 -0700990 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991
992 byteArray = env->NewByteArray(16);
WyattRiley840c0b22018-10-31 09:03:53 -0700993 if (byteArray != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700994 env->SetByteArrayRegion(byteArray, 0, 16,
995 (const jbyte*)(agps_status.ipV6Addr.data()));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700996 } else {
997 ALOGE("Unable to allocate byte array for IPv6 address.");
998 }
999
1000 IF_ALOGD() {
1001 // log the IP for reference in case there is a bogus value pushed by HAL
1002 char str[INET6_ADDRSTRLEN];
1003 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1004 ALOGD("AGPS IP is v6: %s", str);
1005 }
1006
WyattRiley840c0b22018-10-31 09:03:53 -07001007 jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001008 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1009 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1010 agps_status.type, agps_status.status, byteArray);
1011
1012 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1013
1014 if (byteArray) {
1015 env->DeleteLocalRef(byteArray);
1016 }
1017
1018 return Void();
1019}
1020
1021Return<void> AGnssCallback::agnssStatusIpV4Cb(
1022 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001023 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001024 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001025
1026 uint32_t ipAddr = agps_status.ipV4Addr;
1027 byteArray = convertToIpV4(ipAddr);
1028
1029 IF_ALOGD() {
1030 /*
1031 * log the IP for reference in case there is a bogus value pushed by
1032 * HAL.
1033 */
1034 char str[INET_ADDRSTRLEN];
1035 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1036 ALOGD("AGPS IP is v4: %s", str);
1037 }
1038
1039 jsize byteArrayLength =
WyattRiley840c0b22018-10-31 09:03:53 -07001040 byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001041 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1042 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1043 agps_status.type, agps_status.status, byteArray);
1044
1045 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1046
1047 if (byteArray) {
1048 env->DeleteLocalRef(byteArray);
1049 }
1050 return Void();
1051}
1052
1053jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1054 if (INADDR_NONE == ip) {
WyattRiley840c0b22018-10-31 09:03:53 -07001055 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001056 }
1057
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001058 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001059 jbyteArray byteArray = env->NewByteArray(4);
WyattRiley840c0b22018-10-31 09:03:53 -07001060 if (byteArray == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001061 ALOGE("Unable to allocate byte array for IPv4 address");
WyattRiley840c0b22018-10-31 09:03:53 -07001062 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001063 }
1064
1065 jbyte ipv4[4];
1066 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1067 memcpy(ipv4, &ip, sizeof(ipv4));
1068 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1069 return byteArray;
1070}
1071
1072/*
1073 * AGnssRilCallback implements the callback methods required by the AGnssRil
1074 * interface.
1075 */
1076struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001077 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001078 Return<void> requestRefLocCb() override;
1079};
1080
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001081Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001082 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001083 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1084 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1085 return Void();
1086}
1087
1088Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001089 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001090 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1091 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1092 return Void();
1093}
1094
Wyatt Rileycf879db2017-01-12 13:57:38 -08001095/*
1096 * GnssBatchingCallback interface implements the callback methods
1097 * required by the IGnssBatching interface.
1098 */
1099struct GnssBatchingCallback : public IGnssBatchingCallback {
1100 /*
1101 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1102 * follow.
1103 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001104 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001105 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001106};
1107
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001108Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001109 JNIEnv* env = getJniEnv();
1110
1111 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1112 env->FindClass("android/location/Location"), nullptr);
1113
1114 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001115 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001116 env->SetObjectArrayElement(jLocations, i, jLocation);
1117 env->DeleteLocalRef(jLocation);
1118 }
1119
1120 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1121 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1122
1123 env->DeleteLocalRef(jLocations);
1124
1125 return Void();
1126}
1127
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001128static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001129 gnssHal_V1_1 = IGnss_V1_1::getService();
1130 if (gnssHal_V1_1 == nullptr) {
1131 ALOGD("gnssHal 1.1 was null, trying 1.0");
1132 gnssHal = IGnss_V1_0::getService();
1133 } else {
1134 gnssHal = gnssHal_V1_1;
1135 }
1136}
1137
1138static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001139 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1140 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001141 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001142 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001143 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1144 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1145 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1146 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001147 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1148 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001149 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1150 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1151 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001152 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001153 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1154 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1155 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1156 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001157 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001158 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001159 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001160 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1161 "(II)V");
1162 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1163 "(II)V");
1164 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1165 "(II)V");
1166 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1167 "(II)V");
1168 method_reportMeasurementData = env->GetMethodID(
1169 clazz,
1170 "reportMeasurementData",
1171 "(Landroid/location/GnssMeasurementsEvent;)V");
1172 method_reportNavigationMessages = env->GetMethodID(
1173 clazz,
1174 "reportNavigationMessage",
1175 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001176 method_reportLocationBatch = env->GetMethodID(
1177 clazz,
1178 "reportLocationBatch",
1179 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001180 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001181
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001182 /*
1183 * Save a pointer to JVM.
1184 */
1185 jint jvmStatus = env->GetJavaVM(&sJvm);
1186 if (jvmStatus != JNI_OK) {
1187 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1188 }
1189
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001190 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001191 gnssHalDeathRecipient = new GnssDeathRecipient();
1192 hardware::Return<bool> linked = gnssHal->linkToDeath(
1193 gnssHalDeathRecipient, /*cookie*/ 0);
1194 if (!linked.isOk()) {
1195 ALOGE("Transaction error in linking to GnssHAL death: %s",
1196 linked.description().c_str());
1197 } else if (!linked) {
1198 ALOGW("Unable to link to GnssHal death notifications");
1199 } else {
1200 ALOGD("Link to death notification successful");
1201 }
1202
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001203 auto gnssXtra = gnssHal->getExtensionXtra();
1204 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001205 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001206 } else {
1207 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001208 }
1209
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001210 auto gnssRil = gnssHal->getExtensionAGnssRil();
1211 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001212 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001213 } else {
1214 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001215 }
1216
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001217 auto gnssAgnss = gnssHal->getExtensionAGnss();
1218 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001219 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001220 } else {
1221 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001222 }
1223
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001224 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1225 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001226 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001227 } else {
1228 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001229 }
1230
gomo48f1a642017-11-10 20:35:46 -08001231 if (gnssHal_V1_1 != nullptr) {
1232 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1233 if (!gnssMeasurement.isOk()) {
1234 ALOGD("Unable to get a handle to GnssMeasurement");
1235 } else {
1236 gnssMeasurementIface_V1_1 = gnssMeasurement;
1237 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1238 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001239 } else {
gomo48f1a642017-11-10 20:35:46 -08001240 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1241 if (!gnssMeasurement_V1_0.isOk()) {
1242 ALOGD("Unable to get a handle to GnssMeasurement");
1243 } else {
1244 gnssMeasurementIface = gnssMeasurement_V1_0;
1245 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001246 }
1247
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001248 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1249 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001250 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001251 } else {
1252 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001253 }
1254
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001255 auto gnssNi = gnssHal->getExtensionGnssNi();
1256 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001257 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001258 } else {
1259 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001260 }
1261
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001262 if (gnssHal_V1_1 != nullptr) {
1263 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1264 if (!gnssConfiguration.isOk()) {
1265 ALOGD("Unable to get a handle to GnssConfiguration");
1266 } else {
1267 gnssConfigurationIface_V1_1 = gnssConfiguration;
1268 gnssConfigurationIface = gnssConfigurationIface_V1_1;
1269 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001270 } else {
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001271 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1272 if (!gnssConfiguration_V1_0.isOk()) {
1273 ALOGD("Unable to get a handle to GnssConfiguration");
1274 } else {
1275 gnssConfigurationIface = gnssConfiguration_V1_0;
1276 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001277 }
1278
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001279 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1280 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001281 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001282 } else {
1283 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001284 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001285
1286 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1287 if (!gnssBatching.isOk()) {
1288 ALOGD("Unable to get a handle to gnssBatching");
1289 } else {
1290 gnssBatchingIface = gnssBatching;
1291 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001292 } else {
1293 ALOGE("Unable to get GPS service\n");
1294 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001295}
1296
1297static jboolean android_location_GnssLocationProvider_is_supported(
1298 JNIEnv* /* env */, jclass /* clazz */) {
1299 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1300}
1301
Anil Admal50ba15e2018-11-01 16:42:42 -07001302static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001303 JNIEnv* /* env */, jclass /* clazz */) {
1304 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1305}
1306
1307static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1308 JNIEnv* /* env */, jclass /* jclazz */) {
1309 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1310}
1311
1312static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1313 /*
1314 * This must be set before calling into the HAL library.
1315 */
1316 if (!mCallbacksObj)
1317 mCallbacksObj = env->NewGlobalRef(obj);
1318
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001319 /*
1320 * Fail if the main interface fails to initialize
1321 */
1322 if (gnssHal == nullptr) {
1323 ALOGE("Unable to Initialize GNSS HAL\n");
1324 return JNI_FALSE;
1325 }
1326
Wyatt Rileyfb840922017-11-08 15:07:58 -08001327 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1328
1329 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001330 if (gnssHal_V1_1 != nullptr) {
1331 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001332 } else {
1333 result = gnssHal->setCallback(gnssCbIface);
1334 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001335 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001336 ALOGE("SetCallback for Gnss Interface fails\n");
1337 return JNI_FALSE;
1338 }
1339
1340 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1341 if (gnssXtraIface == nullptr) {
WyattRileybc5a8b02018-10-31 13:06:34 -07001342 ALOGI("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001343 } else {
1344 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001345 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001346 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001347 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001348 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001349 }
1350
1351 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1352 if (agnssIface != nullptr) {
1353 agnssIface->setCallback(aGnssCbIface);
1354 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001355 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001356 }
1357
1358 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1359 if (gnssGeofencingIface != nullptr) {
1360 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1361 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001362 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001363 }
1364
1365 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001366 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001367 gnssNiIface->setCallback(gnssNiCbIface);
1368 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001369 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001370 }
1371
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001372 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1373 if (agnssRilIface != nullptr) {
1374 agnssRilIface->setCallback(aGnssRilCbIface);
1375 } else {
1376 ALOGI("Unable to Initialize AGnss Ril interface\n");
1377 }
1378
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001379 return JNI_TRUE;
1380}
1381
1382static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1383 if (gnssHal != nullptr) {
1384 gnssHal->cleanup();
1385 }
1386}
1387
1388static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1389 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001390 jint preferred_time, jboolean low_power_mode) {
1391 Return<bool> result = false;
1392 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001393 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1394 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1395 min_interval,
1396 preferred_accuracy,
1397 preferred_time,
1398 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001399 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001400 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1401 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1402 min_interval,
1403 preferred_accuracy,
1404 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001405 }
1406 if (!result.isOk()) {
1407 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1408 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001409 } else {
gomo48f1a642017-11-10 20:35:46 -08001410 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001411 }
1412}
1413
1414static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1415 if (gnssHal != nullptr) {
1416 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001417 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001418 return JNI_FALSE;
1419 } else {
1420 return result;
1421 }
1422 } else {
1423 return JNI_FALSE;
1424 }
1425}
1426
1427static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1428 if (gnssHal != nullptr) {
1429 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001430 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001431 return JNI_FALSE;
1432 } else {
1433 return result;
1434 }
1435 } else {
1436 return JNI_FALSE;
1437 }
1438}
1439static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1440 jobject /* obj */,
1441 jint flags) {
1442 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001443 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001444 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001445 ALOGE("Error in deleting aiding data");
1446 }
1447 }
1448}
1449
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001450static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1451 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1452 IAGnssRil::AGnssRefLocation location;
1453
1454 if (agnssRilIface == nullptr) {
1455 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1456 return;
1457 }
1458
1459 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1460 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1461 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1462 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1463 location.cellID.mcc = mcc;
1464 location.cellID.mnc = mnc;
1465 location.cellID.lac = lac;
1466 location.cellID.cid = cid;
1467 break;
1468 default:
1469 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1470 return;
1471 break;
1472 }
1473
1474 agnssRilIface->setRefLocation(location);
1475}
1476
1477static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1478 jint type, jstring setid_string) {
1479 if (agnssRilIface == nullptr) {
1480 ALOGE("no AGPS RIL interface in agps_set_id");
1481 return;
1482 }
1483
WyattRiley840c0b22018-10-31 09:03:53 -07001484 const char *setid = env->GetStringUTFChars(setid_string, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001485 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1486 env->ReleaseStringUTFChars(setid_string, setid);
1487}
1488
1489static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1490 jbyteArray nmeaArray, jint buffer_size) {
1491 // this should only be called from within a call to reportNmea
1492 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1493 int length = GnssCallback::sNmeaStringLength;
1494 if (length > buffer_size)
1495 length = buffer_size;
1496 memcpy(nmea, GnssCallback::sNmeaString, length);
1497 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1498 return (jint) length;
1499}
1500
1501static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1502 jlong time, jlong timeReference, jint uncertainty) {
1503 if (gnssHal != nullptr) {
1504 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001505 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001506 ALOGE("%s: Gnss injectTime() failed", __func__);
1507 }
1508 }
1509}
1510
Yu-Han Yange7baef32018-02-09 13:58:17 -08001511static void android_location_GnssLocationProvider_inject_best_location(
1512 JNIEnv*,
1513 jobject,
1514 jint gnssLocationFlags,
1515 jdouble latitudeDegrees,
1516 jdouble longitudeDegrees,
1517 jdouble altitudeMeters,
1518 jfloat speedMetersPerSec,
1519 jfloat bearingDegrees,
1520 jfloat horizontalAccuracyMeters,
1521 jfloat verticalAccuracyMeters,
1522 jfloat speedAccuracyMetersPerSecond,
1523 jfloat bearingAccuracyDegrees,
1524 jlong timestamp) {
1525 if (gnssHal_V1_1 != nullptr) {
1526 GnssLocation location = createGnssLocation(
1527 gnssLocationFlags,
1528 latitudeDegrees,
1529 longitudeDegrees,
1530 altitudeMeters,
1531 speedMetersPerSec,
1532 bearingDegrees,
1533 horizontalAccuracyMeters,
1534 verticalAccuracyMeters,
1535 speedAccuracyMetersPerSecond,
1536 bearingAccuracyDegrees,
1537 timestamp);
1538 auto result = gnssHal_V1_1->injectBestLocation(location);
1539 if (!result.isOk() || !result) {
1540 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1541 }
1542 } else {
1543 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1544 }
1545}
1546
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001547static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1548 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1549 if (gnssHal != nullptr) {
1550 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001551 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001552 ALOGE("%s: Gnss injectLocation() failed", __func__);
1553 }
1554 }
1555}
1556
1557static jboolean android_location_GnssLocationProvider_supports_xtra(
1558 JNIEnv* /* env */, jobject /* obj */) {
1559 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1560}
1561
1562static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1563 jbyteArray data, jint length) {
1564 if (gnssXtraIface == nullptr) {
1565 ALOGE("XTRA Interface not supported");
1566 return;
1567 }
1568
1569 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1570 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1571 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1572}
1573
Anil Admal50ba15e2018-11-01 16:42:42 -07001574static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001575 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1576 if (agnssIface == nullptr) {
1577 ALOGE("no AGPS interface in agps_data_conn_open");
1578 return;
1579 }
WyattRiley840c0b22018-10-31 09:03:53 -07001580 if (apn == nullptr) {
1581 jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001582 return;
1583 }
1584
WyattRiley840c0b22018-10-31 09:03:53 -07001585 const char *apnStr = env->GetStringUTFChars(apn, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001586
1587 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001588 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001589 ALOGE("%s: Failed to set APN and its IP type", __func__);
1590 }
1591 env->ReleaseStringUTFChars(apn, apnStr);
1592}
1593
Anil Admal50ba15e2018-11-01 16:42:42 -07001594static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001595 jobject /* obj */) {
1596 if (agnssIface == nullptr) {
1597 ALOGE("%s: AGPS interface not supported", __func__);
1598 return;
1599 }
1600
1601 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001602 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 ALOGE("%s: Failed to close AGnss data connection", __func__);
1604 }
1605}
1606
Anil Admal50ba15e2018-11-01 16:42:42 -07001607static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001608 jobject /* obj */) {
1609 if (agnssIface == nullptr) {
1610 ALOGE("%s: AGPS interface not supported", __func__);
1611 return;
1612 }
1613
1614 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001615 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001616 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1617 }
1618}
1619
1620static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1621 jint type, jstring hostname, jint port) {
1622 if (agnssIface == nullptr) {
1623 ALOGE("no AGPS interface in set_agps_server");
1624 return;
1625 }
1626
WyattRiley840c0b22018-10-31 09:03:53 -07001627 const char *c_hostname = env->GetStringUTFChars(hostname, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001628 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1629 c_hostname,
1630 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001631 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1633 }
1634
1635 env->ReleaseStringUTFChars(hostname, c_hostname);
1636}
1637
1638static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1639 jobject /* obj */, jint notifId, jint response) {
1640 if (gnssNiIface == nullptr) {
1641 ALOGE("no NI interface in send_ni_response");
1642 return;
1643 }
1644
1645 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1646}
1647
1648static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1649 jobject /* obj */) {
WyattRiley840c0b22018-10-31 09:03:53 -07001650 jstring result = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001651 /*
1652 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1653 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001654
1655 std::stringstream internalState;
1656
1657 if (gnssDebugIface == nullptr) {
1658 internalState << "Gnss Debug Interface not available" << std::endl;
1659 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001660 IGnssDebug::DebugData data;
1661 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1662 data = debugData;
1663 });
1664
Wyatt Riley268c6e02017-03-29 10:21:46 -07001665 internalState << "Gnss Location Data:: ";
1666 if (!data.position.valid) {
1667 internalState << "not valid";
1668 } else {
1669 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001670 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1671 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001672 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1673 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001674 << ", horizontalAccuracyMeters: "
1675 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001676 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001677 << ", speedAccuracyMetersPerSecond: "
1678 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001679 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001680 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001681 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001682 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683
Wyatt Riley268c6e02017-03-29 10:21:46 -07001684 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1685 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1686 << ", frequencyUncertaintyNsPerSec: "
1687 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001688
1689 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001690 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1691 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001692 }
1693
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001694 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1695 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
1696 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
1697 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001698 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001699 internalState << "constell: "
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001700 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001701 << ", svid: " << std::setw(3) << data.satelliteDataArray[i].svid
1702 << ", serverPredAvail: "
Wyatt Riley268c6e02017-03-29 10:21:46 -07001703 << data.satelliteDataArray[i].serverPredictionIsAvailable
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001704 << ", serverPredAgeSec: " << std::setw(7)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001705 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001706 << ", ephType: "
1707 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1708 << ", ephSource: "
1709 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1710 << ", ephHealth: "
1711 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1712 << ", ephAgeSec: " << std::setw(7)
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001713 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1714 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001715 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001716
1717 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001718 return result;
1719}
1720
Anil Admal50ba15e2018-11-01 16:42:42 -07001721static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001722 jobject /* obj */,
1723 jboolean connected,
1724 jint type,
1725 jboolean roaming,
1726 jboolean available,
1727 jstring extraInfo,
1728 jstring apn) {
1729 if (agnssRilIface != nullptr) {
1730 auto result = agnssRilIface->updateNetworkState(connected,
1731 static_cast<IAGnssRil::NetworkType>(type),
1732 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001733 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001734 ALOGE("updateNetworkState failed");
1735 }
1736
WyattRiley840c0b22018-10-31 09:03:53 -07001737 const char *c_apn = env->GetStringUTFChars(apn, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001738 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001739 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001740 ALOGE("updateNetworkAvailability failed");
1741 }
1742
1743 env->ReleaseStringUTFChars(apn, c_apn);
1744 } else {
1745 ALOGE("AGnssRilInterface does not exist");
1746 }
1747}
1748
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001749static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 JNIEnv* /* env */, jobject /* obj */) {
1751 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1752}
1753
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001754static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001755 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1756 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1757 jint unknown_timer) {
1758 if (gnssGeofencingIface != nullptr) {
1759 auto result = gnssGeofencingIface->addGeofence(
1760 geofenceId, latitude, longitude, radius,
1761 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1762 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001763 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001764 } else {
1765 ALOGE("Geofence Interface not available");
1766 }
1767 return JNI_FALSE;
1768}
1769
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001770static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001771 jobject /* obj */, jint geofenceId) {
1772 if (gnssGeofencingIface != nullptr) {
1773 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001774 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001775 } else {
1776 ALOGE("Geofence interface not available");
1777 }
1778 return JNI_FALSE;
1779}
1780
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001781static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001782 jobject /* obj */, jint geofenceId) {
1783 if (gnssGeofencingIface != nullptr) {
1784 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001785 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001786 } else {
1787 ALOGE("Geofence interface not available");
1788 }
1789 return JNI_FALSE;
1790}
1791
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001792static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001793 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1794 if (gnssGeofencingIface != nullptr) {
1795 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001796 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001797 } else {
1798 ALOGE("Geofence interface not available");
1799 }
1800 return JNI_FALSE;
1801}
1802
Yu-Han Yang8de21502018-04-23 01:40:25 -07001803static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001804 JNIEnv* env, jclass clazz) {
1805 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001806 return JNI_TRUE;
1807 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001808
destradaaea8a8a62014-06-23 18:19:03 -07001809 return JNI_FALSE;
1810}
1811
Yu-Han Yang8de21502018-04-23 01:40:25 -07001812static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001813 JNIEnv* /* env */,
1814 jobject /* obj */,
1815 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001816 if (gnssMeasurementIface == nullptr) {
1817 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001818 return JNI_FALSE;
1819 }
1820
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001821 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001822 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1823 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1824 if (gnssMeasurementIface_V1_1 != nullptr) {
1825 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1826 enableFullTracking);
1827 } else {
1828 if (enableFullTracking == JNI_TRUE) {
1829 // full tracking mode not supported in 1.0 HAL
1830 return JNI_FALSE;
1831 }
1832 result = gnssMeasurementIface->setCallback(cbIface);
1833 }
1834
1835 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001836 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1837 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001838 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001839 } else {
1840 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001841 }
1842
1843 return JNI_TRUE;
1844}
1845
Yu-Han Yang8de21502018-04-23 01:40:25 -07001846static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001847 JNIEnv* env,
1848 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001849 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001850 ALOGE("Measurement interface not available");
1851 return JNI_FALSE;
1852 }
1853
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001854 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001855 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001856}
1857
Yu-Han Yang23d92162018-04-19 06:03:00 -07001858static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001859 JNIEnv* env,
1860 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001861 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001862 return JNI_TRUE;
1863 }
1864 return JNI_FALSE;
1865}
1866
Yu-Han Yang23d92162018-04-19 06:03:00 -07001867static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001868 JNIEnv* env,
1869 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001870 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001871 ALOGE("Navigation Message interface is not available.");
1872 return JNI_FALSE;
1873 }
1874
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001875 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1876 new GnssNavigationMessageCallback();
1877 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1878 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1879
1880 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1881 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001882 return JNI_FALSE;
1883 }
1884
1885 return JNI_TRUE;
1886}
1887
Yu-Han Yang23d92162018-04-19 06:03:00 -07001888static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001889 JNIEnv* env,
1890 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001891 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001892 ALOGE("Navigation Message interface is not available.");
1893 return JNI_FALSE;
1894 }
1895
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001896 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001897 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001898}
1899
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001900static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1901 jobject,
1902 jint emergencySuplPdn) {
1903 if (gnssConfigurationIface == nullptr) {
1904 ALOGE("no GNSS configuration interface available");
1905 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001906 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001907
1908 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001909 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001910 return result;
1911 } else {
1912 return JNI_FALSE;
1913 }
1914}
1915
1916static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1917 jobject,
1918 jint version) {
1919 if (gnssConfigurationIface == nullptr) {
1920 ALOGE("no GNSS configuration interface available");
1921 return JNI_FALSE;
1922 }
1923 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001924 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001925 return result;
1926 } else {
1927 return JNI_FALSE;
1928 }
1929}
1930
1931static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1932 jobject,
1933 jint suplEs) {
1934 if (gnssConfigurationIface == nullptr) {
1935 ALOGE("no GNSS configuration interface available");
1936 return JNI_FALSE;
1937 }
1938
1939 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001940 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001941 return result;
1942 } else {
1943 return JNI_FALSE;
1944 }
1945}
1946
1947static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1948 jobject,
1949 jint mode) {
1950 if (gnssConfigurationIface == nullptr) {
1951 ALOGE("no GNSS configuration interface available");
1952 return JNI_FALSE;
1953 }
1954
1955 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001956 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001957 return result;
1958 } else {
1959 return JNI_FALSE;
1960 }
1961}
1962
1963static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1964 jobject,
1965 jint gpsLock) {
1966 if (gnssConfigurationIface == nullptr) {
1967 ALOGE("no GNSS configuration interface available");
1968 return JNI_FALSE;
1969 }
1970
1971 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001972 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001973 return result;
1974 } else {
1975 return JNI_FALSE;
1976 }
1977}
1978
1979static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1980 jobject,
1981 jint lppProfile) {
1982 if (gnssConfigurationIface == nullptr) {
1983 ALOGE("no GNSS configuration interface available");
1984 return JNI_FALSE;
1985 }
1986
1987 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1988
Steven Morelandd002a8b2017-01-03 17:18:24 -08001989 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001990 return result;
1991 } else {
1992 return JNI_FALSE;
1993 }
1994}
1995
1996static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1997 jobject,
1998 jint gnssPosProtocol) {
1999 if (gnssConfigurationIface == nullptr) {
2000 ALOGE("no GNSS configuration interface available");
2001 return JNI_FALSE;
2002 }
2003
2004 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002005 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002006 return result;
2007 } else {
2008 return JNI_FALSE;
2009 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002010}
2011
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002012static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
2013 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2014 if (gnssConfigurationIface_V1_1 == nullptr) {
2015 ALOGI("No GNSS Satellite Blacklist interface available");
2016 return JNI_FALSE;
2017 }
2018
2019 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002020 if (nullptr == constellation_array) {
2021 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002022 return JNI_FALSE;
2023 }
2024 jsize length = env->GetArrayLength(constellations);
2025
2026 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002027 if (nullptr == sv_id_array) {
2028 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002029 return JNI_FALSE;
2030 }
2031
2032 if (length != env->GetArrayLength(sv_ids)) {
2033 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2034 return JNI_FALSE;
2035 }
2036
2037 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2038 sources.resize(length);
2039
2040 for (int i = 0; i < length; i++) {
2041 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2042 sources[i].svid = sv_id_array[i];
2043 }
2044
2045 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2046 if (result.isOk()) {
2047 return result;
2048 } else {
2049 return JNI_FALSE;
2050 }
2051}
2052
2053
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002054static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002055 if (gnssBatchingIface == nullptr) {
2056 return 0; // batching not supported, size = 0
2057 }
2058 auto result = gnssBatchingIface->getBatchSize();
2059 if (result.isOk()) {
2060 return static_cast<jint>(result);
2061 } else {
2062 return 0; // failure in binder, don't support batching
2063 }
2064}
2065
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002066static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002067 if (gnssBatchingIface == nullptr) {
2068 return JNI_FALSE; // batching not supported
2069 }
2070 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2071
2072 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2073}
2074
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002075static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002076 if (gnssBatchingIface == nullptr) {
2077 return; // batching not supported
2078 }
2079 gnssBatchingIface->cleanup();
2080}
2081
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002082static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002083 jlong periodNanos, jboolean wakeOnFifoFull) {
2084 if (gnssBatchingIface == nullptr) {
2085 return JNI_FALSE; // batching not supported
2086 }
2087
2088 IGnssBatching::Options options;
2089 options.periodNanos = periodNanos;
2090 if (wakeOnFifoFull) {
2091 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2092 } else {
2093 options.flags = 0;
2094 }
2095
2096 return static_cast<jboolean>(gnssBatchingIface->start(options));
2097}
2098
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002099static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002100 if (gnssBatchingIface == nullptr) {
2101 return; // batching not supported
2102 }
2103
2104 gnssBatchingIface->flush();
2105}
2106
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002107static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002108 if (gnssBatchingIface == nullptr) {
2109 return JNI_FALSE; // batching not supported
2110 }
2111
2112 return gnssBatchingIface->stop();
2113}
2114
Daniel Micay76f6a862015-09-19 17:31:01 -04002115static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002117 {"class_init_native", "()V", reinterpret_cast<void *>(
2118 android_location_GnssLocationProvider_class_init_native)},
2119 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2120 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002121 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002122 reinterpret_cast<void *>(
2123 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002124 {"native_init_once", "()V", reinterpret_cast<void *>(
2125 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002126 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2127 {"native_cleanup", "()V", reinterpret_cast<void *>(
2128 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002129 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002130 "(IIIIIZ)Z",
2131 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002132 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2133 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002134 {"native_delete_aiding_data",
2135 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002136 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002137 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2138 android_location_GnssLocationProvider_read_nmea)},
2139 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2140 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002141 {"native_inject_best_location",
2142 "(IDDDFFFFFFJ)V",
2143 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002144 {"native_inject_location",
2145 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002146 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2147 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2148 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002149 {"native_inject_xtra_data",
2150 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002151 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002152 {"native_agps_set_id",
2153 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002154 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002155 {"native_agps_set_ref_location_cellid",
2156 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002157 reinterpret_cast<void *>(
2158 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002159 {"native_set_agps_server",
2160 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002161 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002162 {"native_send_ni_response",
2163 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002164 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002165 {"native_get_internal_state",
2166 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002167 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002168 {"native_set_supl_es",
2169 "(I)Z",
2170 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2171 {"native_set_supl_version",
2172 "(I)Z",
2173 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2174 {"native_set_supl_mode",
2175 "(I)Z",
2176 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2177 {"native_set_lpp_profile",
2178 "(I)Z",
2179 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2180 {"native_set_gnss_pos_protocol_select",
2181 "(I)Z",
2182 reinterpret_cast<void *>(
2183 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2184 {"native_set_gps_lock",
2185 "(I)Z",
2186 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2187 {"native_set_emergency_supl_pdn",
2188 "(I)Z",
2189 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002190 {"native_set_satellite_blacklist",
2191 "([I[I)Z",
2192 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002193};
2194
2195static const JNINativeMethod sMethodsBatching[] = {
2196 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002197 {"native_get_batch_size",
2198 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002199 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002200 {"native_start_batch",
2201 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002202 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002203 {"native_flush_batch",
2204 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002205 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002206 {"native_stop_batch",
2207 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002208 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002209 {"native_init_batching",
2210 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002211 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002212 {"native_cleanup_batching",
2213 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002214 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215};
2216
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002217static const JNINativeMethod sGeofenceMethods[] = {
2218 /* name, signature, funcPtr */
2219 {"native_is_geofence_supported",
2220 "()Z",
2221 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2222 {"native_add_geofence",
2223 "(IDDDIIII)Z",
2224 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2225 {"native_remove_geofence",
2226 "(I)Z",
2227 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2228 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2229 android_location_GnssGeofenceProvider_pause_geofence)},
2230 {"native_resume_geofence",
2231 "(II)Z",
2232 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2233};
2234
Yu-Han Yang8de21502018-04-23 01:40:25 -07002235static const JNINativeMethod sMeasurementMethods[] = {
2236 /* name, signature, funcPtr */
2237 {"native_is_measurement_supported",
2238 "()Z",
2239 reinterpret_cast<void *>(
2240 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2241 {"native_start_measurement_collection",
2242 "(Z)Z",
2243 reinterpret_cast<void *>(
2244 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2245 {"native_stop_measurement_collection",
2246 "()Z",
2247 reinterpret_cast<void *>(
2248 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2249};
2250
Yu-Han Yang23d92162018-04-19 06:03:00 -07002251static const JNINativeMethod sNavigationMessageMethods[] = {
2252 /* name, signature, funcPtr */
2253 {"native_is_navigation_message_supported",
2254 "()Z",
2255 reinterpret_cast<void *>(
2256 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2257 {"native_start_navigation_message_collection",
2258 "()Z",
2259 reinterpret_cast<void *>(
2260 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2261 {"native_stop_navigation_message_collection",
2262 "()Z",
2263 reinterpret_cast<void *>(
2264 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2265};
2266
Anil Admal50ba15e2018-11-01 16:42:42 -07002267static const JNINativeMethod sNetworkConnectivityMethods[] = {
2268 /* name, signature, funcPtr */
2269 {"native_is_agps_ril_supported", "()Z",
2270 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
2271 {"native_update_network_state",
2272 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
2273 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
2274 {"native_agps_data_conn_open",
2275 "(Ljava/lang/String;I)V",
2276 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
2277 {"native_agps_data_conn_closed",
2278 "()V",
2279 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
2280 {"native_agps_data_conn_failed",
2281 "()V",
2282 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
2283};
2284
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002285int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002286 jniRegisterNativeMethods(
2287 env,
2288 "com/android/server/location/GnssBatchingProvider",
2289 sMethodsBatching,
2290 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002291 jniRegisterNativeMethods(
2292 env,
2293 "com/android/server/location/GnssGeofenceProvider",
2294 sGeofenceMethods,
2295 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002296 jniRegisterNativeMethods(
2297 env,
2298 "com/android/server/location/GnssMeasurementsProvider",
2299 sMeasurementMethods,
2300 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002301 jniRegisterNativeMethods(
2302 env,
2303 "com/android/server/location/GnssNavigationMessageProvider",
2304 sNavigationMessageMethods,
2305 NELEM(sNavigationMessageMethods));
Anil Admal50ba15e2018-11-01 16:42:42 -07002306 jniRegisterNativeMethods(
2307 env,
2308 "com/android/server/location/GnssNetworkConnectivityHandler",
2309 sNetworkConnectivityMethods,
2310 NELEM(sNetworkConnectivityMethods));
destradaaea8a8a62014-06-23 18:19:03 -07002311 return jniRegisterNativeMethods(
2312 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002313 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002314 sMethods,
2315 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316}
2317
2318} /* namespace android */