blob: dcee15106f8a81a8a453ec2aadc9a79792193f47 [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;
Wyatt Rileyfb840922017-11-08 15:07:58 -080084using android::hardware::gnss::V1_0::GnssLocation;
85using android::hardware::gnss::V1_0::GnssLocationFlags;
Wyatt Riley46ac9562018-03-02 20:16:58 -080086
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070087using android::hardware::gnss::V1_0::IAGnss;
88using android::hardware::gnss::V1_0::IAGnssCallback;
89using android::hardware::gnss::V1_0::IAGnssCallback;
90using android::hardware::gnss::V1_0::IAGnssRil;
91using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080092using android::hardware::gnss::V1_0::IGnssBatching;
93using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070094using android::hardware::gnss::V1_0::IGnssConfiguration;
95using android::hardware::gnss::V1_0::IGnssDebug;
96using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
97using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070098using android::hardware::gnss::V1_0::IGnssNavigationMessage;
99using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
100using android::hardware::gnss::V1_0::IGnssNi;
101using android::hardware::gnss::V1_0::IGnssNiCallback;
102using android::hardware::gnss::V1_0::IGnssXtra;
103using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800104
Wyatt Rileyfb840922017-11-08 15:07:58 -0800105using android::hardware::gnss::V1_1::IGnssCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800106
107using android::hidl::base::V1_0::IBase;
108
109using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
110using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
111using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
112using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
113using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
114using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
115
Wyatt Rileyfb840922017-11-08 15:07:58 -0800116
gomo25208882017-04-15 02:05:25 -0700117struct GnssDeathRecipient : virtual public hidl_death_recipient
118{
119 // hidl_death_recipient interface
120 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800121 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700122 // crashing system server process as described in go//treble-gnss-death
123 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
124 " restarting system server");
125 }
126};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700127
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800128// Must match the value from GnssMeasurement.java
129static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
130
gomo25208882017-04-15 02:05:25 -0700131sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800132sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800133sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700134sp<IGnssXtra> gnssXtraIface = nullptr;
135sp<IAGnssRil> agnssRilIface = nullptr;
136sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
137sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800138sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700139sp<IGnssDebug> gnssDebugIface = nullptr;
140sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
141sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800142sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
143sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400146#define WAKE_LOCK_NAME "GPS"
147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148namespace android {
149
Lifu Tang120480f2016-02-07 18:08:19 -0800150template<class T>
151class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700152 public:
153 // Helper function to call setter on a Java object.
154 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800155 JNIEnv* env,
156 jclass clazz,
157 jobject object,
158 const char* method_name,
159 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700160
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700161 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800162 static const char *const signature_;
163};
Lifu Tange5a0e212016-01-25 18:02:17 -0800164
Lifu Tang120480f2016-02-07 18:08:19 -0800165template<class T>
166void JavaMethodHelper<T>::callJavaMethod(
167 JNIEnv* env,
168 jclass clazz,
169 jobject object,
170 const char* method_name,
171 T value) {
172 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
173 env->CallVoidMethod(object, method, value);
174}
destradaaea8a8a62014-06-23 18:19:03 -0700175
Lifu Tang120480f2016-02-07 18:08:19 -0800176class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700177 public:
178 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800179 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700180 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800181
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700182 template<class T>
183 void callSetter(const char* method_name, T value);
184 template<class T>
185 void callSetter(const char* method_name, T* value, size_t size);
186 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800187
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700188 private:
189 JNIEnv* env_;
190 jclass clazz_;
191 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800192};
193
194JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
195 clazz_ = env_->FindClass(class_name);
196 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
197 object_ = env_->NewObject(clazz_, ctor);
198}
199
Wyatt Rileycf879db2017-01-12 13:57:38 -0800200JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
201 clazz_ = env_->FindClass(class_name);
202 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
203 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
204}
205
Lifu Tang120480f2016-02-07 18:08:19 -0800206JavaObject::~JavaObject() {
207 env_->DeleteLocalRef(clazz_);
208}
209
210template<class T>
211void JavaObject::callSetter(const char* method_name, T value) {
212 JavaMethodHelper<T>::callJavaMethod(
213 env_, clazz_, object_, method_name, value);
214}
215
216template<>
217void JavaObject::callSetter(
218 const char* method_name, uint8_t* value, size_t size) {
219 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700220 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800221 jmethodID method = env_->GetMethodID(
222 clazz_,
223 method_name,
224 "([B)V");
225 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700226 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800227}
228
229jobject JavaObject::get() {
230 return object_;
231}
232
233// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800234template<>
235const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
236template<>
237const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
238template<>
239const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
240template<>
241const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
242template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800243const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
244template<>
245const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800246template<>
247const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
248template<>
249const char *const JavaMethodHelper<float>::signature_ = "(F)V";
250template<>
251const char *const JavaMethodHelper<double>::signature_ = "(D)V";
252template<>
253const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
254
255#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800256
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700257static inline jboolean boolToJbool(bool value) {
258 return value ? JNI_TRUE : JNI_FALSE;
259}
Lifu Tang120480f2016-02-07 18:08:19 -0800260
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700261static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
262 if (env->ExceptionCheck()) {
263 ALOGE("An exception was thrown by callback '%s'.", methodName);
264 LOGE_EX(env);
265 env->ExceptionClear();
266 }
267}
destradaaea8a8a62014-06-23 18:19:03 -0700268
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800269class ScopedJniThreadAttach {
270public:
271 ScopedJniThreadAttach() {
272 /*
273 * attachResult will also be JNI_OK if the thead was already attached to
274 * JNI before the call to AttachCurrentThread().
275 */
276 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
277 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
278 attachResult);
279 }
280
281 ~ScopedJniThreadAttach() {
282 jint detachResult = sJvm->DetachCurrentThread();
283 /*
284 * Return if the thread was already detached. Log error for any other
285 * failure.
286 */
287 if (detachResult == JNI_EDETACHED) {
288 return;
289 }
290
291 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
292 detachResult);
293 }
294
295 JNIEnv* getEnv() {
296 /*
297 * Checking validity of mEnv in case the thread was detached elsewhere.
298 */
299 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
300 return mEnv;
301 }
302
303private:
304 JNIEnv* mEnv = nullptr;
305};
306
307thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
308
309static JNIEnv* getJniEnv() {
310 JNIEnv* env = AndroidRuntime::getJNIEnv();
311
312 /*
313 * If env is nullptr, the thread is not already attached to
314 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
315 * will detach it on thread exit.
316 */
317 if (env == nullptr) {
318 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
319 env = tJniThreadAttacher->getEnv();
320 }
321
322 return env;
323}
324
Wyatt Rileyfb840922017-11-08 15:07:58 -0800325static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800326 JavaObject object(env, "android/location/Location", "gps");
327
328 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800329 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800330 SET(Latitude, location.latitudeDegrees);
331 SET(Longitude, location.longitudeDegrees);
332 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800333 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800334 SET(Altitude, location.altitudeMeters);
335 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 SET(Speed, location.speedMetersPerSec);
338 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800339 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800340 SET(Bearing, location.bearingDegrees);
341 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800342 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800343 SET(Accuracy, location.horizontalAccuracyMeters);
344 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800345 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800346 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
347 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800348 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800349 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
350 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800351 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800352 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
353 }
354 SET(Time, location.timestamp);
355
356 return object.get();
357}
358
Yu-Han Yange7baef32018-02-09 13:58:17 -0800359static GnssLocation createGnssLocation(
360 jint gnssLocationFlags,
361 jdouble latitudeDegrees,
362 jdouble longitudeDegrees,
363 jdouble altitudeMeters,
364 jfloat speedMetersPerSec,
365 jfloat bearingDegrees,
366 jfloat horizontalAccuracyMeters,
367 jfloat verticalAccuracyMeters,
368 jfloat speedAccuracyMetersPerSecond,
369 jfloat bearingAccuracyDegrees,
370 jlong timestamp) {
371 GnssLocation location;
372 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
373 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
374 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
375 location.altitudeMeters = static_cast<double>(altitudeMeters);
376 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
377 location.bearingDegrees = static_cast<float>(bearingDegrees);
378 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
379 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
380 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
381 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
382 location.timestamp = static_cast<uint64_t>(timestamp);
383
384 return location;
385}
386
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700387/*
388 * GnssCallback class implements the callback methods for IGnss interface.
389 */
390struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800391 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700392 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
393 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
394 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
395 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
396 Return<void> gnssAcquireWakelockCb() override;
397 Return<void> gnssReleaseWakelockCb() override;
398 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800399 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700400 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800401
Wyatt Rileyfb840922017-11-08 15:07:58 -0800402 // New in 1.1
403 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
404
Wyatt Riley26465d22018-02-12 13:44:24 -0800405 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700406 static const char* sNmeaString;
407 static size_t sNmeaStringLength;
408};
409
Wyatt Rileyfb840922017-11-08 15:07:58 -0800410Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
411 ALOGD("%s: name=%s\n", __func__, name.c_str());
412
Wyatt Rileyfb840922017-11-08 15:07:58 -0800413 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800414 jstring jstringName = env->NewStringUTF(name.c_str());
415 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800416 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800417
Wyatt Rileyfb840922017-11-08 15:07:58 -0800418 return Void();
419}
420
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700421const char* GnssCallback::sNmeaString = nullptr;
422size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700423
Wyatt Rileyfb840922017-11-08 15:07:58 -0800424Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800425 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800426
427 jobject jLocation = translateLocation(env, location);
428 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800429 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800430
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700431 env->CallVoidMethod(mCallbacksObj,
432 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800433 boolToJbool(hasLatLong),
434 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700435 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800436 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700437 return Void();
438}
439
440Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800441 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700442 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
443 checkAndClearExceptionFromCallback(env, __FUNCTION__);
444 return Void();
445}
446
447Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800448 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700449
Wyatt Riley26465d22018-02-12 13:44:24 -0800450 uint32_t listSize = svStatus.numSvs;
451 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700452 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800453 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700454 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800455 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800456 }
457
Wyatt Riley26465d22018-02-12 13:44:24 -0800458 jintArray svidWithFlagArray = env->NewIntArray(listSize);
459 jfloatArray cn0Array = env->NewFloatArray(listSize);
460 jfloatArray elevArray = env->NewFloatArray(listSize);
461 jfloatArray azimArray = env->NewFloatArray(listSize);
462 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
463
464 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
465 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
466 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
467 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
468 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
469
470 /*
471 * Read GNSS SV info.
472 */
473 for (size_t i = 0; i < listSize; ++i) {
474 enum ShiftWidth: uint8_t {
475 SVID_SHIFT_WIDTH = 8,
476 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
477 };
478
479 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
480 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
481 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
482 static_cast<uint32_t>(info.svFlag);
483 cn0s[i] = info.cN0Dbhz;
484 elev[i] = info.elevationDegrees;
485 azim[i] = info.azimuthDegrees;
486 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800487 }
destradaaea8a8a62014-06-23 18:19:03 -0700488
Wyatt Riley26465d22018-02-12 13:44:24 -0800489 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
490 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
491 env->ReleaseFloatArrayElements(elevArray, elev, 0);
492 env->ReleaseFloatArrayElements(azimArray, azim, 0);
493 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
494
495 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
496 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
497 carrierFreqArray);
498
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700499 checkAndClearExceptionFromCallback(env, __FUNCTION__);
500 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700501}
502
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700503Return<void> GnssCallback::gnssNmeaCb(
504 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800505 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700506 /*
507 * The Java code will call back to read these values.
508 * We do this to avoid creating unnecessary String objects.
509 */
510 sNmeaString = nmea.c_str();
511 sNmeaStringLength = nmea.size();
512
513 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
514 checkAndClearExceptionFromCallback(env, __FUNCTION__);
515 return Void();
516}
517
518Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
519 ALOGD("%s: %du\n", __func__, capabilities);
520
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800521 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700522 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
523 checkAndClearExceptionFromCallback(env, __FUNCTION__);
524 return Void();
525}
526
527Return<void> GnssCallback::gnssAcquireWakelockCb() {
528 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
529 return Void();
530}
531
532Return<void> GnssCallback::gnssReleaseWakelockCb() {
533 release_wake_lock(WAKE_LOCK_NAME);
534 return Void();
535}
536
537Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800538 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700539 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
540 checkAndClearExceptionFromCallback(env, __FUNCTION__);
541 return Void();
542}
543
Yu-Han Yang21988932018-01-23 15:07:37 -0800544Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800545 JNIEnv* env = getJniEnv();
546 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
547 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800548 return Void();
549}
550
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700551Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
552 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
553
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800554 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700555 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
556 info.yearOfHw);
557 checkAndClearExceptionFromCallback(env, __FUNCTION__);
558 return Void();
559}
560
561class GnssXtraCallback : public IGnssXtraCallback {
562 Return<void> downloadRequestCb() override;
563};
564
565/*
566 * GnssXtraCallback class implements the callback methods for the IGnssXtra
567 * interface.
568 */
569Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800570 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700571 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
572 checkAndClearExceptionFromCallback(env, __FUNCTION__);
573 return Void();
574}
575
576/*
577 * GnssGeofenceCallback class implements the callback methods for the
578 * IGnssGeofence interface.
579 */
580struct GnssGeofenceCallback : public IGnssGeofenceCallback {
581 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
582 Return<void> gnssGeofenceTransitionCb(
583 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800584 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700585 GeofenceTransition transition,
586 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
587 Return<void> gnssGeofenceStatusCb(
588 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800589 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700590 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
591 GeofenceStatus status) override;
592 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
593 GeofenceStatus status) override;
594 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
595 GeofenceStatus status) override;
596 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
597 GeofenceStatus status) override;
598};
599
600Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
601 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800602 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700603 GeofenceTransition transition,
604 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800605 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700606
Wyatt Riley5d229832017-02-10 17:06:00 -0800607 jobject jLocation = translateLocation(env, location);
608
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700609 env->CallVoidMethod(mCallbacksObj,
610 method_reportGeofenceTransition,
611 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800612 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700613 transition,
614 timestamp);
615
616 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800617 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700618 return Void();
619}
620
621Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
622 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800623 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800624 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800625
626 jobject jLocation = translateLocation(env, location);
627
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700628 env->CallVoidMethod(mCallbacksObj,
629 method_reportGeofenceStatus,
630 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800631 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700632 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800633 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700634 return Void();
635}
636
637Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
638 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800639 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700640 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
641 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
642 }
643
644 env->CallVoidMethod(mCallbacksObj,
645 method_reportGeofenceAddStatus,
646 geofenceId,
647 status);
648 checkAndClearExceptionFromCallback(env, __FUNCTION__);
649 return Void();
650}
651
652Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
653 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800654 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700655 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
656 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
657 }
658
659 env->CallVoidMethod(mCallbacksObj,
660 method_reportGeofenceRemoveStatus,
661 geofenceId, status);
662 checkAndClearExceptionFromCallback(env, __FUNCTION__);
663 return Void();
664}
665
666Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
667 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800668 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700669 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
670 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
671 }
672
673 env->CallVoidMethod(mCallbacksObj,
674 method_reportGeofencePauseStatus,
675 geofenceId, status);
676 checkAndClearExceptionFromCallback(env, __FUNCTION__);
677 return Void();
678}
679
680Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
681 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800682 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700683 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
684 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
685 }
686
687 env->CallVoidMethod(mCallbacksObj,
688 method_reportGeofenceResumeStatus,
689 geofenceId, status);
690 checkAndClearExceptionFromCallback(env, __FUNCTION__);
691 return Void();
692}
693
694/*
695 * GnssNavigationMessageCallback interface implements the callback methods
696 * required by the IGnssNavigationMessage interface.
697 */
698struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
699 /*
700 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
701 * follow.
702 */
703 Return<void> gnssNavigationMessageCb(
704 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
705};
706
707Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
708 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800709 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700710
711 size_t dataLength = message.data.size();
712
713 std::vector<uint8_t> navigationData = message.data;
714 uint8_t* data = &(navigationData[0]);
715 if (dataLength == 0 || data == NULL) {
716 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
717 dataLength);
718 return Void();
719 }
720
721 JavaObject object(env, "android/location/GnssNavigationMessage");
722 SET(Type, static_cast<int32_t>(message.type));
723 SET(Svid, static_cast<int32_t>(message.svid));
724 SET(MessageId, static_cast<int32_t>(message.messageId));
725 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
726 object.callSetter("setData", data, dataLength);
727 SET(Status, static_cast<int32_t>(message.status));
728
729 jobject navigationMessage = object.get();
730 env->CallVoidMethod(mCallbacksObj,
731 method_reportNavigationMessages,
732 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800733 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700734 env->DeleteLocalRef(navigationMessage);
735 return Void();
736}
737
738/*
739 * GnssMeasurementCallback implements the callback methods required for the
740 * GnssMeasurement interface.
741 */
Wyatt Riley46ac9562018-03-02 20:16:58 -0800742struct GnssMeasurementCallback : public IGnssMeasurementCallback_V1_1 {
743 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800744 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700745 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800746 void translateGnssMeasurement_V1_0(
747 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800748 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700749 jobjectArray translateGnssMeasurements(
750 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800751 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800752 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700753 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800754 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800755 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700756 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
757};
758
759
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800760Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800761 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800762 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700763
764 jobject clock;
765 jobjectArray measurementArray;
766
767 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800768
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700769 measurementArray = translateGnssMeasurements(
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800770 env, data.measurements.data(), NULL, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700771 setMeasurementData(env, clock, measurementArray);
772
773 env->DeleteLocalRef(clock);
774 env->DeleteLocalRef(measurementArray);
775 return Void();
776}
777
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800778Return<void> GnssMeasurementCallback::GnssMeasurementCb(
779 const IGnssMeasurementCallback_V1_0::GnssData& data) {
780 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800781
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800782 jobject clock;
783 jobjectArray measurementArray;
784
785 clock = translateGnssClock(env, &data.clock);
786 measurementArray = translateGnssMeasurements(
787 env, NULL, data.measurements.data(), data.measurementCount);
788 setMeasurementData(env, clock, measurementArray);
789
790 env->DeleteLocalRef(clock);
791 env->DeleteLocalRef(measurementArray);
792 return Void();
793}
794
795// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
796void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
797 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800798 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700799 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700800
801 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800802 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700803 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800804 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700805 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800806 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700807 measurement->receivedSvTimeUncertaintyInNs);
808 SET(Cn0DbHz, measurement->cN0DbHz);
809 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800810 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700811 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800812 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800813 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
814 !ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700815 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800816 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700817 measurement->accumulatedDeltaRangeUncertaintyM);
818
819 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
820 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
821 }
822
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800823 // Intentionally not copying deprecated fields of carrierCycles,
824 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700825
826 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
827
828 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
829 SET(SnrInDb, measurement->snrDb);
830 }
Lifu Tang120480f2016-02-07 18:08:19 -0800831
gomo4402af62017-01-11 13:20:13 -0800832 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800833 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800834 }
Lifu Tang120480f2016-02-07 18:08:19 -0800835}
836
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700837jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800838 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700839 JavaObject object(env, "android/location/GnssClock");
840
841 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
842 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
843 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
844 }
845
846 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
847 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
848 }
849
850 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
851 SET(FullBiasNanos, clock->fullBiasNs);
852 }
853
854 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
855 SET(BiasNanos, clock->biasNs);
856 }
857
858 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
859 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
860 }
861
862 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
863 SET(DriftNanosPerSecond, clock->driftNsps);
864 }
865
866 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
867 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
868 }
869
870 SET(TimeNanos, clock->timeNs);
871 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
872
873 return object.get();
874}
875
876jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800877 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800878 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
879 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800880 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700881 return NULL;
882 }
883
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700884 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800885 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800886 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800887 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700888 NULL /* initialElement */);
889
Lifu Tang120480f2016-02-07 18:08:19 -0800890 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800891 JavaObject object(env, "android/location/GnssMeasurement");
Wyatt Riley46ac9562018-03-02 20:16:58 -0800892 if (measurements_v1_1 != NULL) {
893 translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800894
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800895 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800896 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800897 (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
898 ADR_STATE_HALF_CYCLE_REPORTED));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800899 } else {
900 translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
901 }
902
903 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700904 }
905
Lifu Tang818aa2c2016-02-01 01:52:00 -0800906 env->DeleteLocalRef(gnssMeasurementClass);
907 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700908}
909
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700910void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
911 jobjectArray measurementArray) {
912 jclass gnssMeasurementsEventClass =
913 env->FindClass("android/location/GnssMeasurementsEvent");
914 jmethodID gnssMeasurementsEventCtor =
915 env->GetMethodID(
916 gnssMeasurementsEventClass,
917 "<init>",
918 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800919
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700920 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
921 gnssMeasurementsEventCtor,
922 clock,
923 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800924
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700925 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
926 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800927 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800928 env->DeleteLocalRef(gnssMeasurementsEventClass);
929 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700930}
931
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700932/*
933 * GnssNiCallback implements callback methods required by the IGnssNi interface.
934 */
935struct GnssNiCallback : public IGnssNiCallback {
936 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
937 override;
destradaaea8a8a62014-06-23 18:19:03 -0700938};
939
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700940Return<void> GnssNiCallback::niNotifyCb(
941 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800942 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
944 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
945
946 if (requestorId && text) {
947 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
948 notification.notificationId, notification.niType,
949 notification.notifyFlags, notification.timeoutSec,
950 notification.defaultResponse, requestorId, text,
951 notification.requestorIdEncoding,
952 notification.notificationIdEncoding);
953 } else {
954 ALOGE("%s: OOM Error\n", __func__);
955 }
956
957 if (requestorId) {
958 env->DeleteLocalRef(requestorId);
959 }
960
961 if (text) {
962 env->DeleteLocalRef(text);
963 }
964 checkAndClearExceptionFromCallback(env, __FUNCTION__);
965 return Void();
966}
967
968/*
969 * AGnssCallback implements callback methods required by the IAGnss interface.
970 */
971struct AGnssCallback : public IAGnssCallback {
972 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
973 Return<void> agnssStatusIpV6Cb(
974 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
975
976 Return<void> agnssStatusIpV4Cb(
977 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
978 private:
979 jbyteArray convertToIpV4(uint32_t ip);
980};
981
982Return<void> AGnssCallback::agnssStatusIpV6Cb(
983 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800984 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700985 jbyteArray byteArray = NULL;
986 bool isSupported = false;
987
988 byteArray = env->NewByteArray(16);
989 if (byteArray != NULL) {
990 env->SetByteArrayRegion(byteArray, 0, 16,
991 (const jbyte*)(agps_status.ipV6Addr.data()));
992 isSupported = true;
993 } else {
994 ALOGE("Unable to allocate byte array for IPv6 address.");
995 }
996
997 IF_ALOGD() {
998 // log the IP for reference in case there is a bogus value pushed by HAL
999 char str[INET6_ADDRSTRLEN];
1000 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1001 ALOGD("AGPS IP is v6: %s", str);
1002 }
1003
1004 jsize byteArrayLength = 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
1015 return Void();
1016}
1017
1018Return<void> AGnssCallback::agnssStatusIpV4Cb(
1019 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001020 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001021 jbyteArray byteArray = NULL;
1022
1023 uint32_t ipAddr = agps_status.ipV4Addr;
1024 byteArray = convertToIpV4(ipAddr);
1025
1026 IF_ALOGD() {
1027 /*
1028 * log the IP for reference in case there is a bogus value pushed by
1029 * HAL.
1030 */
1031 char str[INET_ADDRSTRLEN];
1032 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1033 ALOGD("AGPS IP is v4: %s", str);
1034 }
1035
1036 jsize byteArrayLength =
1037 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1038 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1039 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1040 agps_status.type, agps_status.status, byteArray);
1041
1042 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1043
1044 if (byteArray) {
1045 env->DeleteLocalRef(byteArray);
1046 }
1047 return Void();
1048}
1049
1050jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1051 if (INADDR_NONE == ip) {
1052 return NULL;
1053 }
1054
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001055 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001056 jbyteArray byteArray = env->NewByteArray(4);
1057 if (byteArray == NULL) {
1058 ALOGE("Unable to allocate byte array for IPv4 address");
1059 return NULL;
1060 }
1061
1062 jbyte ipv4[4];
1063 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1064 memcpy(ipv4, &ip, sizeof(ipv4));
1065 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1066 return byteArray;
1067}
1068
1069/*
1070 * AGnssRilCallback implements the callback methods required by the AGnssRil
1071 * interface.
1072 */
1073struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001074 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001075 Return<void> requestRefLocCb() override;
1076};
1077
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001078Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001079 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001080 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1081 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1082 return Void();
1083}
1084
1085Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001086 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001087 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1088 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1089 return Void();
1090}
1091
Wyatt Rileycf879db2017-01-12 13:57:38 -08001092/*
1093 * GnssBatchingCallback interface implements the callback methods
1094 * required by the IGnssBatching interface.
1095 */
1096struct GnssBatchingCallback : public IGnssBatchingCallback {
1097 /*
1098 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1099 * follow.
1100 */
1101 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001102 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001103 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001104};
1105
1106Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001107 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001108 JNIEnv* env = getJniEnv();
1109
1110 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1111 env->FindClass("android/location/Location"), nullptr);
1112
1113 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001114 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001115 env->SetObjectArrayElement(jLocations, i, jLocation);
1116 env->DeleteLocalRef(jLocation);
1117 }
1118
1119 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1120 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1121
1122 env->DeleteLocalRef(jLocations);
1123
1124 return Void();
1125}
1126
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001127static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001128 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1129 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001130 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001131 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001132 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1133 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1134 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1135 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001136 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1137 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001138 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1139 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1140 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001141 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001142 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1143 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1144 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1145 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001146 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001147 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001148 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001149 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1150 "(II)V");
1151 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1152 "(II)V");
1153 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1154 "(II)V");
1155 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1156 "(II)V");
1157 method_reportMeasurementData = env->GetMethodID(
1158 clazz,
1159 "reportMeasurementData",
1160 "(Landroid/location/GnssMeasurementsEvent;)V");
1161 method_reportNavigationMessages = env->GetMethodID(
1162 clazz,
1163 "reportNavigationMessage",
1164 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001165 method_reportLocationBatch = env->GetMethodID(
1166 clazz,
1167 "reportLocationBatch",
1168 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001169
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001170 /*
1171 * Save a pointer to JVM.
1172 */
1173 jint jvmStatus = env->GetJavaVM(&sJvm);
1174 if (jvmStatus != JNI_OK) {
1175 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1176 }
1177
gomo48f1a642017-11-10 20:35:46 -08001178 // TODO(b/31632518)
1179 gnssHal_V1_1 = IGnss_V1_1::getService();
1180 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001181 ALOGD("gnssHal 1.1 was null, trying 1.0");
Wyatt Riley46ac9562018-03-02 20:16:58 -08001182 gnssHal = IGnss_V1_0::getService();
gomo48f1a642017-11-10 20:35:46 -08001183 } else {
1184 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001185 }
1186
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001187 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001188 gnssHalDeathRecipient = new GnssDeathRecipient();
1189 hardware::Return<bool> linked = gnssHal->linkToDeath(
1190 gnssHalDeathRecipient, /*cookie*/ 0);
1191 if (!linked.isOk()) {
1192 ALOGE("Transaction error in linking to GnssHAL death: %s",
1193 linked.description().c_str());
1194 } else if (!linked) {
1195 ALOGW("Unable to link to GnssHal death notifications");
1196 } else {
1197 ALOGD("Link to death notification successful");
1198 }
1199
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001200 auto gnssXtra = gnssHal->getExtensionXtra();
1201 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001202 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001203 } else {
1204 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001205 }
1206
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001207 auto gnssRil = gnssHal->getExtensionAGnssRil();
1208 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001209 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001210 } else {
1211 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001212 }
1213
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001214 auto gnssAgnss = gnssHal->getExtensionAGnss();
1215 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001216 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001217 } else {
1218 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001219 }
1220
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001221 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1222 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001223 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001224 } else {
1225 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001226 }
1227
gomo48f1a642017-11-10 20:35:46 -08001228 if (gnssHal_V1_1 != nullptr) {
1229 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1230 if (!gnssMeasurement.isOk()) {
1231 ALOGD("Unable to get a handle to GnssMeasurement");
1232 } else {
1233 gnssMeasurementIface_V1_1 = gnssMeasurement;
1234 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1235 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001236 } else {
gomo48f1a642017-11-10 20:35:46 -08001237 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1238 if (!gnssMeasurement_V1_0.isOk()) {
1239 ALOGD("Unable to get a handle to GnssMeasurement");
1240 } else {
1241 gnssMeasurementIface = gnssMeasurement_V1_0;
1242 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001243 }
1244
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001245 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1246 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001247 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001248 } else {
1249 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001250 }
1251
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001252 auto gnssNi = gnssHal->getExtensionGnssNi();
1253 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001254 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001255 } else {
1256 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001257 }
1258
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001259 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1260 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001261 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001262 } else {
1263 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001264 }
1265
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001266 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1267 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001268 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001269 } else {
1270 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001271 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001272
1273 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1274 if (!gnssBatching.isOk()) {
1275 ALOGD("Unable to get a handle to gnssBatching");
1276 } else {
1277 gnssBatchingIface = gnssBatching;
1278 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001279 } else {
1280 ALOGE("Unable to get GPS service\n");
1281 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001282}
1283
1284static jboolean android_location_GnssLocationProvider_is_supported(
1285 JNIEnv* /* env */, jclass /* clazz */) {
1286 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1287}
1288
1289static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1290 JNIEnv* /* env */, jclass /* clazz */) {
1291 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1292}
1293
1294static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1295 JNIEnv* /* env */, jclass /* jclazz */) {
1296 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1297}
1298
1299static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1300 /*
1301 * This must be set before calling into the HAL library.
1302 */
1303 if (!mCallbacksObj)
1304 mCallbacksObj = env->NewGlobalRef(obj);
1305
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001306 /*
1307 * Fail if the main interface fails to initialize
1308 */
1309 if (gnssHal == nullptr) {
1310 ALOGE("Unable to Initialize GNSS HAL\n");
1311 return JNI_FALSE;
1312 }
1313
Wyatt Rileyfb840922017-11-08 15:07:58 -08001314 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1315
1316 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001317 if (gnssHal_V1_1 != nullptr) {
1318 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001319 } else {
1320 result = gnssHal->setCallback(gnssCbIface);
1321 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001322 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001323 ALOGE("SetCallback for Gnss Interface fails\n");
1324 return JNI_FALSE;
1325 }
1326
1327 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1328 if (gnssXtraIface == nullptr) {
1329 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001330 } else {
1331 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001332 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001333 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001334 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001335 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001336 }
1337
1338 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1339 if (agnssIface != nullptr) {
1340 agnssIface->setCallback(aGnssCbIface);
1341 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001342 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001343 }
1344
1345 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1346 if (gnssGeofencingIface != nullptr) {
1347 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1348 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001349 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001350 }
1351
1352 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001353 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001354 gnssNiIface->setCallback(gnssNiCbIface);
1355 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001356 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001357 }
1358
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001359 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1360 if (agnssRilIface != nullptr) {
1361 agnssRilIface->setCallback(aGnssRilCbIface);
1362 } else {
1363 ALOGI("Unable to Initialize AGnss Ril interface\n");
1364 }
1365
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001366 return JNI_TRUE;
1367}
1368
1369static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1370 if (gnssHal != nullptr) {
1371 gnssHal->cleanup();
1372 }
1373}
1374
1375static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1376 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001377 jint preferred_time, jboolean low_power_mode) {
1378 Return<bool> result = false;
1379 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001380 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1381 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1382 min_interval,
1383 preferred_accuracy,
1384 preferred_time,
1385 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001386 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001387 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1388 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1389 min_interval,
1390 preferred_accuracy,
1391 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001392 }
1393 if (!result.isOk()) {
1394 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1395 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001396 } else {
gomo48f1a642017-11-10 20:35:46 -08001397 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001398 }
1399}
1400
1401static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1402 if (gnssHal != nullptr) {
1403 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001404 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001405 return JNI_FALSE;
1406 } else {
1407 return result;
1408 }
1409 } else {
1410 return JNI_FALSE;
1411 }
1412}
1413
1414static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1415 if (gnssHal != nullptr) {
1416 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001417 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001418 return JNI_FALSE;
1419 } else {
1420 return result;
1421 }
1422 } else {
1423 return JNI_FALSE;
1424 }
1425}
1426static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1427 jobject /* obj */,
1428 jint flags) {
1429 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001430 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001431 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432 ALOGE("Error in deleting aiding data");
1433 }
1434 }
1435}
1436
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001437static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1438 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1439 IAGnssRil::AGnssRefLocation location;
1440
1441 if (agnssRilIface == nullptr) {
1442 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1443 return;
1444 }
1445
1446 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1447 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1448 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1449 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1450 location.cellID.mcc = mcc;
1451 location.cellID.mnc = mnc;
1452 location.cellID.lac = lac;
1453 location.cellID.cid = cid;
1454 break;
1455 default:
1456 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1457 return;
1458 break;
1459 }
1460
1461 agnssRilIface->setRefLocation(location);
1462}
1463
1464static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1465 jint type, jstring setid_string) {
1466 if (agnssRilIface == nullptr) {
1467 ALOGE("no AGPS RIL interface in agps_set_id");
1468 return;
1469 }
1470
1471 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1472 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1473 env->ReleaseStringUTFChars(setid_string, setid);
1474}
1475
1476static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1477 jbyteArray nmeaArray, jint buffer_size) {
1478 // this should only be called from within a call to reportNmea
1479 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1480 int length = GnssCallback::sNmeaStringLength;
1481 if (length > buffer_size)
1482 length = buffer_size;
1483 memcpy(nmea, GnssCallback::sNmeaString, length);
1484 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1485 return (jint) length;
1486}
1487
1488static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1489 jlong time, jlong timeReference, jint uncertainty) {
1490 if (gnssHal != nullptr) {
1491 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001492 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001493 ALOGE("%s: Gnss injectTime() failed", __func__);
1494 }
1495 }
1496}
1497
Yu-Han Yange7baef32018-02-09 13:58:17 -08001498static void android_location_GnssLocationProvider_inject_best_location(
1499 JNIEnv*,
1500 jobject,
1501 jint gnssLocationFlags,
1502 jdouble latitudeDegrees,
1503 jdouble longitudeDegrees,
1504 jdouble altitudeMeters,
1505 jfloat speedMetersPerSec,
1506 jfloat bearingDegrees,
1507 jfloat horizontalAccuracyMeters,
1508 jfloat verticalAccuracyMeters,
1509 jfloat speedAccuracyMetersPerSecond,
1510 jfloat bearingAccuracyDegrees,
1511 jlong timestamp) {
1512 if (gnssHal_V1_1 != nullptr) {
1513 GnssLocation location = createGnssLocation(
1514 gnssLocationFlags,
1515 latitudeDegrees,
1516 longitudeDegrees,
1517 altitudeMeters,
1518 speedMetersPerSec,
1519 bearingDegrees,
1520 horizontalAccuracyMeters,
1521 verticalAccuracyMeters,
1522 speedAccuracyMetersPerSecond,
1523 bearingAccuracyDegrees,
1524 timestamp);
1525 auto result = gnssHal_V1_1->injectBestLocation(location);
1526 if (!result.isOk() || !result) {
1527 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1528 }
1529 } else {
1530 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1531 }
1532}
1533
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001534static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1535 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1536 if (gnssHal != nullptr) {
1537 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001538 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001539 ALOGE("%s: Gnss injectLocation() failed", __func__);
1540 }
1541 }
1542}
1543
1544static jboolean android_location_GnssLocationProvider_supports_xtra(
1545 JNIEnv* /* env */, jobject /* obj */) {
1546 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1547}
1548
1549static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1550 jbyteArray data, jint length) {
1551 if (gnssXtraIface == nullptr) {
1552 ALOGE("XTRA Interface not supported");
1553 return;
1554 }
1555
1556 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1557 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1558 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1559}
1560
1561static void android_location_GnssLocationProvider_agps_data_conn_open(
1562 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1563 if (agnssIface == nullptr) {
1564 ALOGE("no AGPS interface in agps_data_conn_open");
1565 return;
1566 }
1567 if (apn == NULL) {
1568 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1569 return;
1570 }
1571
1572 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1573
1574 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001575 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001576 ALOGE("%s: Failed to set APN and its IP type", __func__);
1577 }
1578 env->ReleaseStringUTFChars(apn, apnStr);
1579}
1580
1581static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1582 jobject /* obj */) {
1583 if (agnssIface == nullptr) {
1584 ALOGE("%s: AGPS interface not supported", __func__);
1585 return;
1586 }
1587
1588 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001589 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001590 ALOGE("%s: Failed to close AGnss data connection", __func__);
1591 }
1592}
1593
1594static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1595 jobject /* obj */) {
1596 if (agnssIface == nullptr) {
1597 ALOGE("%s: AGPS interface not supported", __func__);
1598 return;
1599 }
1600
1601 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001602 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1604 }
1605}
1606
1607static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1608 jint type, jstring hostname, jint port) {
1609 if (agnssIface == nullptr) {
1610 ALOGE("no AGPS interface in set_agps_server");
1611 return;
1612 }
1613
1614 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1615 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1616 c_hostname,
1617 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001618 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001619 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1620 }
1621
1622 env->ReleaseStringUTFChars(hostname, c_hostname);
1623}
1624
1625static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1626 jobject /* obj */, jint notifId, jint response) {
1627 if (gnssNiIface == nullptr) {
1628 ALOGE("no NI interface in send_ni_response");
1629 return;
1630 }
1631
1632 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1633}
1634
1635static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1636 jobject /* obj */) {
1637 jstring result = NULL;
1638 /*
1639 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1640 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001641
1642 std::stringstream internalState;
1643
1644 if (gnssDebugIface == nullptr) {
1645 internalState << "Gnss Debug Interface not available" << std::endl;
1646 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001647 IGnssDebug::DebugData data;
1648 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1649 data = debugData;
1650 });
1651
Wyatt Riley268c6e02017-03-29 10:21:46 -07001652 internalState << "Gnss Location Data:: ";
1653 if (!data.position.valid) {
1654 internalState << "not valid";
1655 } else {
1656 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001657 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1658 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001659 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1660 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001661 << ", horizontalAccuracyMeters: "
1662 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001663 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001664 << ", speedAccuracyMetersPerSecond: "
1665 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001666 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001667 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001668 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001669 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001670
Wyatt Riley268c6e02017-03-29 10:21:46 -07001671 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1672 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1673 << ", frequencyUncertaintyNsPerSec: "
1674 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001675
1676 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001677 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1678 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001679 }
1680
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001681 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1682 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1683 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1684 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001685 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1686 internalState << "svid: " << data.satelliteDataArray[i].svid
1687 << ", constellation: "
1688 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1689 << ", ephemerisType: "
1690 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001691 << ", ephemerisSource: "
1692 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1693 << ", ephemerisHealth: "
1694 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1695 << ", serverPredictionIsAvailable: "
1696 << data.satelliteDataArray[i].serverPredictionIsAvailable
1697 << ", serverPredictionAgeSeconds: "
1698 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001699 << ", ephemerisAgeSeconds: "
1700 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1701 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001702 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001703
1704 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 return result;
1706}
1707
1708static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1709 jobject /* obj */,
1710 jboolean connected,
1711 jint type,
1712 jboolean roaming,
1713 jboolean available,
1714 jstring extraInfo,
1715 jstring apn) {
1716 if (agnssRilIface != nullptr) {
1717 auto result = agnssRilIface->updateNetworkState(connected,
1718 static_cast<IAGnssRil::NetworkType>(type),
1719 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001720 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001721 ALOGE("updateNetworkState failed");
1722 }
1723
1724 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1725 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001726 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001727 ALOGE("updateNetworkAvailability failed");
1728 }
1729
1730 env->ReleaseStringUTFChars(apn, c_apn);
1731 } else {
1732 ALOGE("AGnssRilInterface does not exist");
1733 }
1734}
1735
1736static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1737 JNIEnv* /* env */, jobject /* obj */) {
1738 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1739}
1740
1741static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1742 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1743 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1744 jint unknown_timer) {
1745 if (gnssGeofencingIface != nullptr) {
1746 auto result = gnssGeofencingIface->addGeofence(
1747 geofenceId, latitude, longitude, radius,
1748 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1749 monitor_transition, notification_responsiveness, unknown_timer);
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
1757static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1758 jobject /* obj */, jint geofenceId) {
1759 if (gnssGeofencingIface != nullptr) {
1760 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001761 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001762 } else {
1763 ALOGE("Geofence interface not available");
1764 }
1765 return JNI_FALSE;
1766}
1767
1768static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1769 jobject /* obj */, jint geofenceId) {
1770 if (gnssGeofencingIface != nullptr) {
1771 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001772 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001773 } else {
1774 ALOGE("Geofence interface not available");
1775 }
1776 return JNI_FALSE;
1777}
1778
1779static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1780 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1781 if (gnssGeofencingIface != nullptr) {
1782 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001783 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001784 } else {
1785 ALOGE("Geofence interface not available");
1786 }
1787 return JNI_FALSE;
1788}
1789
Lifu Tang30f95a72016-01-07 23:20:38 -08001790static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001791 JNIEnv* env, jclass clazz) {
1792 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001793 return JNI_TRUE;
1794 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001795
destradaaea8a8a62014-06-23 18:19:03 -07001796 return JNI_FALSE;
1797}
1798
Lifu Tang30f95a72016-01-07 23:20:38 -08001799static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001800 JNIEnv* /* env */,
1801 jobject /* obj */,
1802 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 if (gnssMeasurementIface == nullptr) {
1804 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001805 return JNI_FALSE;
1806 }
1807
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001808 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001809 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1810 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1811 if (gnssMeasurementIface_V1_1 != nullptr) {
1812 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1813 enableFullTracking);
1814 } else {
1815 if (enableFullTracking == JNI_TRUE) {
1816 // full tracking mode not supported in 1.0 HAL
1817 return JNI_FALSE;
1818 }
1819 result = gnssMeasurementIface->setCallback(cbIface);
1820 }
1821
1822 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001823 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1824 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001825 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001826 } else {
1827 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001828 }
1829
1830 return JNI_TRUE;
1831}
1832
Lifu Tang30f95a72016-01-07 23:20:38 -08001833static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001834 JNIEnv* env,
1835 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001836 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001837 ALOGE("Measurement interface not available");
1838 return JNI_FALSE;
1839 }
1840
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001841 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001842 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001843}
1844
Lifu Tang30f95a72016-01-07 23:20:38 -08001845static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001846 JNIEnv* env,
1847 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001848 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001849 return JNI_TRUE;
1850 }
1851 return JNI_FALSE;
1852}
1853
Lifu Tang30f95a72016-01-07 23:20:38 -08001854static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001855 JNIEnv* env,
1856 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001857 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001858 ALOGE("Navigation Message interface is not available.");
1859 return JNI_FALSE;
1860 }
1861
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001862 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1863 new GnssNavigationMessageCallback();
1864 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1865 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1866
1867 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1868 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001869 return JNI_FALSE;
1870 }
1871
1872 return JNI_TRUE;
1873}
1874
Lifu Tang30f95a72016-01-07 23:20:38 -08001875static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001876 JNIEnv* env,
1877 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001878 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001879 ALOGE("Navigation Message interface is not available.");
1880 return JNI_FALSE;
1881 }
1882
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001883 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001884 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001885}
1886
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001887static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1888 jobject,
1889 jint emergencySuplPdn) {
1890 if (gnssConfigurationIface == nullptr) {
1891 ALOGE("no GNSS configuration interface available");
1892 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001893 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001894
1895 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001896 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001897 return result;
1898 } else {
1899 return JNI_FALSE;
1900 }
1901}
1902
1903static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1904 jobject,
1905 jint version) {
1906 if (gnssConfigurationIface == nullptr) {
1907 ALOGE("no GNSS configuration interface available");
1908 return JNI_FALSE;
1909 }
1910 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001911 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001912 return result;
1913 } else {
1914 return JNI_FALSE;
1915 }
1916}
1917
1918static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1919 jobject,
1920 jint suplEs) {
1921 if (gnssConfigurationIface == nullptr) {
1922 ALOGE("no GNSS configuration interface available");
1923 return JNI_FALSE;
1924 }
1925
1926 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001927 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001928 return result;
1929 } else {
1930 return JNI_FALSE;
1931 }
1932}
1933
1934static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1935 jobject,
1936 jint mode) {
1937 if (gnssConfigurationIface == nullptr) {
1938 ALOGE("no GNSS configuration interface available");
1939 return JNI_FALSE;
1940 }
1941
1942 auto result = gnssConfigurationIface->setSuplMode(mode);
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_gps_lock(JNIEnv*,
1951 jobject,
1952 jint gpsLock) {
1953 if (gnssConfigurationIface == nullptr) {
1954 ALOGE("no GNSS configuration interface available");
1955 return JNI_FALSE;
1956 }
1957
1958 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
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 }
1964}
1965
1966static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1967 jobject,
1968 jint lppProfile) {
1969 if (gnssConfigurationIface == nullptr) {
1970 ALOGE("no GNSS configuration interface available");
1971 return JNI_FALSE;
1972 }
1973
1974 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1975
Steven Morelandd002a8b2017-01-03 17:18:24 -08001976 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001977 return result;
1978 } else {
1979 return JNI_FALSE;
1980 }
1981}
1982
1983static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1984 jobject,
1985 jint gnssPosProtocol) {
1986 if (gnssConfigurationIface == nullptr) {
1987 ALOGE("no GNSS configuration interface available");
1988 return JNI_FALSE;
1989 }
1990
1991 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001992 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001993 return result;
1994 } else {
1995 return JNI_FALSE;
1996 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001997}
1998
Wyatt Rileycf879db2017-01-12 13:57:38 -08001999static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
2000 if (gnssBatchingIface == nullptr) {
2001 return 0; // batching not supported, size = 0
2002 }
2003 auto result = gnssBatchingIface->getBatchSize();
2004 if (result.isOk()) {
2005 return static_cast<jint>(result);
2006 } else {
2007 return 0; // failure in binder, don't support batching
2008 }
2009}
2010
2011static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
2012 if (gnssBatchingIface == nullptr) {
2013 return JNI_FALSE; // batching not supported
2014 }
2015 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2016
2017 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2018}
2019
2020static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
2021 if (gnssBatchingIface == nullptr) {
2022 return; // batching not supported
2023 }
2024 gnssBatchingIface->cleanup();
2025}
2026
2027static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
2028 jlong periodNanos, jboolean wakeOnFifoFull) {
2029 if (gnssBatchingIface == nullptr) {
2030 return JNI_FALSE; // batching not supported
2031 }
2032
2033 IGnssBatching::Options options;
2034 options.periodNanos = periodNanos;
2035 if (wakeOnFifoFull) {
2036 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2037 } else {
2038 options.flags = 0;
2039 }
2040
2041 return static_cast<jboolean>(gnssBatchingIface->start(options));
2042}
2043
2044static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
2045 if (gnssBatchingIface == nullptr) {
2046 return; // batching not supported
2047 }
2048
2049 gnssBatchingIface->flush();
2050}
2051
2052static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
2053 if (gnssBatchingIface == nullptr) {
2054 return JNI_FALSE; // batching not supported
2055 }
2056
2057 return gnssBatchingIface->stop();
2058}
2059
Daniel Micay76f6a862015-09-19 17:31:01 -04002060static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002061 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002062 {"class_init_native", "()V", reinterpret_cast<void *>(
2063 android_location_GnssLocationProvider_class_init_native)},
2064 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2065 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002066 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002067 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002068 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002069 reinterpret_cast<void *>(
2070 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
2071 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2072 {"native_cleanup", "()V", reinterpret_cast<void *>(
2073 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002074 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002075 "(IIIIIZ)Z",
2076 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002077 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2078 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002079 {"native_delete_aiding_data",
2080 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002081 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002082 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2083 android_location_GnssLocationProvider_read_nmea)},
2084 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2085 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002086 {"native_inject_best_location",
2087 "(IDDDFFFFFFJ)V",
2088 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002089 {"native_inject_location",
2090 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002091 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2092 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2093 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002094 {"native_inject_xtra_data",
2095 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002096 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002097 {"native_agps_data_conn_open",
2098 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002099 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002100 {"native_agps_data_conn_closed",
2101 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002102 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002103 {"native_agps_data_conn_failed",
2104 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002105 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002106 {"native_agps_set_id",
2107 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002108 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002109 {"native_agps_set_ref_location_cellid",
2110 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002111 reinterpret_cast<void *>(
2112 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002113 {"native_set_agps_server",
2114 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002115 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002116 {"native_send_ni_response",
2117 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002118 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002119 {"native_get_internal_state",
2120 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002121 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002122 {"native_update_network_state",
2123 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002124 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002125 {"native_is_geofence_supported",
2126 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002127 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002128 {"native_add_geofence",
2129 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002130 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002131 {"native_remove_geofence",
2132 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002133 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2134 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2135 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002136 {"native_resume_geofence",
2137 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002138 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002139 {"native_is_measurement_supported",
2140 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002141 reinterpret_cast<void *>(
2142 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002143 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002144 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002145 reinterpret_cast<void *>(
2146 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002147 {"native_stop_measurement_collection",
2148 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002149 reinterpret_cast<void *>(
2150 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002151 {"native_is_navigation_message_supported",
2152 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002153 reinterpret_cast<void *>(
2154 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002155 {"native_start_navigation_message_collection",
2156 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002157 reinterpret_cast<void *>(
2158 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002159 {"native_stop_navigation_message_collection",
2160 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002161 reinterpret_cast<void *>(
2162 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2163 {"native_set_supl_es",
2164 "(I)Z",
2165 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2166 {"native_set_supl_version",
2167 "(I)Z",
2168 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2169 {"native_set_supl_mode",
2170 "(I)Z",
2171 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2172 {"native_set_lpp_profile",
2173 "(I)Z",
2174 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2175 {"native_set_gnss_pos_protocol_select",
2176 "(I)Z",
2177 reinterpret_cast<void *>(
2178 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2179 {"native_set_gps_lock",
2180 "(I)Z",
2181 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2182 {"native_set_emergency_supl_pdn",
2183 "(I)Z",
2184 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002185 {"native_get_batch_size",
2186 "()I",
2187 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2188 {"native_init_batching",
2189 "()Z",
2190 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2191 {"native_start_batch",
2192 "(JZ)Z",
2193 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2194 {"native_flush_batch",
2195 "()V",
2196 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2197 {"native_stop_batch",
2198 "()Z",
2199 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2200 {"native_init_batching",
2201 "()Z",
2202 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2203 {"native_cleanup_batching",
2204 "()V",
2205 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206};
2207
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002208int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002209 return jniRegisterNativeMethods(
2210 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002211 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002212 sMethods,
2213 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002214}
2215
2216} /* namespace android */