blob: e18eee26761064a93b24b2bdf44481cbc69829cd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lifu Tang30f95a72016-01-07 23:20:38 -080017#define LOG_TAG "GnssLocationProvider"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwoodb8d90332010-10-18 17:59:48 -040019#define LOG_NDEBUG 0
Danke Xie22d1f9f2009-08-18 18:28:45 -040020
gomo48f1a642017-11-10 20:35:46 -080021#include <android/hardware/gnss/1.0/IGnss.h>
Wyatt Rileyfb840922017-11-08 15:07:58 -080022#include <android/hardware/gnss/1.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070023
gomo48f1a642017-11-10 20:35:46 -080024#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
25#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070026#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040028#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029#include "utils/Log.h"
30#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070031#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070032#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
destradaa931a37f2014-08-12 16:36:59 -070034#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <limits>
destradaa96a14702014-06-05 11:36:30 -070036#include <linux/in.h>
37#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080038#include <pthread.h>
39#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070040#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Mike Lockwoodf602d362010-06-20 14:28:16 -070042static jobject mCallbacksObj = NULL;
43
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044static jmethodID method_reportLocation;
45static jmethodID method_reportStatus;
46static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040047static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040048static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040049static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080050static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080051static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040053static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080054static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020055static jmethodID method_requestRefLocation;
56static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040057static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070058static jmethodID method_reportGeofenceTransition;
59static jmethodID method_reportGeofenceStatus;
60static jmethodID method_reportGeofenceAddStatus;
61static jmethodID method_reportGeofenceRemoveStatus;
62static jmethodID method_reportGeofencePauseStatus;
63static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070064static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070065static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080066static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080068/*
69 * Save a pointer to JavaVm to attach/detach threads executing
70 * callback methods that need to make JNI calls.
71 */
72static JavaVM* sJvm;
73
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070074using android::OK;
75using android::sp;
gomo25208882017-04-15 02:05:25 -070076using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070077using android::status_t;
78using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070080using android::hardware::Return;
81using android::hardware::Void;
82using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070083using android::hardware::hidl_death_recipient;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070084using android::hardware::gnss::V1_0::GnssConstellationType;
Wyatt Rileyfb840922017-11-08 15:07:58 -080085using android::hardware::gnss::V1_0::GnssLocation;
86using android::hardware::gnss::V1_0::GnssLocationFlags;
Wyatt Riley46ac9562018-03-02 20:16:58 -080087
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070088using android::hardware::gnss::V1_0::IAGnss;
89using android::hardware::gnss::V1_0::IAGnssCallback;
90using android::hardware::gnss::V1_0::IAGnssCallback;
91using android::hardware::gnss::V1_0::IAGnssRil;
92using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080093using android::hardware::gnss::V1_0::IGnssBatching;
94using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070095using android::hardware::gnss::V1_0::IGnssDebug;
96using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
97using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070098using android::hardware::gnss::V1_0::IGnssNavigationMessage;
99using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
100using android::hardware::gnss::V1_0::IGnssNi;
101using android::hardware::gnss::V1_0::IGnssNiCallback;
102using android::hardware::gnss::V1_0::IGnssXtra;
103using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800104
Wyatt Rileyfb840922017-11-08 15:07:58 -0800105using android::hardware::gnss::V1_1::IGnssCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800106
107using android::hidl::base::V1_0::IBase;
108
109using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
110using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700111using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
112using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800113using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
114using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
115using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
116using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
117
Wyatt Rileyfb840922017-11-08 15:07:58 -0800118
gomo25208882017-04-15 02:05:25 -0700119struct GnssDeathRecipient : virtual public hidl_death_recipient
120{
121 // hidl_death_recipient interface
122 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800123 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700124 // crashing system server process as described in go//treble-gnss-death
125 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
126 " restarting system server");
127 }
128};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700129
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800130// Must match the value from GnssMeasurement.java
131static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
132
gomo25208882017-04-15 02:05:25 -0700133sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800134sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800135sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700136sp<IGnssXtra> gnssXtraIface = nullptr;
137sp<IAGnssRil> agnssRilIface = nullptr;
138sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
139sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800140sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700141sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700142sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
143sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800145sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
146sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700147sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400149#define WAKE_LOCK_NAME "GPS"
150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151namespace android {
152
Lifu Tang120480f2016-02-07 18:08:19 -0800153template<class T>
154class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700155 public:
156 // Helper function to call setter on a Java object.
157 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800158 JNIEnv* env,
159 jclass clazz,
160 jobject object,
161 const char* method_name,
162 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700163
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700164 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800165 static const char *const signature_;
166};
Lifu Tange5a0e212016-01-25 18:02:17 -0800167
Lifu Tang120480f2016-02-07 18:08:19 -0800168template<class T>
169void JavaMethodHelper<T>::callJavaMethod(
170 JNIEnv* env,
171 jclass clazz,
172 jobject object,
173 const char* method_name,
174 T value) {
175 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
176 env->CallVoidMethod(object, method, value);
177}
destradaaea8a8a62014-06-23 18:19:03 -0700178
Lifu Tang120480f2016-02-07 18:08:19 -0800179class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700180 public:
181 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800182 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700183 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800184
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700185 template<class T>
186 void callSetter(const char* method_name, T value);
187 template<class T>
188 void callSetter(const char* method_name, T* value, size_t size);
189 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800190
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700191 private:
192 JNIEnv* env_;
193 jclass clazz_;
194 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800195};
196
197JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
198 clazz_ = env_->FindClass(class_name);
199 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
200 object_ = env_->NewObject(clazz_, ctor);
201}
202
Wyatt Rileycf879db2017-01-12 13:57:38 -0800203JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
204 clazz_ = env_->FindClass(class_name);
205 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
206 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
207}
208
Lifu Tang120480f2016-02-07 18:08:19 -0800209JavaObject::~JavaObject() {
210 env_->DeleteLocalRef(clazz_);
211}
212
213template<class T>
214void JavaObject::callSetter(const char* method_name, T value) {
215 JavaMethodHelper<T>::callJavaMethod(
216 env_, clazz_, object_, method_name, value);
217}
218
219template<>
220void JavaObject::callSetter(
221 const char* method_name, uint8_t* value, size_t size) {
222 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700223 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800224 jmethodID method = env_->GetMethodID(
225 clazz_,
226 method_name,
227 "([B)V");
228 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700229 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800230}
231
232jobject JavaObject::get() {
233 return object_;
234}
235
236// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800237template<>
238const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
239template<>
240const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
241template<>
242const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
243template<>
244const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
245template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800246const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
247template<>
248const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800249template<>
250const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
251template<>
252const char *const JavaMethodHelper<float>::signature_ = "(F)V";
253template<>
254const char *const JavaMethodHelper<double>::signature_ = "(D)V";
255template<>
256const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
257
258#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800259
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700260static inline jboolean boolToJbool(bool value) {
261 return value ? JNI_TRUE : JNI_FALSE;
262}
Lifu Tang120480f2016-02-07 18:08:19 -0800263
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700264static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
265 if (env->ExceptionCheck()) {
266 ALOGE("An exception was thrown by callback '%s'.", methodName);
267 LOGE_EX(env);
268 env->ExceptionClear();
269 }
270}
destradaaea8a8a62014-06-23 18:19:03 -0700271
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800272class ScopedJniThreadAttach {
273public:
274 ScopedJniThreadAttach() {
275 /*
276 * attachResult will also be JNI_OK if the thead was already attached to
277 * JNI before the call to AttachCurrentThread().
278 */
279 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
280 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
281 attachResult);
282 }
283
284 ~ScopedJniThreadAttach() {
285 jint detachResult = sJvm->DetachCurrentThread();
286 /*
287 * Return if the thread was already detached. Log error for any other
288 * failure.
289 */
290 if (detachResult == JNI_EDETACHED) {
291 return;
292 }
293
294 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
295 detachResult);
296 }
297
298 JNIEnv* getEnv() {
299 /*
300 * Checking validity of mEnv in case the thread was detached elsewhere.
301 */
302 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
303 return mEnv;
304 }
305
306private:
307 JNIEnv* mEnv = nullptr;
308};
309
310thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
311
312static JNIEnv* getJniEnv() {
313 JNIEnv* env = AndroidRuntime::getJNIEnv();
314
315 /*
316 * If env is nullptr, the thread is not already attached to
317 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
318 * will detach it on thread exit.
319 */
320 if (env == nullptr) {
321 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
322 env = tJniThreadAttacher->getEnv();
323 }
324
325 return env;
326}
327
Wyatt Rileyfb840922017-11-08 15:07:58 -0800328static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800329 JavaObject object(env, "android/location/Location", "gps");
330
331 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800332 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800333 SET(Latitude, location.latitudeDegrees);
334 SET(Longitude, location.longitudeDegrees);
335 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 SET(Altitude, location.altitudeMeters);
338 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800339 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800340 SET(Speed, location.speedMetersPerSec);
341 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800342 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800343 SET(Bearing, location.bearingDegrees);
344 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800345 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800346 SET(Accuracy, location.horizontalAccuracyMeters);
347 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800348 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800349 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
350 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800351 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800352 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
353 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800354 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800355 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
356 }
357 SET(Time, location.timestamp);
358
359 return object.get();
360}
361
Yu-Han Yange7baef32018-02-09 13:58:17 -0800362static GnssLocation createGnssLocation(
363 jint gnssLocationFlags,
364 jdouble latitudeDegrees,
365 jdouble longitudeDegrees,
366 jdouble altitudeMeters,
367 jfloat speedMetersPerSec,
368 jfloat bearingDegrees,
369 jfloat horizontalAccuracyMeters,
370 jfloat verticalAccuracyMeters,
371 jfloat speedAccuracyMetersPerSecond,
372 jfloat bearingAccuracyDegrees,
373 jlong timestamp) {
374 GnssLocation location;
375 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
376 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
377 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
378 location.altitudeMeters = static_cast<double>(altitudeMeters);
379 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
380 location.bearingDegrees = static_cast<float>(bearingDegrees);
381 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
382 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
383 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
384 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
385 location.timestamp = static_cast<uint64_t>(timestamp);
386
387 return location;
388}
389
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700390/*
391 * GnssCallback class implements the callback methods for IGnss interface.
392 */
393struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800394 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700395 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
396 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
397 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
398 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
399 Return<void> gnssAcquireWakelockCb() override;
400 Return<void> gnssReleaseWakelockCb() override;
401 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800402 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800404
Wyatt Rileyfb840922017-11-08 15:07:58 -0800405 // New in 1.1
406 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
407
Wyatt Riley26465d22018-02-12 13:44:24 -0800408 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700409 static const char* sNmeaString;
410 static size_t sNmeaStringLength;
411};
412
Wyatt Rileyfb840922017-11-08 15:07:58 -0800413Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
414 ALOGD("%s: name=%s\n", __func__, name.c_str());
415
Wyatt Rileyfb840922017-11-08 15:07:58 -0800416 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800417 jstring jstringName = env->NewStringUTF(name.c_str());
418 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800419 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800420
Wyatt Rileyfb840922017-11-08 15:07:58 -0800421 return Void();
422}
423
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700424const char* GnssCallback::sNmeaString = nullptr;
425size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700426
Wyatt Rileyfb840922017-11-08 15:07:58 -0800427Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800428 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800429
430 jobject jLocation = translateLocation(env, location);
431 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800432 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800433
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700434 env->CallVoidMethod(mCallbacksObj,
435 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800436 boolToJbool(hasLatLong),
437 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700438 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800439 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700440 return Void();
441}
442
443Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800444 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700445 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
446 checkAndClearExceptionFromCallback(env, __FUNCTION__);
447 return Void();
448}
449
450Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800451 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700452
Wyatt Riley26465d22018-02-12 13:44:24 -0800453 uint32_t listSize = svStatus.numSvs;
454 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700455 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800456 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700457 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800458 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800459 }
460
Wyatt Riley26465d22018-02-12 13:44:24 -0800461 jintArray svidWithFlagArray = env->NewIntArray(listSize);
462 jfloatArray cn0Array = env->NewFloatArray(listSize);
463 jfloatArray elevArray = env->NewFloatArray(listSize);
464 jfloatArray azimArray = env->NewFloatArray(listSize);
465 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
466
467 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
468 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
469 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
470 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
471 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
472
473 /*
474 * Read GNSS SV info.
475 */
476 for (size_t i = 0; i < listSize; ++i) {
477 enum ShiftWidth: uint8_t {
478 SVID_SHIFT_WIDTH = 8,
479 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
480 };
481
482 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
483 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
484 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
485 static_cast<uint32_t>(info.svFlag);
486 cn0s[i] = info.cN0Dbhz;
487 elev[i] = info.elevationDegrees;
488 azim[i] = info.azimuthDegrees;
489 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800490 }
destradaaea8a8a62014-06-23 18:19:03 -0700491
Wyatt Riley26465d22018-02-12 13:44:24 -0800492 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
493 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
494 env->ReleaseFloatArrayElements(elevArray, elev, 0);
495 env->ReleaseFloatArrayElements(azimArray, azim, 0);
496 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
497
498 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
499 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
500 carrierFreqArray);
501
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700502 checkAndClearExceptionFromCallback(env, __FUNCTION__);
503 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700504}
505
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700506Return<void> GnssCallback::gnssNmeaCb(
507 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800508 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700509 /*
510 * The Java code will call back to read these values.
511 * We do this to avoid creating unnecessary String objects.
512 */
513 sNmeaString = nmea.c_str();
514 sNmeaStringLength = nmea.size();
515
516 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
517 checkAndClearExceptionFromCallback(env, __FUNCTION__);
518 return Void();
519}
520
521Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
522 ALOGD("%s: %du\n", __func__, capabilities);
523
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800524 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700525 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
526 checkAndClearExceptionFromCallback(env, __FUNCTION__);
527 return Void();
528}
529
530Return<void> GnssCallback::gnssAcquireWakelockCb() {
531 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
532 return Void();
533}
534
535Return<void> GnssCallback::gnssReleaseWakelockCb() {
536 release_wake_lock(WAKE_LOCK_NAME);
537 return Void();
538}
539
540Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800541 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700542 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
543 checkAndClearExceptionFromCallback(env, __FUNCTION__);
544 return Void();
545}
546
Yu-Han Yang21988932018-01-23 15:07:37 -0800547Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800548 JNIEnv* env = getJniEnv();
549 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
550 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800551 return Void();
552}
553
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700554Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
555 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
556
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800557 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700558 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
559 info.yearOfHw);
560 checkAndClearExceptionFromCallback(env, __FUNCTION__);
561 return Void();
562}
563
564class GnssXtraCallback : public IGnssXtraCallback {
565 Return<void> downloadRequestCb() override;
566};
567
568/*
569 * GnssXtraCallback class implements the callback methods for the IGnssXtra
570 * interface.
571 */
572Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800573 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700574 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
575 checkAndClearExceptionFromCallback(env, __FUNCTION__);
576 return Void();
577}
578
579/*
580 * GnssGeofenceCallback class implements the callback methods for the
581 * IGnssGeofence interface.
582 */
583struct GnssGeofenceCallback : public IGnssGeofenceCallback {
584 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
585 Return<void> gnssGeofenceTransitionCb(
586 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800587 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700588 GeofenceTransition transition,
589 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
590 Return<void> gnssGeofenceStatusCb(
591 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800592 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700593 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
594 GeofenceStatus status) override;
595 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
596 GeofenceStatus status) override;
597 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
598 GeofenceStatus status) override;
599 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
600 GeofenceStatus status) override;
601};
602
603Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
604 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800605 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700606 GeofenceTransition transition,
607 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800608 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700609
Wyatt Riley5d229832017-02-10 17:06:00 -0800610 jobject jLocation = translateLocation(env, location);
611
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700612 env->CallVoidMethod(mCallbacksObj,
613 method_reportGeofenceTransition,
614 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800615 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700616 transition,
617 timestamp);
618
619 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800620 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700621 return Void();
622}
623
624Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
625 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800626 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800627 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800628
629 jobject jLocation = translateLocation(env, location);
630
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700631 env->CallVoidMethod(mCallbacksObj,
632 method_reportGeofenceStatus,
633 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800634 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700635 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800636 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700637 return Void();
638}
639
640Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
641 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800642 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700643 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
644 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
645 }
646
647 env->CallVoidMethod(mCallbacksObj,
648 method_reportGeofenceAddStatus,
649 geofenceId,
650 status);
651 checkAndClearExceptionFromCallback(env, __FUNCTION__);
652 return Void();
653}
654
655Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
656 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800657 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700658 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
659 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
660 }
661
662 env->CallVoidMethod(mCallbacksObj,
663 method_reportGeofenceRemoveStatus,
664 geofenceId, status);
665 checkAndClearExceptionFromCallback(env, __FUNCTION__);
666 return Void();
667}
668
669Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
670 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800671 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700672 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
673 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
674 }
675
676 env->CallVoidMethod(mCallbacksObj,
677 method_reportGeofencePauseStatus,
678 geofenceId, status);
679 checkAndClearExceptionFromCallback(env, __FUNCTION__);
680 return Void();
681}
682
683Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
684 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800685 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700686 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
687 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
688 }
689
690 env->CallVoidMethod(mCallbacksObj,
691 method_reportGeofenceResumeStatus,
692 geofenceId, status);
693 checkAndClearExceptionFromCallback(env, __FUNCTION__);
694 return Void();
695}
696
697/*
698 * GnssNavigationMessageCallback interface implements the callback methods
699 * required by the IGnssNavigationMessage interface.
700 */
701struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
702 /*
703 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
704 * follow.
705 */
706 Return<void> gnssNavigationMessageCb(
707 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
708};
709
710Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
711 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800712 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700713
714 size_t dataLength = message.data.size();
715
716 std::vector<uint8_t> navigationData = message.data;
717 uint8_t* data = &(navigationData[0]);
718 if (dataLength == 0 || data == NULL) {
719 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
720 dataLength);
721 return Void();
722 }
723
724 JavaObject object(env, "android/location/GnssNavigationMessage");
725 SET(Type, static_cast<int32_t>(message.type));
726 SET(Svid, static_cast<int32_t>(message.svid));
727 SET(MessageId, static_cast<int32_t>(message.messageId));
728 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
729 object.callSetter("setData", data, dataLength);
730 SET(Status, static_cast<int32_t>(message.status));
731
732 jobject navigationMessage = object.get();
733 env->CallVoidMethod(mCallbacksObj,
734 method_reportNavigationMessages,
735 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800736 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700737 env->DeleteLocalRef(navigationMessage);
738 return Void();
739}
740
741/*
742 * GnssMeasurementCallback implements the callback methods required for the
743 * GnssMeasurement interface.
744 */
Wyatt Riley46ac9562018-03-02 20:16:58 -0800745struct GnssMeasurementCallback : public IGnssMeasurementCallback_V1_1 {
746 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800747 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700748 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800749 void translateGnssMeasurement_V1_0(
750 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800751 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700752 jobjectArray translateGnssMeasurements(
753 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800754 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800755 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700756 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800757 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800758 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700759 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
760};
761
762
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800763Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800764 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800765 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700766
767 jobject clock;
768 jobjectArray measurementArray;
769
770 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800771
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700772 measurementArray = translateGnssMeasurements(
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800773 env, data.measurements.data(), NULL, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700774 setMeasurementData(env, clock, measurementArray);
775
776 env->DeleteLocalRef(clock);
777 env->DeleteLocalRef(measurementArray);
778 return Void();
779}
780
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800781Return<void> GnssMeasurementCallback::GnssMeasurementCb(
782 const IGnssMeasurementCallback_V1_0::GnssData& data) {
783 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800784
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800785 jobject clock;
786 jobjectArray measurementArray;
787
788 clock = translateGnssClock(env, &data.clock);
789 measurementArray = translateGnssMeasurements(
790 env, NULL, data.measurements.data(), data.measurementCount);
791 setMeasurementData(env, clock, measurementArray);
792
793 env->DeleteLocalRef(clock);
794 env->DeleteLocalRef(measurementArray);
795 return Void();
796}
797
798// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
799void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
800 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800801 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700802 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700803
804 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800805 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700806 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800807 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700808 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800809 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700810 measurement->receivedSvTimeUncertaintyInNs);
811 SET(Cn0DbHz, measurement->cN0DbHz);
812 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800813 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700814 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800815 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800816 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
817 !ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700818 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800819 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700820 measurement->accumulatedDeltaRangeUncertaintyM);
821
822 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
823 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
824 }
825
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800826 // Intentionally not copying deprecated fields of carrierCycles,
827 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700828
829 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
830
831 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
832 SET(SnrInDb, measurement->snrDb);
833 }
Lifu Tang120480f2016-02-07 18:08:19 -0800834
gomo4402af62017-01-11 13:20:13 -0800835 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800836 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800837 }
Lifu Tang120480f2016-02-07 18:08:19 -0800838}
839
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700840jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800841 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700842 JavaObject object(env, "android/location/GnssClock");
843
844 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
845 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
846 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
847 }
848
849 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
850 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
851 }
852
853 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
854 SET(FullBiasNanos, clock->fullBiasNs);
855 }
856
857 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
858 SET(BiasNanos, clock->biasNs);
859 }
860
861 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
862 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
863 }
864
865 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
866 SET(DriftNanosPerSecond, clock->driftNsps);
867 }
868
869 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
870 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
871 }
872
873 SET(TimeNanos, clock->timeNs);
874 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
875
876 return object.get();
877}
878
879jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800880 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800881 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
882 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800883 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700884 return NULL;
885 }
886
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700887 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800888 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800889 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800890 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700891 NULL /* initialElement */);
892
Lifu Tang120480f2016-02-07 18:08:19 -0800893 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800894 JavaObject object(env, "android/location/GnssMeasurement");
Wyatt Riley46ac9562018-03-02 20:16:58 -0800895 if (measurements_v1_1 != NULL) {
896 translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800897
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800898 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800899 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800900 (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
901 ADR_STATE_HALF_CYCLE_REPORTED));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800902 } else {
903 translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
904 }
905
906 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700907 }
908
Lifu Tang818aa2c2016-02-01 01:52:00 -0800909 env->DeleteLocalRef(gnssMeasurementClass);
910 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700911}
912
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700913void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
914 jobjectArray measurementArray) {
915 jclass gnssMeasurementsEventClass =
916 env->FindClass("android/location/GnssMeasurementsEvent");
917 jmethodID gnssMeasurementsEventCtor =
918 env->GetMethodID(
919 gnssMeasurementsEventClass,
920 "<init>",
921 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800922
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700923 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
924 gnssMeasurementsEventCtor,
925 clock,
926 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800927
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700928 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
929 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800930 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800931 env->DeleteLocalRef(gnssMeasurementsEventClass);
932 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700933}
934
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700935/*
936 * GnssNiCallback implements callback methods required by the IGnssNi interface.
937 */
938struct GnssNiCallback : public IGnssNiCallback {
939 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
940 override;
destradaaea8a8a62014-06-23 18:19:03 -0700941};
942
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943Return<void> GnssNiCallback::niNotifyCb(
944 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800945 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700946 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
947 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
948
949 if (requestorId && text) {
950 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
951 notification.notificationId, notification.niType,
952 notification.notifyFlags, notification.timeoutSec,
953 notification.defaultResponse, requestorId, text,
954 notification.requestorIdEncoding,
955 notification.notificationIdEncoding);
956 } else {
957 ALOGE("%s: OOM Error\n", __func__);
958 }
959
960 if (requestorId) {
961 env->DeleteLocalRef(requestorId);
962 }
963
964 if (text) {
965 env->DeleteLocalRef(text);
966 }
967 checkAndClearExceptionFromCallback(env, __FUNCTION__);
968 return Void();
969}
970
971/*
972 * AGnssCallback implements callback methods required by the IAGnss interface.
973 */
974struct AGnssCallback : public IAGnssCallback {
975 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
976 Return<void> agnssStatusIpV6Cb(
977 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
978
979 Return<void> agnssStatusIpV4Cb(
980 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
981 private:
982 jbyteArray convertToIpV4(uint32_t ip);
983};
984
985Return<void> AGnssCallback::agnssStatusIpV6Cb(
986 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800987 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700988 jbyteArray byteArray = NULL;
989 bool isSupported = false;
990
991 byteArray = env->NewByteArray(16);
992 if (byteArray != NULL) {
993 env->SetByteArrayRegion(byteArray, 0, 16,
994 (const jbyte*)(agps_status.ipV6Addr.data()));
995 isSupported = true;
996 } 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
1007 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1008 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();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001024 jbyteArray byteArray = NULL;
1025
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 =
1040 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1041 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) {
1055 return NULL;
1056 }
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);
1060 if (byteArray == NULL) {
1061 ALOGE("Unable to allocate byte array for IPv4 address");
1062 return NULL;
1063 }
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");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001180
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001181 /*
1182 * Save a pointer to JVM.
1183 */
1184 jint jvmStatus = env->GetJavaVM(&sJvm);
1185 if (jvmStatus != JNI_OK) {
1186 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1187 }
1188
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001189 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001190 gnssHalDeathRecipient = new GnssDeathRecipient();
1191 hardware::Return<bool> linked = gnssHal->linkToDeath(
1192 gnssHalDeathRecipient, /*cookie*/ 0);
1193 if (!linked.isOk()) {
1194 ALOGE("Transaction error in linking to GnssHAL death: %s",
1195 linked.description().c_str());
1196 } else if (!linked) {
1197 ALOGW("Unable to link to GnssHal death notifications");
1198 } else {
1199 ALOGD("Link to death notification successful");
1200 }
1201
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001202 auto gnssXtra = gnssHal->getExtensionXtra();
1203 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001204 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001205 } else {
1206 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001207 }
1208
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001209 auto gnssRil = gnssHal->getExtensionAGnssRil();
1210 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001211 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001212 } else {
1213 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001214 }
1215
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001216 auto gnssAgnss = gnssHal->getExtensionAGnss();
1217 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001218 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001219 } else {
1220 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001221 }
1222
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001223 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1224 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001225 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001226 } else {
1227 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001228 }
1229
gomo48f1a642017-11-10 20:35:46 -08001230 if (gnssHal_V1_1 != nullptr) {
1231 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1232 if (!gnssMeasurement.isOk()) {
1233 ALOGD("Unable to get a handle to GnssMeasurement");
1234 } else {
1235 gnssMeasurementIface_V1_1 = gnssMeasurement;
1236 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1237 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001238 } else {
gomo48f1a642017-11-10 20:35:46 -08001239 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1240 if (!gnssMeasurement_V1_0.isOk()) {
1241 ALOGD("Unable to get a handle to GnssMeasurement");
1242 } else {
1243 gnssMeasurementIface = gnssMeasurement_V1_0;
1244 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001245 }
1246
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001247 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1248 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001249 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001250 } else {
1251 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001252 }
1253
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001254 auto gnssNi = gnssHal->getExtensionGnssNi();
1255 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001256 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001257 } else {
1258 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001259 }
1260
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001261 if (gnssHal_V1_1 != nullptr) {
1262 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1263 if (!gnssConfiguration.isOk()) {
1264 ALOGD("Unable to get a handle to GnssConfiguration");
1265 } else {
1266 gnssConfigurationIface_V1_1 = gnssConfiguration;
1267 gnssConfigurationIface = gnssConfigurationIface_V1_1;
1268 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001269 } else {
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001270 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1271 if (!gnssConfiguration_V1_0.isOk()) {
1272 ALOGD("Unable to get a handle to GnssConfiguration");
1273 } else {
1274 gnssConfigurationIface = gnssConfiguration_V1_0;
1275 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001276 }
1277
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001278 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1279 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001280 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001281 } else {
1282 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001283 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001284
1285 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1286 if (!gnssBatching.isOk()) {
1287 ALOGD("Unable to get a handle to gnssBatching");
1288 } else {
1289 gnssBatchingIface = gnssBatching;
1290 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001291 } else {
1292 ALOGE("Unable to get GPS service\n");
1293 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001294}
1295
1296static jboolean android_location_GnssLocationProvider_is_supported(
1297 JNIEnv* /* env */, jclass /* clazz */) {
1298 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1299}
1300
1301static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1302 JNIEnv* /* env */, jclass /* clazz */) {
1303 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1304}
1305
1306static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1307 JNIEnv* /* env */, jclass /* jclazz */) {
1308 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1309}
1310
1311static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1312 /*
1313 * This must be set before calling into the HAL library.
1314 */
1315 if (!mCallbacksObj)
1316 mCallbacksObj = env->NewGlobalRef(obj);
1317
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001318 /*
1319 * Fail if the main interface fails to initialize
1320 */
1321 if (gnssHal == nullptr) {
1322 ALOGE("Unable to Initialize GNSS HAL\n");
1323 return JNI_FALSE;
1324 }
1325
Wyatt Rileyfb840922017-11-08 15:07:58 -08001326 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1327
1328 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001329 if (gnssHal_V1_1 != nullptr) {
1330 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001331 } else {
1332 result = gnssHal->setCallback(gnssCbIface);
1333 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001334 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001335 ALOGE("SetCallback for Gnss Interface fails\n");
1336 return JNI_FALSE;
1337 }
1338
1339 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1340 if (gnssXtraIface == nullptr) {
1341 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001342 } else {
1343 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001344 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001345 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001346 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001347 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001348 }
1349
1350 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1351 if (agnssIface != nullptr) {
1352 agnssIface->setCallback(aGnssCbIface);
1353 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001354 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001355 }
1356
1357 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1358 if (gnssGeofencingIface != nullptr) {
1359 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1360 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001361 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001362 }
1363
1364 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001365 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001366 gnssNiIface->setCallback(gnssNiCbIface);
1367 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001368 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001369 }
1370
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001371 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1372 if (agnssRilIface != nullptr) {
1373 agnssRilIface->setCallback(aGnssRilCbIface);
1374 } else {
1375 ALOGI("Unable to Initialize AGnss Ril interface\n");
1376 }
1377
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001378 return JNI_TRUE;
1379}
1380
1381static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1382 if (gnssHal != nullptr) {
1383 gnssHal->cleanup();
1384 }
1385}
1386
1387static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1388 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001389 jint preferred_time, jboolean low_power_mode) {
1390 Return<bool> result = false;
1391 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001392 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1393 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1394 min_interval,
1395 preferred_accuracy,
1396 preferred_time,
1397 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001398 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001399 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1400 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1401 min_interval,
1402 preferred_accuracy,
1403 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001404 }
1405 if (!result.isOk()) {
1406 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1407 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001408 } else {
gomo48f1a642017-11-10 20:35:46 -08001409 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001410 }
1411}
1412
1413static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1414 if (gnssHal != nullptr) {
1415 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001416 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001417 return JNI_FALSE;
1418 } else {
1419 return result;
1420 }
1421 } else {
1422 return JNI_FALSE;
1423 }
1424}
1425
1426static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1427 if (gnssHal != nullptr) {
1428 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001429 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001430 return JNI_FALSE;
1431 } else {
1432 return result;
1433 }
1434 } else {
1435 return JNI_FALSE;
1436 }
1437}
1438static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1439 jobject /* obj */,
1440 jint flags) {
1441 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001442 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001443 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001444 ALOGE("Error in deleting aiding data");
1445 }
1446 }
1447}
1448
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001449static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1450 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1451 IAGnssRil::AGnssRefLocation location;
1452
1453 if (agnssRilIface == nullptr) {
1454 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1455 return;
1456 }
1457
1458 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1459 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1460 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1461 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1462 location.cellID.mcc = mcc;
1463 location.cellID.mnc = mnc;
1464 location.cellID.lac = lac;
1465 location.cellID.cid = cid;
1466 break;
1467 default:
1468 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1469 return;
1470 break;
1471 }
1472
1473 agnssRilIface->setRefLocation(location);
1474}
1475
1476static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1477 jint type, jstring setid_string) {
1478 if (agnssRilIface == nullptr) {
1479 ALOGE("no AGPS RIL interface in agps_set_id");
1480 return;
1481 }
1482
1483 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1484 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1485 env->ReleaseStringUTFChars(setid_string, setid);
1486}
1487
1488static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1489 jbyteArray nmeaArray, jint buffer_size) {
1490 // this should only be called from within a call to reportNmea
1491 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1492 int length = GnssCallback::sNmeaStringLength;
1493 if (length > buffer_size)
1494 length = buffer_size;
1495 memcpy(nmea, GnssCallback::sNmeaString, length);
1496 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1497 return (jint) length;
1498}
1499
1500static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1501 jlong time, jlong timeReference, jint uncertainty) {
1502 if (gnssHal != nullptr) {
1503 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001504 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001505 ALOGE("%s: Gnss injectTime() failed", __func__);
1506 }
1507 }
1508}
1509
Yu-Han Yange7baef32018-02-09 13:58:17 -08001510static void android_location_GnssLocationProvider_inject_best_location(
1511 JNIEnv*,
1512 jobject,
1513 jint gnssLocationFlags,
1514 jdouble latitudeDegrees,
1515 jdouble longitudeDegrees,
1516 jdouble altitudeMeters,
1517 jfloat speedMetersPerSec,
1518 jfloat bearingDegrees,
1519 jfloat horizontalAccuracyMeters,
1520 jfloat verticalAccuracyMeters,
1521 jfloat speedAccuracyMetersPerSecond,
1522 jfloat bearingAccuracyDegrees,
1523 jlong timestamp) {
1524 if (gnssHal_V1_1 != nullptr) {
1525 GnssLocation location = createGnssLocation(
1526 gnssLocationFlags,
1527 latitudeDegrees,
1528 longitudeDegrees,
1529 altitudeMeters,
1530 speedMetersPerSec,
1531 bearingDegrees,
1532 horizontalAccuracyMeters,
1533 verticalAccuracyMeters,
1534 speedAccuracyMetersPerSecond,
1535 bearingAccuracyDegrees,
1536 timestamp);
1537 auto result = gnssHal_V1_1->injectBestLocation(location);
1538 if (!result.isOk() || !result) {
1539 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1540 }
1541 } else {
1542 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1543 }
1544}
1545
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001546static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1547 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1548 if (gnssHal != nullptr) {
1549 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001550 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001551 ALOGE("%s: Gnss injectLocation() failed", __func__);
1552 }
1553 }
1554}
1555
1556static jboolean android_location_GnssLocationProvider_supports_xtra(
1557 JNIEnv* /* env */, jobject /* obj */) {
1558 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1559}
1560
1561static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1562 jbyteArray data, jint length) {
1563 if (gnssXtraIface == nullptr) {
1564 ALOGE("XTRA Interface not supported");
1565 return;
1566 }
1567
1568 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1569 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1570 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1571}
1572
1573static void android_location_GnssLocationProvider_agps_data_conn_open(
1574 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1575 if (agnssIface == nullptr) {
1576 ALOGE("no AGPS interface in agps_data_conn_open");
1577 return;
1578 }
1579 if (apn == NULL) {
1580 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1581 return;
1582 }
1583
1584 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1585
1586 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001587 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001588 ALOGE("%s: Failed to set APN and its IP type", __func__);
1589 }
1590 env->ReleaseStringUTFChars(apn, apnStr);
1591}
1592
1593static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1594 jobject /* obj */) {
1595 if (agnssIface == nullptr) {
1596 ALOGE("%s: AGPS interface not supported", __func__);
1597 return;
1598 }
1599
1600 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001601 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001602 ALOGE("%s: Failed to close AGnss data connection", __func__);
1603 }
1604}
1605
1606static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1607 jobject /* obj */) {
1608 if (agnssIface == nullptr) {
1609 ALOGE("%s: AGPS interface not supported", __func__);
1610 return;
1611 }
1612
1613 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001614 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001615 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1616 }
1617}
1618
1619static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1620 jint type, jstring hostname, jint port) {
1621 if (agnssIface == nullptr) {
1622 ALOGE("no AGPS interface in set_agps_server");
1623 return;
1624 }
1625
1626 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1627 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1628 c_hostname,
1629 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001630 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001631 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1632 }
1633
1634 env->ReleaseStringUTFChars(hostname, c_hostname);
1635}
1636
1637static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1638 jobject /* obj */, jint notifId, jint response) {
1639 if (gnssNiIface == nullptr) {
1640 ALOGE("no NI interface in send_ni_response");
1641 return;
1642 }
1643
1644 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1645}
1646
1647static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1648 jobject /* obj */) {
1649 jstring result = NULL;
1650 /*
1651 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1652 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001653
1654 std::stringstream internalState;
1655
1656 if (gnssDebugIface == nullptr) {
1657 internalState << "Gnss Debug Interface not available" << std::endl;
1658 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001659 IGnssDebug::DebugData data;
1660 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1661 data = debugData;
1662 });
1663
Wyatt Riley268c6e02017-03-29 10:21:46 -07001664 internalState << "Gnss Location Data:: ";
1665 if (!data.position.valid) {
1666 internalState << "not valid";
1667 } else {
1668 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001669 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1670 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001671 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1672 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001673 << ", horizontalAccuracyMeters: "
1674 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001675 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001676 << ", speedAccuracyMetersPerSecond: "
1677 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001678 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001679 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001681 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001682
Wyatt Riley268c6e02017-03-29 10:21:46 -07001683 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1684 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1685 << ", frequencyUncertaintyNsPerSec: "
1686 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001687
1688 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001689 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1690 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001691 }
1692
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001693 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1694 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1695 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1696 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001697 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1698 internalState << "svid: " << data.satelliteDataArray[i].svid
1699 << ", constellation: "
1700 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1701 << ", ephemerisType: "
1702 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001703 << ", ephemerisSource: "
1704 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1705 << ", ephemerisHealth: "
1706 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1707 << ", serverPredictionIsAvailable: "
1708 << data.satelliteDataArray[i].serverPredictionIsAvailable
1709 << ", serverPredictionAgeSeconds: "
1710 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001711 << ", ephemerisAgeSeconds: "
1712 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1713 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001714 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001715
1716 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 return result;
1718}
1719
1720static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1721 jobject /* obj */,
1722 jboolean connected,
1723 jint type,
1724 jboolean roaming,
1725 jboolean available,
1726 jstring extraInfo,
1727 jstring apn) {
1728 if (agnssRilIface != nullptr) {
1729 auto result = agnssRilIface->updateNetworkState(connected,
1730 static_cast<IAGnssRil::NetworkType>(type),
1731 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001732 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001733 ALOGE("updateNetworkState failed");
1734 }
1735
1736 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1737 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001738 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001739 ALOGE("updateNetworkAvailability failed");
1740 }
1741
1742 env->ReleaseStringUTFChars(apn, c_apn);
1743 } else {
1744 ALOGE("AGnssRilInterface does not exist");
1745 }
1746}
1747
1748static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1749 JNIEnv* /* env */, jobject /* obj */) {
1750 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1751}
1752
1753static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1754 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1755 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1756 jint unknown_timer) {
1757 if (gnssGeofencingIface != nullptr) {
1758 auto result = gnssGeofencingIface->addGeofence(
1759 geofenceId, latitude, longitude, radius,
1760 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1761 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001762 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001763 } else {
1764 ALOGE("Geofence Interface not available");
1765 }
1766 return JNI_FALSE;
1767}
1768
1769static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1770 jobject /* obj */, jint geofenceId) {
1771 if (gnssGeofencingIface != nullptr) {
1772 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001773 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001774 } else {
1775 ALOGE("Geofence interface not available");
1776 }
1777 return JNI_FALSE;
1778}
1779
1780static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1781 jobject /* obj */, jint geofenceId) {
1782 if (gnssGeofencingIface != nullptr) {
1783 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001784 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001785 } else {
1786 ALOGE("Geofence interface not available");
1787 }
1788 return JNI_FALSE;
1789}
1790
1791static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1792 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1793 if (gnssGeofencingIface != nullptr) {
1794 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001795 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001796 } else {
1797 ALOGE("Geofence interface not available");
1798 }
1799 return JNI_FALSE;
1800}
1801
Lifu Tang30f95a72016-01-07 23:20:38 -08001802static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 JNIEnv* env, jclass clazz) {
1804 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001805 return JNI_TRUE;
1806 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001807
destradaaea8a8a62014-06-23 18:19:03 -07001808 return JNI_FALSE;
1809}
1810
Lifu Tang30f95a72016-01-07 23:20:38 -08001811static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001812 JNIEnv* /* env */,
1813 jobject /* obj */,
1814 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001815 if (gnssMeasurementIface == nullptr) {
1816 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001817 return JNI_FALSE;
1818 }
1819
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001820 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001821 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1822 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1823 if (gnssMeasurementIface_V1_1 != nullptr) {
1824 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1825 enableFullTracking);
1826 } else {
1827 if (enableFullTracking == JNI_TRUE) {
1828 // full tracking mode not supported in 1.0 HAL
1829 return JNI_FALSE;
1830 }
1831 result = gnssMeasurementIface->setCallback(cbIface);
1832 }
1833
1834 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001835 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1836 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001837 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001838 } else {
1839 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001840 }
1841
1842 return JNI_TRUE;
1843}
1844
Lifu Tang30f95a72016-01-07 23:20:38 -08001845static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001846 JNIEnv* env,
1847 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001848 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001849 ALOGE("Measurement interface not available");
1850 return JNI_FALSE;
1851 }
1852
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001853 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001854 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001855}
1856
Lifu Tang30f95a72016-01-07 23:20:38 -08001857static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001858 JNIEnv* env,
1859 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001860 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001861 return JNI_TRUE;
1862 }
1863 return JNI_FALSE;
1864}
1865
Lifu Tang30f95a72016-01-07 23:20:38 -08001866static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001867 JNIEnv* env,
1868 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001869 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001870 ALOGE("Navigation Message interface is not available.");
1871 return JNI_FALSE;
1872 }
1873
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001874 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1875 new GnssNavigationMessageCallback();
1876 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1877 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1878
1879 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1880 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001881 return JNI_FALSE;
1882 }
1883
1884 return JNI_TRUE;
1885}
1886
Lifu Tang30f95a72016-01-07 23:20:38 -08001887static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001888 JNIEnv* env,
1889 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001890 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001891 ALOGE("Navigation Message interface is not available.");
1892 return JNI_FALSE;
1893 }
1894
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001895 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001896 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001897}
1898
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001899static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1900 jobject,
1901 jint emergencySuplPdn) {
1902 if (gnssConfigurationIface == nullptr) {
1903 ALOGE("no GNSS configuration interface available");
1904 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001905 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001906
1907 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001908 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001909 return result;
1910 } else {
1911 return JNI_FALSE;
1912 }
1913}
1914
1915static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1916 jobject,
1917 jint version) {
1918 if (gnssConfigurationIface == nullptr) {
1919 ALOGE("no GNSS configuration interface available");
1920 return JNI_FALSE;
1921 }
1922 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001923 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001924 return result;
1925 } else {
1926 return JNI_FALSE;
1927 }
1928}
1929
1930static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1931 jobject,
1932 jint suplEs) {
1933 if (gnssConfigurationIface == nullptr) {
1934 ALOGE("no GNSS configuration interface available");
1935 return JNI_FALSE;
1936 }
1937
1938 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001939 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001940 return result;
1941 } else {
1942 return JNI_FALSE;
1943 }
1944}
1945
1946static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1947 jobject,
1948 jint mode) {
1949 if (gnssConfigurationIface == nullptr) {
1950 ALOGE("no GNSS configuration interface available");
1951 return JNI_FALSE;
1952 }
1953
1954 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001955 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001956 return result;
1957 } else {
1958 return JNI_FALSE;
1959 }
1960}
1961
1962static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1963 jobject,
1964 jint gpsLock) {
1965 if (gnssConfigurationIface == nullptr) {
1966 ALOGE("no GNSS configuration interface available");
1967 return JNI_FALSE;
1968 }
1969
1970 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001971 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001972 return result;
1973 } else {
1974 return JNI_FALSE;
1975 }
1976}
1977
1978static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1979 jobject,
1980 jint lppProfile) {
1981 if (gnssConfigurationIface == nullptr) {
1982 ALOGE("no GNSS configuration interface available");
1983 return JNI_FALSE;
1984 }
1985
1986 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1987
Steven Morelandd002a8b2017-01-03 17:18:24 -08001988 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001989 return result;
1990 } else {
1991 return JNI_FALSE;
1992 }
1993}
1994
1995static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1996 jobject,
1997 jint gnssPosProtocol) {
1998 if (gnssConfigurationIface == nullptr) {
1999 ALOGE("no GNSS configuration interface available");
2000 return JNI_FALSE;
2001 }
2002
2003 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002004 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002005 return result;
2006 } else {
2007 return JNI_FALSE;
2008 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002009}
2010
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002011static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
2012 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2013 if (gnssConfigurationIface_V1_1 == nullptr) {
2014 ALOGI("No GNSS Satellite Blacklist interface available");
2015 return JNI_FALSE;
2016 }
2017
2018 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
2019 if (NULL == constellation_array) {
2020 ALOGI("GetIntArrayElements returns NULL.");
2021 return JNI_FALSE;
2022 }
2023 jsize length = env->GetArrayLength(constellations);
2024
2025 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
2026 if (NULL == sv_id_array) {
2027 ALOGI("GetIntArrayElements returns NULL.");
2028 return JNI_FALSE;
2029 }
2030
2031 if (length != env->GetArrayLength(sv_ids)) {
2032 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2033 return JNI_FALSE;
2034 }
2035
2036 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2037 sources.resize(length);
2038
2039 for (int i = 0; i < length; i++) {
2040 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2041 sources[i].svid = sv_id_array[i];
2042 }
2043
2044 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2045 if (result.isOk()) {
2046 return result;
2047 } else {
2048 return JNI_FALSE;
2049 }
2050}
2051
2052
Wyatt Rileycf879db2017-01-12 13:57:38 -08002053static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
2054 if (gnssBatchingIface == nullptr) {
2055 return 0; // batching not supported, size = 0
2056 }
2057 auto result = gnssBatchingIface->getBatchSize();
2058 if (result.isOk()) {
2059 return static_cast<jint>(result);
2060 } else {
2061 return 0; // failure in binder, don't support batching
2062 }
2063}
2064
2065static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
2066 if (gnssBatchingIface == nullptr) {
2067 return JNI_FALSE; // batching not supported
2068 }
2069 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2070
2071 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2072}
2073
2074static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
2075 if (gnssBatchingIface == nullptr) {
2076 return; // batching not supported
2077 }
2078 gnssBatchingIface->cleanup();
2079}
2080
2081static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
2082 jlong periodNanos, jboolean wakeOnFifoFull) {
2083 if (gnssBatchingIface == nullptr) {
2084 return JNI_FALSE; // batching not supported
2085 }
2086
2087 IGnssBatching::Options options;
2088 options.periodNanos = periodNanos;
2089 if (wakeOnFifoFull) {
2090 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2091 } else {
2092 options.flags = 0;
2093 }
2094
2095 return static_cast<jboolean>(gnssBatchingIface->start(options));
2096}
2097
2098static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
2099 if (gnssBatchingIface == nullptr) {
2100 return; // batching not supported
2101 }
2102
2103 gnssBatchingIface->flush();
2104}
2105
2106static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
2107 if (gnssBatchingIface == nullptr) {
2108 return JNI_FALSE; // batching not supported
2109 }
2110
2111 return gnssBatchingIface->stop();
2112}
2113
Daniel Micay76f6a862015-09-19 17:31:01 -04002114static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002115 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002116 {"class_init_native", "()V", reinterpret_cast<void *>(
2117 android_location_GnssLocationProvider_class_init_native)},
2118 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2119 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002120 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002121 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002122 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002123 reinterpret_cast<void *>(
2124 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002125 {"native_init_once", "()V", reinterpret_cast<void *>(
2126 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002127 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2128 {"native_cleanup", "()V", reinterpret_cast<void *>(
2129 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002130 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002131 "(IIIIIZ)Z",
2132 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002133 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2134 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002135 {"native_delete_aiding_data",
2136 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002137 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002138 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2139 android_location_GnssLocationProvider_read_nmea)},
2140 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2141 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002142 {"native_inject_best_location",
2143 "(IDDDFFFFFFJ)V",
2144 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002145 {"native_inject_location",
2146 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002147 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2148 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2149 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002150 {"native_inject_xtra_data",
2151 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002152 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002153 {"native_agps_data_conn_open",
2154 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002155 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002156 {"native_agps_data_conn_closed",
2157 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002158 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002159 {"native_agps_data_conn_failed",
2160 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002161 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002162 {"native_agps_set_id",
2163 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002164 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002165 {"native_agps_set_ref_location_cellid",
2166 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002167 reinterpret_cast<void *>(
2168 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002169 {"native_set_agps_server",
2170 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002171 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002172 {"native_send_ni_response",
2173 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002174 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002175 {"native_get_internal_state",
2176 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002177 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002178 {"native_update_network_state",
2179 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002180 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002181 {"native_is_geofence_supported",
2182 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002183 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002184 {"native_add_geofence",
2185 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002186 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002187 {"native_remove_geofence",
2188 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002189 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2190 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2191 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002192 {"native_resume_geofence",
2193 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002194 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002195 {"native_is_measurement_supported",
2196 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002197 reinterpret_cast<void *>(
2198 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002199 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002200 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002201 reinterpret_cast<void *>(
2202 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002203 {"native_stop_measurement_collection",
2204 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002205 reinterpret_cast<void *>(
2206 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002207 {"native_is_navigation_message_supported",
2208 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002209 reinterpret_cast<void *>(
2210 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002211 {"native_start_navigation_message_collection",
2212 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002213 reinterpret_cast<void *>(
2214 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002215 {"native_stop_navigation_message_collection",
2216 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002217 reinterpret_cast<void *>(
2218 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2219 {"native_set_supl_es",
2220 "(I)Z",
2221 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2222 {"native_set_supl_version",
2223 "(I)Z",
2224 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2225 {"native_set_supl_mode",
2226 "(I)Z",
2227 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2228 {"native_set_lpp_profile",
2229 "(I)Z",
2230 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2231 {"native_set_gnss_pos_protocol_select",
2232 "(I)Z",
2233 reinterpret_cast<void *>(
2234 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2235 {"native_set_gps_lock",
2236 "(I)Z",
2237 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2238 {"native_set_emergency_supl_pdn",
2239 "(I)Z",
2240 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002241 {"native_set_satellite_blacklist",
2242 "([I[I)Z",
2243 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002244 {"native_get_batch_size",
2245 "()I",
2246 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2247 {"native_init_batching",
2248 "()Z",
2249 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2250 {"native_start_batch",
2251 "(JZ)Z",
2252 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2253 {"native_flush_batch",
2254 "()V",
2255 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2256 {"native_stop_batch",
2257 "()Z",
2258 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2259 {"native_init_batching",
2260 "()Z",
2261 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2262 {"native_cleanup_batching",
2263 "()V",
2264 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002265};
2266
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002267int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002268 return jniRegisterNativeMethods(
2269 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002270 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002271 sMethods,
2272 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273}
2274
2275} /* namespace android */