blob: 0c11bc110c77f525b3ee9d1d7972c19be48ecb83 [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;
84using android::hidl::base::V1_0::IBase;
Wyatt Rileyfb840922017-11-08 15:07:58 -080085using android::hardware::gnss::V1_0::GnssLocation;
86using android::hardware::gnss::V1_0::GnssLocationFlags;
gomo48f1a642017-11-10 20:35:46 -080087using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
88using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
89using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
90using android::hardware::gnss::V1_0::IGnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070091using android::hardware::gnss::V1_0::IAGnss;
92using android::hardware::gnss::V1_0::IAGnssCallback;
93using android::hardware::gnss::V1_0::IAGnssCallback;
94using android::hardware::gnss::V1_0::IAGnssRil;
95using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080096using android::hardware::gnss::V1_0::IGnssBatching;
97using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070098using android::hardware::gnss::V1_0::IGnssConfiguration;
99using android::hardware::gnss::V1_0::IGnssDebug;
100using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
101using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700102using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
103using android::hardware::gnss::V1_0::IGnssNavigationMessage;
104using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
105using android::hardware::gnss::V1_0::IGnssNi;
106using android::hardware::gnss::V1_0::IGnssNiCallback;
107using android::hardware::gnss::V1_0::IGnssXtra;
108using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800109using android::hardware::gnss::V1_1::IGnssCallback;
110
gomo25208882017-04-15 02:05:25 -0700111struct GnssDeathRecipient : virtual public hidl_death_recipient
112{
113 // hidl_death_recipient interface
114 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800115 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700116 // crashing system server process as described in go//treble-gnss-death
117 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
118 " restarting system server");
119 }
120};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700121
gomo25208882017-04-15 02:05:25 -0700122sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700123sp<IGnss> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800124sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700125sp<IGnssXtra> gnssXtraIface = nullptr;
126sp<IAGnssRil> agnssRilIface = nullptr;
127sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
128sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800129sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700130sp<IGnssDebug> gnssDebugIface = nullptr;
131sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
132sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800133sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
134sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700135sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400137#define WAKE_LOCK_NAME "GPS"
138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139namespace android {
140
Lifu Tang120480f2016-02-07 18:08:19 -0800141template<class T>
142class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700143 public:
144 // Helper function to call setter on a Java object.
145 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800146 JNIEnv* env,
147 jclass clazz,
148 jobject object,
149 const char* method_name,
150 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700151
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700152 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800153 static const char *const signature_;
154};
Lifu Tange5a0e212016-01-25 18:02:17 -0800155
Lifu Tang120480f2016-02-07 18:08:19 -0800156template<class T>
157void JavaMethodHelper<T>::callJavaMethod(
158 JNIEnv* env,
159 jclass clazz,
160 jobject object,
161 const char* method_name,
162 T value) {
163 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
164 env->CallVoidMethod(object, method, value);
165}
destradaaea8a8a62014-06-23 18:19:03 -0700166
Lifu Tang120480f2016-02-07 18:08:19 -0800167class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700168 public:
169 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800170 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700171 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800172
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700173 template<class T>
174 void callSetter(const char* method_name, T value);
175 template<class T>
176 void callSetter(const char* method_name, T* value, size_t size);
177 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800178
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700179 private:
180 JNIEnv* env_;
181 jclass clazz_;
182 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800183};
184
185JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
186 clazz_ = env_->FindClass(class_name);
187 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
188 object_ = env_->NewObject(clazz_, ctor);
189}
190
Wyatt Rileycf879db2017-01-12 13:57:38 -0800191JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
192 clazz_ = env_->FindClass(class_name);
193 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
194 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
195}
196
Lifu Tang120480f2016-02-07 18:08:19 -0800197JavaObject::~JavaObject() {
198 env_->DeleteLocalRef(clazz_);
199}
200
201template<class T>
202void JavaObject::callSetter(const char* method_name, T value) {
203 JavaMethodHelper<T>::callJavaMethod(
204 env_, clazz_, object_, method_name, value);
205}
206
207template<>
208void JavaObject::callSetter(
209 const char* method_name, uint8_t* value, size_t size) {
210 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700211 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800212 jmethodID method = env_->GetMethodID(
213 clazz_,
214 method_name,
215 "([B)V");
216 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700217 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800218}
219
220jobject JavaObject::get() {
221 return object_;
222}
223
224// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800225template<>
226const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
227template<>
228const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
229template<>
230const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
231template<>
232const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
233template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800234const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
235template<>
236const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800237template<>
238const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
239template<>
240const char *const JavaMethodHelper<float>::signature_ = "(F)V";
241template<>
242const char *const JavaMethodHelper<double>::signature_ = "(D)V";
243template<>
244const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
245
246#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800247
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700248static inline jboolean boolToJbool(bool value) {
249 return value ? JNI_TRUE : JNI_FALSE;
250}
Lifu Tang120480f2016-02-07 18:08:19 -0800251
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700252static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
253 if (env->ExceptionCheck()) {
254 ALOGE("An exception was thrown by callback '%s'.", methodName);
255 LOGE_EX(env);
256 env->ExceptionClear();
257 }
258}
destradaaea8a8a62014-06-23 18:19:03 -0700259
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800260class ScopedJniThreadAttach {
261public:
262 ScopedJniThreadAttach() {
263 /*
264 * attachResult will also be JNI_OK if the thead was already attached to
265 * JNI before the call to AttachCurrentThread().
266 */
267 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
268 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
269 attachResult);
270 }
271
272 ~ScopedJniThreadAttach() {
273 jint detachResult = sJvm->DetachCurrentThread();
274 /*
275 * Return if the thread was already detached. Log error for any other
276 * failure.
277 */
278 if (detachResult == JNI_EDETACHED) {
279 return;
280 }
281
282 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
283 detachResult);
284 }
285
286 JNIEnv* getEnv() {
287 /*
288 * Checking validity of mEnv in case the thread was detached elsewhere.
289 */
290 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
291 return mEnv;
292 }
293
294private:
295 JNIEnv* mEnv = nullptr;
296};
297
298thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
299
300static JNIEnv* getJniEnv() {
301 JNIEnv* env = AndroidRuntime::getJNIEnv();
302
303 /*
304 * If env is nullptr, the thread is not already attached to
305 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
306 * will detach it on thread exit.
307 */
308 if (env == nullptr) {
309 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
310 env = tJniThreadAttacher->getEnv();
311 }
312
313 return env;
314}
315
Wyatt Rileyfb840922017-11-08 15:07:58 -0800316static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800317 JavaObject object(env, "android/location/Location", "gps");
318
319 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800320 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800321 SET(Latitude, location.latitudeDegrees);
322 SET(Longitude, location.longitudeDegrees);
323 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800324 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800325 SET(Altitude, location.altitudeMeters);
326 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800327 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800328 SET(Speed, location.speedMetersPerSec);
329 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800330 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800331 SET(Bearing, location.bearingDegrees);
332 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800333 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800334 SET(Accuracy, location.horizontalAccuracyMeters);
335 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
338 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800339 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800340 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
341 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800342 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800343 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
344 }
345 SET(Time, location.timestamp);
346
347 return object.get();
348}
349
Yu-Han Yange7baef32018-02-09 13:58:17 -0800350static GnssLocation createGnssLocation(
351 jint gnssLocationFlags,
352 jdouble latitudeDegrees,
353 jdouble longitudeDegrees,
354 jdouble altitudeMeters,
355 jfloat speedMetersPerSec,
356 jfloat bearingDegrees,
357 jfloat horizontalAccuracyMeters,
358 jfloat verticalAccuracyMeters,
359 jfloat speedAccuracyMetersPerSecond,
360 jfloat bearingAccuracyDegrees,
361 jlong timestamp) {
362 GnssLocation location;
363 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
364 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
365 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
366 location.altitudeMeters = static_cast<double>(altitudeMeters);
367 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
368 location.bearingDegrees = static_cast<float>(bearingDegrees);
369 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
370 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
371 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
372 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
373 location.timestamp = static_cast<uint64_t>(timestamp);
374
375 return location;
376}
377
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700378/*
379 * GnssCallback class implements the callback methods for IGnss interface.
380 */
381struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800382 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700383 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
384 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
385 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
386 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
387 Return<void> gnssAcquireWakelockCb() override;
388 Return<void> gnssReleaseWakelockCb() override;
389 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800390 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700391 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800392
Wyatt Rileyfb840922017-11-08 15:07:58 -0800393 // New in 1.1
394 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
395
Wyatt Riley26465d22018-02-12 13:44:24 -0800396 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700397 static const char* sNmeaString;
398 static size_t sNmeaStringLength;
399};
400
Wyatt Rileyfb840922017-11-08 15:07:58 -0800401Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
402 ALOGD("%s: name=%s\n", __func__, name.c_str());
403
Wyatt Rileyfb840922017-11-08 15:07:58 -0800404 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800405 jstring jstringName = env->NewStringUTF(name.c_str());
406 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800407 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800408
Wyatt Rileyfb840922017-11-08 15:07:58 -0800409 return Void();
410}
411
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700412const char* GnssCallback::sNmeaString = nullptr;
413size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700414
Wyatt Rileyfb840922017-11-08 15:07:58 -0800415Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800416 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800417
418 jobject jLocation = translateLocation(env, location);
419 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800420 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800421
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700422 env->CallVoidMethod(mCallbacksObj,
423 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800424 boolToJbool(hasLatLong),
425 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700426 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800427 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700428 return Void();
429}
430
431Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800432 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700433 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
434 checkAndClearExceptionFromCallback(env, __FUNCTION__);
435 return Void();
436}
437
438Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800439 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700440
Wyatt Riley26465d22018-02-12 13:44:24 -0800441 uint32_t listSize = svStatus.numSvs;
442 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700443 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800444 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700445 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800446 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800447 }
448
Wyatt Riley26465d22018-02-12 13:44:24 -0800449 jintArray svidWithFlagArray = env->NewIntArray(listSize);
450 jfloatArray cn0Array = env->NewFloatArray(listSize);
451 jfloatArray elevArray = env->NewFloatArray(listSize);
452 jfloatArray azimArray = env->NewFloatArray(listSize);
453 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
454
455 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
456 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
457 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
458 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
459 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
460
461 /*
462 * Read GNSS SV info.
463 */
464 for (size_t i = 0; i < listSize; ++i) {
465 enum ShiftWidth: uint8_t {
466 SVID_SHIFT_WIDTH = 8,
467 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
468 };
469
470 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
471 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
472 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
473 static_cast<uint32_t>(info.svFlag);
474 cn0s[i] = info.cN0Dbhz;
475 elev[i] = info.elevationDegrees;
476 azim[i] = info.azimuthDegrees;
477 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800478 }
destradaaea8a8a62014-06-23 18:19:03 -0700479
Wyatt Riley26465d22018-02-12 13:44:24 -0800480 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
481 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
482 env->ReleaseFloatArrayElements(elevArray, elev, 0);
483 env->ReleaseFloatArrayElements(azimArray, azim, 0);
484 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
485
486 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
487 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
488 carrierFreqArray);
489
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700490 checkAndClearExceptionFromCallback(env, __FUNCTION__);
491 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700492}
493
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700494Return<void> GnssCallback::gnssNmeaCb(
495 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800496 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700497 /*
498 * The Java code will call back to read these values.
499 * We do this to avoid creating unnecessary String objects.
500 */
501 sNmeaString = nmea.c_str();
502 sNmeaStringLength = nmea.size();
503
504 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
505 checkAndClearExceptionFromCallback(env, __FUNCTION__);
506 return Void();
507}
508
509Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
510 ALOGD("%s: %du\n", __func__, capabilities);
511
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800512 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700513 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
514 checkAndClearExceptionFromCallback(env, __FUNCTION__);
515 return Void();
516}
517
518Return<void> GnssCallback::gnssAcquireWakelockCb() {
519 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
520 return Void();
521}
522
523Return<void> GnssCallback::gnssReleaseWakelockCb() {
524 release_wake_lock(WAKE_LOCK_NAME);
525 return Void();
526}
527
528Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800529 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700530 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
531 checkAndClearExceptionFromCallback(env, __FUNCTION__);
532 return Void();
533}
534
Yu-Han Yang21988932018-01-23 15:07:37 -0800535Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800536 JNIEnv* env = getJniEnv();
537 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
538 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800539 return Void();
540}
541
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700542Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
543 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
544
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800545 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700546 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
547 info.yearOfHw);
548 checkAndClearExceptionFromCallback(env, __FUNCTION__);
549 return Void();
550}
551
552class GnssXtraCallback : public IGnssXtraCallback {
553 Return<void> downloadRequestCb() override;
554};
555
556/*
557 * GnssXtraCallback class implements the callback methods for the IGnssXtra
558 * interface.
559 */
560Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800561 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700562 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
563 checkAndClearExceptionFromCallback(env, __FUNCTION__);
564 return Void();
565}
566
567/*
568 * GnssGeofenceCallback class implements the callback methods for the
569 * IGnssGeofence interface.
570 */
571struct GnssGeofenceCallback : public IGnssGeofenceCallback {
572 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
573 Return<void> gnssGeofenceTransitionCb(
574 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800575 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700576 GeofenceTransition transition,
577 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
578 Return<void> gnssGeofenceStatusCb(
579 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800580 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700581 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
582 GeofenceStatus status) override;
583 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
584 GeofenceStatus status) override;
585 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
586 GeofenceStatus status) override;
587 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
588 GeofenceStatus status) override;
589};
590
591Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
592 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800593 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700594 GeofenceTransition transition,
595 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800596 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700597
Wyatt Riley5d229832017-02-10 17:06:00 -0800598 jobject jLocation = translateLocation(env, location);
599
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700600 env->CallVoidMethod(mCallbacksObj,
601 method_reportGeofenceTransition,
602 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800603 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700604 transition,
605 timestamp);
606
607 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800608 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700609 return Void();
610}
611
612Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
613 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800614 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800615 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800616
617 jobject jLocation = translateLocation(env, location);
618
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700619 env->CallVoidMethod(mCallbacksObj,
620 method_reportGeofenceStatus,
621 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800622 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700623 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800624 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700625 return Void();
626}
627
628Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
629 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800630 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700631 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
632 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
633 }
634
635 env->CallVoidMethod(mCallbacksObj,
636 method_reportGeofenceAddStatus,
637 geofenceId,
638 status);
639 checkAndClearExceptionFromCallback(env, __FUNCTION__);
640 return Void();
641}
642
643Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
644 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800645 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700646 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
647 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
648 }
649
650 env->CallVoidMethod(mCallbacksObj,
651 method_reportGeofenceRemoveStatus,
652 geofenceId, status);
653 checkAndClearExceptionFromCallback(env, __FUNCTION__);
654 return Void();
655}
656
657Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
658 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800659 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700660 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
661 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
662 }
663
664 env->CallVoidMethod(mCallbacksObj,
665 method_reportGeofencePauseStatus,
666 geofenceId, status);
667 checkAndClearExceptionFromCallback(env, __FUNCTION__);
668 return Void();
669}
670
671Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
672 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800673 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700674 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
675 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
676 }
677
678 env->CallVoidMethod(mCallbacksObj,
679 method_reportGeofenceResumeStatus,
680 geofenceId, status);
681 checkAndClearExceptionFromCallback(env, __FUNCTION__);
682 return Void();
683}
684
685/*
686 * GnssNavigationMessageCallback interface implements the callback methods
687 * required by the IGnssNavigationMessage interface.
688 */
689struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
690 /*
691 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
692 * follow.
693 */
694 Return<void> gnssNavigationMessageCb(
695 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
696};
697
698Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
699 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800700 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700701
702 size_t dataLength = message.data.size();
703
704 std::vector<uint8_t> navigationData = message.data;
705 uint8_t* data = &(navigationData[0]);
706 if (dataLength == 0 || data == NULL) {
707 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
708 dataLength);
709 return Void();
710 }
711
712 JavaObject object(env, "android/location/GnssNavigationMessage");
713 SET(Type, static_cast<int32_t>(message.type));
714 SET(Svid, static_cast<int32_t>(message.svid));
715 SET(MessageId, static_cast<int32_t>(message.messageId));
716 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
717 object.callSetter("setData", data, dataLength);
718 SET(Status, static_cast<int32_t>(message.status));
719
720 jobject navigationMessage = object.get();
721 env->CallVoidMethod(mCallbacksObj,
722 method_reportNavigationMessages,
723 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800724 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700725 env->DeleteLocalRef(navigationMessage);
726 return Void();
727}
728
729/*
730 * GnssMeasurementCallback implements the callback methods required for the
731 * GnssMeasurement interface.
732 */
733struct GnssMeasurementCallback : public IGnssMeasurementCallback {
734 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
735 private:
736 jobject translateGnssMeasurement(
737 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
738 jobject translateGnssClock(
739 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
740 jobjectArray translateGnssMeasurements(
741 JNIEnv* env,
742 const IGnssMeasurementCallback::GnssMeasurement* measurements,
743 size_t count);
744 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
745};
746
747
748Return<void> GnssMeasurementCallback::GnssMeasurementCb(
749 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800750 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700751
752 jobject clock;
753 jobjectArray measurementArray;
754
755 clock = translateGnssClock(env, &data.clock);
756 measurementArray = translateGnssMeasurements(
757 env, data.measurements.data(), data.measurementCount);
758 setMeasurementData(env, clock, measurementArray);
759
760 env->DeleteLocalRef(clock);
761 env->DeleteLocalRef(measurementArray);
762 return Void();
763}
764
765jobject GnssMeasurementCallback::translateGnssMeasurement(
766 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800767 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800768
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700769 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700770
771 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800772 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700773 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800774 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700775 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800776 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700777 measurement->receivedSvTimeUncertaintyInNs);
778 SET(Cn0DbHz, measurement->cN0DbHz);
779 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800780 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700781 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800782 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700783 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
784 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800785 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700786 measurement->accumulatedDeltaRangeUncertaintyM);
787
788 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
789 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
790 }
791
792 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
793 SET(CarrierPhase, measurement->carrierPhase);
794 }
795
796 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
797 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
798 }
799
800 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
801
802 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
803 SET(SnrInDb, measurement->snrDb);
804 }
Lifu Tang120480f2016-02-07 18:08:19 -0800805
gomo4402af62017-01-11 13:20:13 -0800806 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800807 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800808 }
809
Lifu Tang120480f2016-02-07 18:08:19 -0800810 return object.get();
811}
812
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700813jobject GnssMeasurementCallback::translateGnssClock(
814 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
815 JavaObject object(env, "android/location/GnssClock");
816
817 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
818 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
819 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
820 }
821
822 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
823 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
824 }
825
826 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
827 SET(FullBiasNanos, clock->fullBiasNs);
828 }
829
830 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
831 SET(BiasNanos, clock->biasNs);
832 }
833
834 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
835 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
836 }
837
838 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
839 SET(DriftNanosPerSecond, clock->driftNsps);
840 }
841
842 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
843 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
844 }
845
846 SET(TimeNanos, clock->timeNs);
847 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
848
849 return object.get();
850}
851
852jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
853 const IGnssMeasurementCallback::GnssMeasurement*
854 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800855 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700856 return NULL;
857 }
858
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700859 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800860 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800861 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800862 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700863 NULL /* initialElement */);
864
Lifu Tang120480f2016-02-07 18:08:19 -0800865 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700866 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800867 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800868 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800869 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
870 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700871 }
872
Lifu Tang818aa2c2016-02-01 01:52:00 -0800873 env->DeleteLocalRef(gnssMeasurementClass);
874 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700875}
876
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700877void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
878 jobjectArray measurementArray) {
879 jclass gnssMeasurementsEventClass =
880 env->FindClass("android/location/GnssMeasurementsEvent");
881 jmethodID gnssMeasurementsEventCtor =
882 env->GetMethodID(
883 gnssMeasurementsEventClass,
884 "<init>",
885 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800886
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700887 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
888 gnssMeasurementsEventCtor,
889 clock,
890 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800891
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700892 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
893 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800894 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800895 env->DeleteLocalRef(gnssMeasurementsEventClass);
896 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700897}
898
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700899/*
900 * GnssNiCallback implements callback methods required by the IGnssNi interface.
901 */
902struct GnssNiCallback : public IGnssNiCallback {
903 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
904 override;
destradaaea8a8a62014-06-23 18:19:03 -0700905};
906
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700907Return<void> GnssNiCallback::niNotifyCb(
908 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800909 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700910 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
911 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
912
913 if (requestorId && text) {
914 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
915 notification.notificationId, notification.niType,
916 notification.notifyFlags, notification.timeoutSec,
917 notification.defaultResponse, requestorId, text,
918 notification.requestorIdEncoding,
919 notification.notificationIdEncoding);
920 } else {
921 ALOGE("%s: OOM Error\n", __func__);
922 }
923
924 if (requestorId) {
925 env->DeleteLocalRef(requestorId);
926 }
927
928 if (text) {
929 env->DeleteLocalRef(text);
930 }
931 checkAndClearExceptionFromCallback(env, __FUNCTION__);
932 return Void();
933}
934
935/*
936 * AGnssCallback implements callback methods required by the IAGnss interface.
937 */
938struct AGnssCallback : public IAGnssCallback {
939 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
940 Return<void> agnssStatusIpV6Cb(
941 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
942
943 Return<void> agnssStatusIpV4Cb(
944 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
945 private:
946 jbyteArray convertToIpV4(uint32_t ip);
947};
948
949Return<void> AGnssCallback::agnssStatusIpV6Cb(
950 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800951 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700952 jbyteArray byteArray = NULL;
953 bool isSupported = false;
954
955 byteArray = env->NewByteArray(16);
956 if (byteArray != NULL) {
957 env->SetByteArrayRegion(byteArray, 0, 16,
958 (const jbyte*)(agps_status.ipV6Addr.data()));
959 isSupported = true;
960 } else {
961 ALOGE("Unable to allocate byte array for IPv6 address.");
962 }
963
964 IF_ALOGD() {
965 // log the IP for reference in case there is a bogus value pushed by HAL
966 char str[INET6_ADDRSTRLEN];
967 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
968 ALOGD("AGPS IP is v6: %s", str);
969 }
970
971 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
972 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
973 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
974 agps_status.type, agps_status.status, byteArray);
975
976 checkAndClearExceptionFromCallback(env, __FUNCTION__);
977
978 if (byteArray) {
979 env->DeleteLocalRef(byteArray);
980 }
981
982 return Void();
983}
984
985Return<void> AGnssCallback::agnssStatusIpV4Cb(
986 const IAGnssCallback::AGnssStatusIpV4& 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
990 uint32_t ipAddr = agps_status.ipV4Addr;
991 byteArray = convertToIpV4(ipAddr);
992
993 IF_ALOGD() {
994 /*
995 * log the IP for reference in case there is a bogus value pushed by
996 * HAL.
997 */
998 char str[INET_ADDRSTRLEN];
999 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1000 ALOGD("AGPS IP is v4: %s", str);
1001 }
1002
1003 jsize byteArrayLength =
1004 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1005 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1006 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1007 agps_status.type, agps_status.status, byteArray);
1008
1009 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1010
1011 if (byteArray) {
1012 env->DeleteLocalRef(byteArray);
1013 }
1014 return Void();
1015}
1016
1017jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1018 if (INADDR_NONE == ip) {
1019 return NULL;
1020 }
1021
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001022 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001023 jbyteArray byteArray = env->NewByteArray(4);
1024 if (byteArray == NULL) {
1025 ALOGE("Unable to allocate byte array for IPv4 address");
1026 return NULL;
1027 }
1028
1029 jbyte ipv4[4];
1030 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1031 memcpy(ipv4, &ip, sizeof(ipv4));
1032 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1033 return byteArray;
1034}
1035
1036/*
1037 * AGnssRilCallback implements the callback methods required by the AGnssRil
1038 * interface.
1039 */
1040struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001041 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001042 Return<void> requestRefLocCb() override;
1043};
1044
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001045Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001046 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001047 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1048 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1049 return Void();
1050}
1051
1052Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001053 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001054 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1055 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1056 return Void();
1057}
1058
Wyatt Rileycf879db2017-01-12 13:57:38 -08001059/*
1060 * GnssBatchingCallback interface implements the callback methods
1061 * required by the IGnssBatching interface.
1062 */
1063struct GnssBatchingCallback : public IGnssBatchingCallback {
1064 /*
1065 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1066 * follow.
1067 */
1068 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001069 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001070 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001071};
1072
1073Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001074 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001075 JNIEnv* env = getJniEnv();
1076
1077 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1078 env->FindClass("android/location/Location"), nullptr);
1079
1080 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001081 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001082 env->SetObjectArrayElement(jLocations, i, jLocation);
1083 env->DeleteLocalRef(jLocation);
1084 }
1085
1086 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1087 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1088
1089 env->DeleteLocalRef(jLocations);
1090
1091 return Void();
1092}
1093
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001094static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001095 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1096 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001097 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001098 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001099 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1100 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1101 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1102 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001103 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1104 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001105 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1106 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1107 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001108 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001109 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1110 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1111 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1112 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001113 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001115 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001116 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1117 "(II)V");
1118 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1119 "(II)V");
1120 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1121 "(II)V");
1122 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1123 "(II)V");
1124 method_reportMeasurementData = env->GetMethodID(
1125 clazz,
1126 "reportMeasurementData",
1127 "(Landroid/location/GnssMeasurementsEvent;)V");
1128 method_reportNavigationMessages = env->GetMethodID(
1129 clazz,
1130 "reportNavigationMessage",
1131 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001132 method_reportLocationBatch = env->GetMethodID(
1133 clazz,
1134 "reportLocationBatch",
1135 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001136
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001137 /*
1138 * Save a pointer to JVM.
1139 */
1140 jint jvmStatus = env->GetJavaVM(&sJvm);
1141 if (jvmStatus != JNI_OK) {
1142 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1143 }
1144
gomo48f1a642017-11-10 20:35:46 -08001145 // TODO(b/31632518)
1146 gnssHal_V1_1 = IGnss_V1_1::getService();
1147 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001148 ALOGD("gnssHal 1.1 was null, trying 1.0");
1149 gnssHal = IGnss::getService();
gomo48f1a642017-11-10 20:35:46 -08001150 } else {
1151 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001152 }
1153
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001154 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001155 gnssHalDeathRecipient = new GnssDeathRecipient();
1156 hardware::Return<bool> linked = gnssHal->linkToDeath(
1157 gnssHalDeathRecipient, /*cookie*/ 0);
1158 if (!linked.isOk()) {
1159 ALOGE("Transaction error in linking to GnssHAL death: %s",
1160 linked.description().c_str());
1161 } else if (!linked) {
1162 ALOGW("Unable to link to GnssHal death notifications");
1163 } else {
1164 ALOGD("Link to death notification successful");
1165 }
1166
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001167 auto gnssXtra = gnssHal->getExtensionXtra();
1168 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001169 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001170 } else {
1171 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001172 }
1173
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001174 auto gnssRil = gnssHal->getExtensionAGnssRil();
1175 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001176 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001177 } else {
1178 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001179 }
1180
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001181 auto gnssAgnss = gnssHal->getExtensionAGnss();
1182 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001183 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001184 } else {
1185 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001186 }
1187
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001188 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1189 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001190 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001191 } else {
1192 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001193 }
1194
gomo48f1a642017-11-10 20:35:46 -08001195 if (gnssHal_V1_1 != nullptr) {
1196 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1197 if (!gnssMeasurement.isOk()) {
1198 ALOGD("Unable to get a handle to GnssMeasurement");
1199 } else {
1200 gnssMeasurementIface_V1_1 = gnssMeasurement;
1201 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1202 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001203 } else {
gomo48f1a642017-11-10 20:35:46 -08001204 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1205 if (!gnssMeasurement_V1_0.isOk()) {
1206 ALOGD("Unable to get a handle to GnssMeasurement");
1207 } else {
1208 gnssMeasurementIface = gnssMeasurement_V1_0;
1209 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001210 }
1211
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001212 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1213 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001214 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001215 } else {
1216 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217 }
1218
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001219 auto gnssNi = gnssHal->getExtensionGnssNi();
1220 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001221 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001222 } else {
1223 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001224 }
1225
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001226 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1227 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001228 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001229 } else {
1230 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001231 }
1232
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001233 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1234 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001235 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001236 } else {
1237 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001239
1240 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1241 if (!gnssBatching.isOk()) {
1242 ALOGD("Unable to get a handle to gnssBatching");
1243 } else {
1244 gnssBatchingIface = gnssBatching;
1245 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001246 } else {
1247 ALOGE("Unable to get GPS service\n");
1248 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001249}
1250
1251static jboolean android_location_GnssLocationProvider_is_supported(
1252 JNIEnv* /* env */, jclass /* clazz */) {
1253 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1254}
1255
1256static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1257 JNIEnv* /* env */, jclass /* clazz */) {
1258 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1259}
1260
1261static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1262 JNIEnv* /* env */, jclass /* jclazz */) {
1263 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1264}
1265
1266static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1267 /*
1268 * This must be set before calling into the HAL library.
1269 */
1270 if (!mCallbacksObj)
1271 mCallbacksObj = env->NewGlobalRef(obj);
1272
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001273 /*
1274 * Fail if the main interface fails to initialize
1275 */
1276 if (gnssHal == nullptr) {
1277 ALOGE("Unable to Initialize GNSS HAL\n");
1278 return JNI_FALSE;
1279 }
1280
Wyatt Rileyfb840922017-11-08 15:07:58 -08001281 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1282
1283 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001284 if (gnssHal_V1_1 != nullptr) {
1285 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001286 } else {
1287 result = gnssHal->setCallback(gnssCbIface);
1288 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001289 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001290 ALOGE("SetCallback for Gnss Interface fails\n");
1291 return JNI_FALSE;
1292 }
1293
1294 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1295 if (gnssXtraIface == nullptr) {
1296 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001297 } else {
1298 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001299 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001300 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001301 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001302 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001303 }
1304
1305 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1306 if (agnssIface != nullptr) {
1307 agnssIface->setCallback(aGnssCbIface);
1308 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001309 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001310 }
1311
1312 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1313 if (gnssGeofencingIface != nullptr) {
1314 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1315 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001316 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001317 }
1318
1319 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001320 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001321 gnssNiIface->setCallback(gnssNiCbIface);
1322 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001323 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001324 }
1325
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001326 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1327 if (agnssRilIface != nullptr) {
1328 agnssRilIface->setCallback(aGnssRilCbIface);
1329 } else {
1330 ALOGI("Unable to Initialize AGnss Ril interface\n");
1331 }
1332
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001333 return JNI_TRUE;
1334}
1335
1336static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1337 if (gnssHal != nullptr) {
1338 gnssHal->cleanup();
1339 }
1340}
1341
1342static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1343 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001344 jint preferred_time, jboolean low_power_mode) {
1345 Return<bool> result = false;
1346 if (gnssHal_V1_1 != nullptr) {
1347 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
1348 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1349 min_interval,
1350 preferred_accuracy,
1351 preferred_time,
1352 low_power_mode);
1353 } else if (gnssHal != nullptr) {
1354 result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1355 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1356 min_interval,
1357 preferred_accuracy,
1358 preferred_time);
1359 }
1360 if (!result.isOk()) {
1361 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1362 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001363 } else {
gomo48f1a642017-11-10 20:35:46 -08001364 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001365 }
1366}
1367
1368static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1369 if (gnssHal != nullptr) {
1370 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001371 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001372 return JNI_FALSE;
1373 } else {
1374 return result;
1375 }
1376 } else {
1377 return JNI_FALSE;
1378 }
1379}
1380
1381static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1382 if (gnssHal != nullptr) {
1383 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001384 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001385 return JNI_FALSE;
1386 } else {
1387 return result;
1388 }
1389 } else {
1390 return JNI_FALSE;
1391 }
1392}
1393static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1394 jobject /* obj */,
1395 jint flags) {
1396 if (gnssHal != nullptr) {
1397 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001398 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001399 ALOGE("Error in deleting aiding data");
1400 }
1401 }
1402}
1403
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001404static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1405 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1406 IAGnssRil::AGnssRefLocation location;
1407
1408 if (agnssRilIface == nullptr) {
1409 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1410 return;
1411 }
1412
1413 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1414 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1415 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1416 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1417 location.cellID.mcc = mcc;
1418 location.cellID.mnc = mnc;
1419 location.cellID.lac = lac;
1420 location.cellID.cid = cid;
1421 break;
1422 default:
1423 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1424 return;
1425 break;
1426 }
1427
1428 agnssRilIface->setRefLocation(location);
1429}
1430
1431static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1432 jint type, jstring setid_string) {
1433 if (agnssRilIface == nullptr) {
1434 ALOGE("no AGPS RIL interface in agps_set_id");
1435 return;
1436 }
1437
1438 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1439 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1440 env->ReleaseStringUTFChars(setid_string, setid);
1441}
1442
1443static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1444 jbyteArray nmeaArray, jint buffer_size) {
1445 // this should only be called from within a call to reportNmea
1446 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1447 int length = GnssCallback::sNmeaStringLength;
1448 if (length > buffer_size)
1449 length = buffer_size;
1450 memcpy(nmea, GnssCallback::sNmeaString, length);
1451 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1452 return (jint) length;
1453}
1454
1455static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1456 jlong time, jlong timeReference, jint uncertainty) {
1457 if (gnssHal != nullptr) {
1458 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001459 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001460 ALOGE("%s: Gnss injectTime() failed", __func__);
1461 }
1462 }
1463}
1464
Yu-Han Yange7baef32018-02-09 13:58:17 -08001465static void android_location_GnssLocationProvider_inject_best_location(
1466 JNIEnv*,
1467 jobject,
1468 jint gnssLocationFlags,
1469 jdouble latitudeDegrees,
1470 jdouble longitudeDegrees,
1471 jdouble altitudeMeters,
1472 jfloat speedMetersPerSec,
1473 jfloat bearingDegrees,
1474 jfloat horizontalAccuracyMeters,
1475 jfloat verticalAccuracyMeters,
1476 jfloat speedAccuracyMetersPerSecond,
1477 jfloat bearingAccuracyDegrees,
1478 jlong timestamp) {
1479 if (gnssHal_V1_1 != nullptr) {
1480 GnssLocation location = createGnssLocation(
1481 gnssLocationFlags,
1482 latitudeDegrees,
1483 longitudeDegrees,
1484 altitudeMeters,
1485 speedMetersPerSec,
1486 bearingDegrees,
1487 horizontalAccuracyMeters,
1488 verticalAccuracyMeters,
1489 speedAccuracyMetersPerSecond,
1490 bearingAccuracyDegrees,
1491 timestamp);
1492 auto result = gnssHal_V1_1->injectBestLocation(location);
1493 if (!result.isOk() || !result) {
1494 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1495 }
1496 } else {
1497 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1498 }
1499}
1500
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001501static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1502 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1503 if (gnssHal != nullptr) {
1504 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001505 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001506 ALOGE("%s: Gnss injectLocation() failed", __func__);
1507 }
1508 }
1509}
1510
1511static jboolean android_location_GnssLocationProvider_supports_xtra(
1512 JNIEnv* /* env */, jobject /* obj */) {
1513 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1514}
1515
1516static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1517 jbyteArray data, jint length) {
1518 if (gnssXtraIface == nullptr) {
1519 ALOGE("XTRA Interface not supported");
1520 return;
1521 }
1522
1523 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1524 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1525 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1526}
1527
1528static void android_location_GnssLocationProvider_agps_data_conn_open(
1529 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1530 if (agnssIface == nullptr) {
1531 ALOGE("no AGPS interface in agps_data_conn_open");
1532 return;
1533 }
1534 if (apn == NULL) {
1535 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1536 return;
1537 }
1538
1539 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1540
1541 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001542 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001543 ALOGE("%s: Failed to set APN and its IP type", __func__);
1544 }
1545 env->ReleaseStringUTFChars(apn, apnStr);
1546}
1547
1548static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1549 jobject /* obj */) {
1550 if (agnssIface == nullptr) {
1551 ALOGE("%s: AGPS interface not supported", __func__);
1552 return;
1553 }
1554
1555 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001556 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001557 ALOGE("%s: Failed to close AGnss data connection", __func__);
1558 }
1559}
1560
1561static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1562 jobject /* obj */) {
1563 if (agnssIface == nullptr) {
1564 ALOGE("%s: AGPS interface not supported", __func__);
1565 return;
1566 }
1567
1568 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001569 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001570 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1571 }
1572}
1573
1574static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1575 jint type, jstring hostname, jint port) {
1576 if (agnssIface == nullptr) {
1577 ALOGE("no AGPS interface in set_agps_server");
1578 return;
1579 }
1580
1581 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1582 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1583 c_hostname,
1584 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001585 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001586 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1587 }
1588
1589 env->ReleaseStringUTFChars(hostname, c_hostname);
1590}
1591
1592static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1593 jobject /* obj */, jint notifId, jint response) {
1594 if (gnssNiIface == nullptr) {
1595 ALOGE("no NI interface in send_ni_response");
1596 return;
1597 }
1598
1599 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1600}
1601
1602static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1603 jobject /* obj */) {
1604 jstring result = NULL;
1605 /*
1606 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1607 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001608
1609 std::stringstream internalState;
1610
1611 if (gnssDebugIface == nullptr) {
1612 internalState << "Gnss Debug Interface not available" << std::endl;
1613 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614 IGnssDebug::DebugData data;
1615 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1616 data = debugData;
1617 });
1618
Wyatt Riley268c6e02017-03-29 10:21:46 -07001619 internalState << "Gnss Location Data:: ";
1620 if (!data.position.valid) {
1621 internalState << "not valid";
1622 } else {
1623 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001624 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1625 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001626 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1627 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001628 << ", horizontalAccuracyMeters: "
1629 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001630 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001631 << ", speedAccuracyMetersPerSecond: "
1632 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001633 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001634 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001635 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001636 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001637
Wyatt Riley268c6e02017-03-29 10:21:46 -07001638 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1639 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1640 << ", frequencyUncertaintyNsPerSec: "
1641 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001642
1643 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001644 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1645 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001646 }
1647
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001648 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1649 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1650 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1651 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001652 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1653 internalState << "svid: " << data.satelliteDataArray[i].svid
1654 << ", constellation: "
1655 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1656 << ", ephemerisType: "
1657 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001658 << ", ephemerisSource: "
1659 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1660 << ", ephemerisHealth: "
1661 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1662 << ", serverPredictionIsAvailable: "
1663 << data.satelliteDataArray[i].serverPredictionIsAvailable
1664 << ", serverPredictionAgeSeconds: "
1665 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001666 << ", ephemerisAgeSeconds: "
1667 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1668 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001669 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001670
1671 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001672 return result;
1673}
1674
1675static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1676 jobject /* obj */,
1677 jboolean connected,
1678 jint type,
1679 jboolean roaming,
1680 jboolean available,
1681 jstring extraInfo,
1682 jstring apn) {
1683 if (agnssRilIface != nullptr) {
1684 auto result = agnssRilIface->updateNetworkState(connected,
1685 static_cast<IAGnssRil::NetworkType>(type),
1686 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001687 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001688 ALOGE("updateNetworkState failed");
1689 }
1690
1691 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1692 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001693 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 ALOGE("updateNetworkAvailability failed");
1695 }
1696
1697 env->ReleaseStringUTFChars(apn, c_apn);
1698 } else {
1699 ALOGE("AGnssRilInterface does not exist");
1700 }
1701}
1702
1703static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1704 JNIEnv* /* env */, jobject /* obj */) {
1705 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1706}
1707
1708static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1709 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1710 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1711 jint unknown_timer) {
1712 if (gnssGeofencingIface != nullptr) {
1713 auto result = gnssGeofencingIface->addGeofence(
1714 geofenceId, latitude, longitude, radius,
1715 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1716 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001717 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001718 } else {
1719 ALOGE("Geofence Interface not available");
1720 }
1721 return JNI_FALSE;
1722}
1723
1724static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1725 jobject /* obj */, jint geofenceId) {
1726 if (gnssGeofencingIface != nullptr) {
1727 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001728 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001729 } else {
1730 ALOGE("Geofence interface not available");
1731 }
1732 return JNI_FALSE;
1733}
1734
1735static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1736 jobject /* obj */, jint geofenceId) {
1737 if (gnssGeofencingIface != nullptr) {
1738 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001739 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001740 } else {
1741 ALOGE("Geofence interface not available");
1742 }
1743 return JNI_FALSE;
1744}
1745
1746static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1747 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1748 if (gnssGeofencingIface != nullptr) {
1749 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001750 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001751 } else {
1752 ALOGE("Geofence interface not available");
1753 }
1754 return JNI_FALSE;
1755}
1756
Lifu Tang30f95a72016-01-07 23:20:38 -08001757static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001758 JNIEnv* env, jclass clazz) {
1759 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001760 return JNI_TRUE;
1761 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001762
destradaaea8a8a62014-06-23 18:19:03 -07001763 return JNI_FALSE;
1764}
1765
Lifu Tang30f95a72016-01-07 23:20:38 -08001766static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001767 JNIEnv* /* env */,
1768 jobject /* obj */,
1769 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001770 if (gnssMeasurementIface == nullptr) {
1771 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001772 return JNI_FALSE;
1773 }
1774
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001775 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001776 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1777 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1778 if (gnssMeasurementIface_V1_1 != nullptr) {
1779 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1780 enableFullTracking);
1781 } else {
1782 if (enableFullTracking == JNI_TRUE) {
1783 // full tracking mode not supported in 1.0 HAL
1784 return JNI_FALSE;
1785 }
1786 result = gnssMeasurementIface->setCallback(cbIface);
1787 }
1788
1789 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001790 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1791 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001792 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001793 } else {
1794 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001795 }
1796
1797 return JNI_TRUE;
1798}
1799
Lifu Tang30f95a72016-01-07 23:20:38 -08001800static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001801 JNIEnv* env,
1802 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001804 ALOGE("Measurement interface not available");
1805 return JNI_FALSE;
1806 }
1807
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001808 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001809 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001810}
1811
Lifu Tang30f95a72016-01-07 23:20:38 -08001812static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001813 JNIEnv* env,
1814 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001815 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001816 return JNI_TRUE;
1817 }
1818 return JNI_FALSE;
1819}
1820
Lifu Tang30f95a72016-01-07 23:20:38 -08001821static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001822 JNIEnv* env,
1823 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001824 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001825 ALOGE("Navigation Message interface is not available.");
1826 return JNI_FALSE;
1827 }
1828
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001829 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1830 new GnssNavigationMessageCallback();
1831 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1832 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1833
1834 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1835 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001836 return JNI_FALSE;
1837 }
1838
1839 return JNI_TRUE;
1840}
1841
Lifu Tang30f95a72016-01-07 23:20:38 -08001842static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001843 JNIEnv* env,
1844 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001845 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001846 ALOGE("Navigation Message interface is not available.");
1847 return JNI_FALSE;
1848 }
1849
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001850 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001851 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001852}
1853
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001854static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1855 jobject,
1856 jint emergencySuplPdn) {
1857 if (gnssConfigurationIface == nullptr) {
1858 ALOGE("no GNSS configuration interface available");
1859 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001860 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001861
1862 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001863 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001864 return result;
1865 } else {
1866 return JNI_FALSE;
1867 }
1868}
1869
1870static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1871 jobject,
1872 jint version) {
1873 if (gnssConfigurationIface == nullptr) {
1874 ALOGE("no GNSS configuration interface available");
1875 return JNI_FALSE;
1876 }
1877 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001878 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001879 return result;
1880 } else {
1881 return JNI_FALSE;
1882 }
1883}
1884
1885static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1886 jobject,
1887 jint suplEs) {
1888 if (gnssConfigurationIface == nullptr) {
1889 ALOGE("no GNSS configuration interface available");
1890 return JNI_FALSE;
1891 }
1892
1893 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001894 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001895 return result;
1896 } else {
1897 return JNI_FALSE;
1898 }
1899}
1900
1901static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1902 jobject,
1903 jint mode) {
1904 if (gnssConfigurationIface == nullptr) {
1905 ALOGE("no GNSS configuration interface available");
1906 return JNI_FALSE;
1907 }
1908
1909 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001910 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001911 return result;
1912 } else {
1913 return JNI_FALSE;
1914 }
1915}
1916
1917static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1918 jobject,
1919 jint gpsLock) {
1920 if (gnssConfigurationIface == nullptr) {
1921 ALOGE("no GNSS configuration interface available");
1922 return JNI_FALSE;
1923 }
1924
1925 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001926 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001927 return result;
1928 } else {
1929 return JNI_FALSE;
1930 }
1931}
1932
1933static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1934 jobject,
1935 jint lppProfile) {
1936 if (gnssConfigurationIface == nullptr) {
1937 ALOGE("no GNSS configuration interface available");
1938 return JNI_FALSE;
1939 }
1940
1941 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1942
Steven Morelandd002a8b2017-01-03 17:18:24 -08001943 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001944 return result;
1945 } else {
1946 return JNI_FALSE;
1947 }
1948}
1949
1950static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1951 jobject,
1952 jint gnssPosProtocol) {
1953 if (gnssConfigurationIface == nullptr) {
1954 ALOGE("no GNSS configuration interface available");
1955 return JNI_FALSE;
1956 }
1957
1958 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001959 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001960 return result;
1961 } else {
1962 return JNI_FALSE;
1963 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001964}
1965
Wyatt Rileycf879db2017-01-12 13:57:38 -08001966static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1967 if (gnssBatchingIface == nullptr) {
1968 return 0; // batching not supported, size = 0
1969 }
1970 auto result = gnssBatchingIface->getBatchSize();
1971 if (result.isOk()) {
1972 return static_cast<jint>(result);
1973 } else {
1974 return 0; // failure in binder, don't support batching
1975 }
1976}
1977
1978static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1979 if (gnssBatchingIface == nullptr) {
1980 return JNI_FALSE; // batching not supported
1981 }
1982 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1983
1984 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1985}
1986
1987static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1988 if (gnssBatchingIface == nullptr) {
1989 return; // batching not supported
1990 }
1991 gnssBatchingIface->cleanup();
1992}
1993
1994static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1995 jlong periodNanos, jboolean wakeOnFifoFull) {
1996 if (gnssBatchingIface == nullptr) {
1997 return JNI_FALSE; // batching not supported
1998 }
1999
2000 IGnssBatching::Options options;
2001 options.periodNanos = periodNanos;
2002 if (wakeOnFifoFull) {
2003 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2004 } else {
2005 options.flags = 0;
2006 }
2007
2008 return static_cast<jboolean>(gnssBatchingIface->start(options));
2009}
2010
2011static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
2012 if (gnssBatchingIface == nullptr) {
2013 return; // batching not supported
2014 }
2015
2016 gnssBatchingIface->flush();
2017}
2018
2019static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
2020 if (gnssBatchingIface == nullptr) {
2021 return JNI_FALSE; // batching not supported
2022 }
2023
2024 return gnssBatchingIface->stop();
2025}
2026
Daniel Micay76f6a862015-09-19 17:31:01 -04002027static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002028 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002029 {"class_init_native", "()V", reinterpret_cast<void *>(
2030 android_location_GnssLocationProvider_class_init_native)},
2031 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2032 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002033 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002034 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002035 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002036 reinterpret_cast<void *>(
2037 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
2038 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2039 {"native_cleanup", "()V", reinterpret_cast<void *>(
2040 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002041 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002042 "(IIIIIZ)Z",
2043 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002044 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2045 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002046 {"native_delete_aiding_data",
2047 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002048 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002049 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2050 android_location_GnssLocationProvider_read_nmea)},
2051 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2052 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002053 {"native_inject_best_location",
2054 "(IDDDFFFFFFJ)V",
2055 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002056 {"native_inject_location",
2057 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002058 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2059 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2060 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002061 {"native_inject_xtra_data",
2062 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002063 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002064 {"native_agps_data_conn_open",
2065 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002066 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002067 {"native_agps_data_conn_closed",
2068 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002069 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002070 {"native_agps_data_conn_failed",
2071 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002072 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002073 {"native_agps_set_id",
2074 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002075 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002076 {"native_agps_set_ref_location_cellid",
2077 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002078 reinterpret_cast<void *>(
2079 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002080 {"native_set_agps_server",
2081 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002082 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002083 {"native_send_ni_response",
2084 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002085 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002086 {"native_get_internal_state",
2087 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002088 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002089 {"native_update_network_state",
2090 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002091 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002092 {"native_is_geofence_supported",
2093 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002094 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002095 {"native_add_geofence",
2096 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002097 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002098 {"native_remove_geofence",
2099 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002100 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2101 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2102 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002103 {"native_resume_geofence",
2104 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002105 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002106 {"native_is_measurement_supported",
2107 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002108 reinterpret_cast<void *>(
2109 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002110 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002111 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002112 reinterpret_cast<void *>(
2113 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002114 {"native_stop_measurement_collection",
2115 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002116 reinterpret_cast<void *>(
2117 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002118 {"native_is_navigation_message_supported",
2119 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002120 reinterpret_cast<void *>(
2121 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002122 {"native_start_navigation_message_collection",
2123 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002124 reinterpret_cast<void *>(
2125 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002126 {"native_stop_navigation_message_collection",
2127 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002128 reinterpret_cast<void *>(
2129 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2130 {"native_set_supl_es",
2131 "(I)Z",
2132 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2133 {"native_set_supl_version",
2134 "(I)Z",
2135 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2136 {"native_set_supl_mode",
2137 "(I)Z",
2138 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2139 {"native_set_lpp_profile",
2140 "(I)Z",
2141 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2142 {"native_set_gnss_pos_protocol_select",
2143 "(I)Z",
2144 reinterpret_cast<void *>(
2145 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2146 {"native_set_gps_lock",
2147 "(I)Z",
2148 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2149 {"native_set_emergency_supl_pdn",
2150 "(I)Z",
2151 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002152 {"native_get_batch_size",
2153 "()I",
2154 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2155 {"native_init_batching",
2156 "()Z",
2157 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2158 {"native_start_batch",
2159 "(JZ)Z",
2160 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2161 {"native_flush_batch",
2162 "()V",
2163 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2164 {"native_stop_batch",
2165 "()Z",
2166 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2167 {"native_init_batching",
2168 "()Z",
2169 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2170 {"native_cleanup_batching",
2171 "()V",
2172 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173};
2174
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002175int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002176 return jniRegisterNativeMethods(
2177 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002178 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002179 sMethods,
2180 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181}
2182
2183} /* namespace android */