blob: cf42c0cd00effe8749b8bd170cf34ecb9f0d8fd0 [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
gomo25208882017-04-15 02:05:25 -0700128sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800129sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800130sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700131sp<IGnssXtra> gnssXtraIface = nullptr;
132sp<IAGnssRil> agnssRilIface = nullptr;
133sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
134sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800135sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700136sp<IGnssDebug> gnssDebugIface = nullptr;
137sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
138sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800139sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
140sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700141sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400143#define WAKE_LOCK_NAME "GPS"
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145namespace android {
146
Lifu Tang120480f2016-02-07 18:08:19 -0800147template<class T>
148class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700149 public:
150 // Helper function to call setter on a Java object.
151 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800152 JNIEnv* env,
153 jclass clazz,
154 jobject object,
155 const char* method_name,
156 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700157
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700158 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800159 static const char *const signature_;
160};
Lifu Tange5a0e212016-01-25 18:02:17 -0800161
Lifu Tang120480f2016-02-07 18:08:19 -0800162template<class T>
163void JavaMethodHelper<T>::callJavaMethod(
164 JNIEnv* env,
165 jclass clazz,
166 jobject object,
167 const char* method_name,
168 T value) {
169 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
170 env->CallVoidMethod(object, method, value);
171}
destradaaea8a8a62014-06-23 18:19:03 -0700172
Lifu Tang120480f2016-02-07 18:08:19 -0800173class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700174 public:
175 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800176 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700177 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800178
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700179 template<class T>
180 void callSetter(const char* method_name, T value);
181 template<class T>
182 void callSetter(const char* method_name, T* value, size_t size);
183 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800184
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700185 private:
186 JNIEnv* env_;
187 jclass clazz_;
188 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800189};
190
191JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
192 clazz_ = env_->FindClass(class_name);
193 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
194 object_ = env_->NewObject(clazz_, ctor);
195}
196
Wyatt Rileycf879db2017-01-12 13:57:38 -0800197JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
198 clazz_ = env_->FindClass(class_name);
199 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
200 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
201}
202
Lifu Tang120480f2016-02-07 18:08:19 -0800203JavaObject::~JavaObject() {
204 env_->DeleteLocalRef(clazz_);
205}
206
207template<class T>
208void JavaObject::callSetter(const char* method_name, T value) {
209 JavaMethodHelper<T>::callJavaMethod(
210 env_, clazz_, object_, method_name, value);
211}
212
213template<>
214void JavaObject::callSetter(
215 const char* method_name, uint8_t* value, size_t size) {
216 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700217 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800218 jmethodID method = env_->GetMethodID(
219 clazz_,
220 method_name,
221 "([B)V");
222 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700223 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800224}
225
226jobject JavaObject::get() {
227 return object_;
228}
229
230// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800231template<>
232const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
233template<>
234const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
235template<>
236const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
237template<>
238const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
239template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800240const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
241template<>
242const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800243template<>
244const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
245template<>
246const char *const JavaMethodHelper<float>::signature_ = "(F)V";
247template<>
248const char *const JavaMethodHelper<double>::signature_ = "(D)V";
249template<>
250const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
251
252#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800253
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700254static inline jboolean boolToJbool(bool value) {
255 return value ? JNI_TRUE : JNI_FALSE;
256}
Lifu Tang120480f2016-02-07 18:08:19 -0800257
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700258static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
259 if (env->ExceptionCheck()) {
260 ALOGE("An exception was thrown by callback '%s'.", methodName);
261 LOGE_EX(env);
262 env->ExceptionClear();
263 }
264}
destradaaea8a8a62014-06-23 18:19:03 -0700265
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800266class ScopedJniThreadAttach {
267public:
268 ScopedJniThreadAttach() {
269 /*
270 * attachResult will also be JNI_OK if the thead was already attached to
271 * JNI before the call to AttachCurrentThread().
272 */
273 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
274 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
275 attachResult);
276 }
277
278 ~ScopedJniThreadAttach() {
279 jint detachResult = sJvm->DetachCurrentThread();
280 /*
281 * Return if the thread was already detached. Log error for any other
282 * failure.
283 */
284 if (detachResult == JNI_EDETACHED) {
285 return;
286 }
287
288 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
289 detachResult);
290 }
291
292 JNIEnv* getEnv() {
293 /*
294 * Checking validity of mEnv in case the thread was detached elsewhere.
295 */
296 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
297 return mEnv;
298 }
299
300private:
301 JNIEnv* mEnv = nullptr;
302};
303
304thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
305
306static JNIEnv* getJniEnv() {
307 JNIEnv* env = AndroidRuntime::getJNIEnv();
308
309 /*
310 * If env is nullptr, the thread is not already attached to
311 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
312 * will detach it on thread exit.
313 */
314 if (env == nullptr) {
315 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
316 env = tJniThreadAttacher->getEnv();
317 }
318
319 return env;
320}
321
Wyatt Rileyfb840922017-11-08 15:07:58 -0800322static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800323 JavaObject object(env, "android/location/Location", "gps");
324
325 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800326 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800327 SET(Latitude, location.latitudeDegrees);
328 SET(Longitude, location.longitudeDegrees);
329 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800330 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800331 SET(Altitude, location.altitudeMeters);
332 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800333 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800334 SET(Speed, location.speedMetersPerSec);
335 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 SET(Bearing, location.bearingDegrees);
338 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800339 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800340 SET(Accuracy, location.horizontalAccuracyMeters);
341 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800342 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800343 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
344 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800345 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800346 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
347 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800348 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800349 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
350 }
351 SET(Time, location.timestamp);
352
353 return object.get();
354}
355
Yu-Han Yange7baef32018-02-09 13:58:17 -0800356static GnssLocation createGnssLocation(
357 jint gnssLocationFlags,
358 jdouble latitudeDegrees,
359 jdouble longitudeDegrees,
360 jdouble altitudeMeters,
361 jfloat speedMetersPerSec,
362 jfloat bearingDegrees,
363 jfloat horizontalAccuracyMeters,
364 jfloat verticalAccuracyMeters,
365 jfloat speedAccuracyMetersPerSecond,
366 jfloat bearingAccuracyDegrees,
367 jlong timestamp) {
368 GnssLocation location;
369 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
370 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
371 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
372 location.altitudeMeters = static_cast<double>(altitudeMeters);
373 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
374 location.bearingDegrees = static_cast<float>(bearingDegrees);
375 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
376 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
377 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
378 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
379 location.timestamp = static_cast<uint64_t>(timestamp);
380
381 return location;
382}
383
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700384/*
385 * GnssCallback class implements the callback methods for IGnss interface.
386 */
387struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800388 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700389 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
390 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
391 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
392 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
393 Return<void> gnssAcquireWakelockCb() override;
394 Return<void> gnssReleaseWakelockCb() override;
395 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800396 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700397 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800398
Wyatt Rileyfb840922017-11-08 15:07:58 -0800399 // New in 1.1
400 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
401
Wyatt Riley26465d22018-02-12 13:44:24 -0800402 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 static const char* sNmeaString;
404 static size_t sNmeaStringLength;
405};
406
Wyatt Rileyfb840922017-11-08 15:07:58 -0800407Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
408 ALOGD("%s: name=%s\n", __func__, name.c_str());
409
Wyatt Rileyfb840922017-11-08 15:07:58 -0800410 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800411 jstring jstringName = env->NewStringUTF(name.c_str());
412 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800413 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800414
Wyatt Rileyfb840922017-11-08 15:07:58 -0800415 return Void();
416}
417
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700418const char* GnssCallback::sNmeaString = nullptr;
419size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700420
Wyatt Rileyfb840922017-11-08 15:07:58 -0800421Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800422 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800423
424 jobject jLocation = translateLocation(env, location);
425 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800426 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800427
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700428 env->CallVoidMethod(mCallbacksObj,
429 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800430 boolToJbool(hasLatLong),
431 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700432 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800433 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700434 return Void();
435}
436
437Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800438 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700439 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
440 checkAndClearExceptionFromCallback(env, __FUNCTION__);
441 return Void();
442}
443
444Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800445 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700446
Wyatt Riley26465d22018-02-12 13:44:24 -0800447 uint32_t listSize = svStatus.numSvs;
448 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700449 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800450 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700451 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800452 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800453 }
454
Wyatt Riley26465d22018-02-12 13:44:24 -0800455 jintArray svidWithFlagArray = env->NewIntArray(listSize);
456 jfloatArray cn0Array = env->NewFloatArray(listSize);
457 jfloatArray elevArray = env->NewFloatArray(listSize);
458 jfloatArray azimArray = env->NewFloatArray(listSize);
459 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
460
461 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
462 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
463 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
464 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
465 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
466
467 /*
468 * Read GNSS SV info.
469 */
470 for (size_t i = 0; i < listSize; ++i) {
471 enum ShiftWidth: uint8_t {
472 SVID_SHIFT_WIDTH = 8,
473 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
474 };
475
476 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
477 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
478 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
479 static_cast<uint32_t>(info.svFlag);
480 cn0s[i] = info.cN0Dbhz;
481 elev[i] = info.elevationDegrees;
482 azim[i] = info.azimuthDegrees;
483 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800484 }
destradaaea8a8a62014-06-23 18:19:03 -0700485
Wyatt Riley26465d22018-02-12 13:44:24 -0800486 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
487 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
488 env->ReleaseFloatArrayElements(elevArray, elev, 0);
489 env->ReleaseFloatArrayElements(azimArray, azim, 0);
490 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
491
492 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
493 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
494 carrierFreqArray);
495
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700496 checkAndClearExceptionFromCallback(env, __FUNCTION__);
497 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700498}
499
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700500Return<void> GnssCallback::gnssNmeaCb(
501 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800502 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700503 /*
504 * The Java code will call back to read these values.
505 * We do this to avoid creating unnecessary String objects.
506 */
507 sNmeaString = nmea.c_str();
508 sNmeaStringLength = nmea.size();
509
510 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
511 checkAndClearExceptionFromCallback(env, __FUNCTION__);
512 return Void();
513}
514
515Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
516 ALOGD("%s: %du\n", __func__, capabilities);
517
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800518 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700519 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
520 checkAndClearExceptionFromCallback(env, __FUNCTION__);
521 return Void();
522}
523
524Return<void> GnssCallback::gnssAcquireWakelockCb() {
525 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
526 return Void();
527}
528
529Return<void> GnssCallback::gnssReleaseWakelockCb() {
530 release_wake_lock(WAKE_LOCK_NAME);
531 return Void();
532}
533
534Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800535 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700536 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
537 checkAndClearExceptionFromCallback(env, __FUNCTION__);
538 return Void();
539}
540
Yu-Han Yang21988932018-01-23 15:07:37 -0800541Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800542 JNIEnv* env = getJniEnv();
543 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
544 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800545 return Void();
546}
547
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700548Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
549 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
550
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800551 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700552 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
553 info.yearOfHw);
554 checkAndClearExceptionFromCallback(env, __FUNCTION__);
555 return Void();
556}
557
558class GnssXtraCallback : public IGnssXtraCallback {
559 Return<void> downloadRequestCb() override;
560};
561
562/*
563 * GnssXtraCallback class implements the callback methods for the IGnssXtra
564 * interface.
565 */
566Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800567 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700568 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
569 checkAndClearExceptionFromCallback(env, __FUNCTION__);
570 return Void();
571}
572
573/*
574 * GnssGeofenceCallback class implements the callback methods for the
575 * IGnssGeofence interface.
576 */
577struct GnssGeofenceCallback : public IGnssGeofenceCallback {
578 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
579 Return<void> gnssGeofenceTransitionCb(
580 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800581 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700582 GeofenceTransition transition,
583 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
584 Return<void> gnssGeofenceStatusCb(
585 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800586 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700587 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
588 GeofenceStatus status) override;
589 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
590 GeofenceStatus status) override;
591 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
592 GeofenceStatus status) override;
593 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
594 GeofenceStatus status) override;
595};
596
597Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
598 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800599 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700600 GeofenceTransition transition,
601 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800602 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700603
Wyatt Riley5d229832017-02-10 17:06:00 -0800604 jobject jLocation = translateLocation(env, location);
605
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700606 env->CallVoidMethod(mCallbacksObj,
607 method_reportGeofenceTransition,
608 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800609 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700610 transition,
611 timestamp);
612
613 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800614 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700615 return Void();
616}
617
618Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
619 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800620 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800621 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800622
623 jobject jLocation = translateLocation(env, location);
624
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700625 env->CallVoidMethod(mCallbacksObj,
626 method_reportGeofenceStatus,
627 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800628 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700629 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800630 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700631 return Void();
632}
633
634Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
635 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800636 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700637 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
638 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
639 }
640
641 env->CallVoidMethod(mCallbacksObj,
642 method_reportGeofenceAddStatus,
643 geofenceId,
644 status);
645 checkAndClearExceptionFromCallback(env, __FUNCTION__);
646 return Void();
647}
648
649Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
650 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800651 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700652 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
653 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
654 }
655
656 env->CallVoidMethod(mCallbacksObj,
657 method_reportGeofenceRemoveStatus,
658 geofenceId, status);
659 checkAndClearExceptionFromCallback(env, __FUNCTION__);
660 return Void();
661}
662
663Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
664 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800665 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700666 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
667 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
668 }
669
670 env->CallVoidMethod(mCallbacksObj,
671 method_reportGeofencePauseStatus,
672 geofenceId, status);
673 checkAndClearExceptionFromCallback(env, __FUNCTION__);
674 return Void();
675}
676
677Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
678 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800679 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700680 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
681 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
682 }
683
684 env->CallVoidMethod(mCallbacksObj,
685 method_reportGeofenceResumeStatus,
686 geofenceId, status);
687 checkAndClearExceptionFromCallback(env, __FUNCTION__);
688 return Void();
689}
690
691/*
692 * GnssNavigationMessageCallback interface implements the callback methods
693 * required by the IGnssNavigationMessage interface.
694 */
695struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
696 /*
697 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
698 * follow.
699 */
700 Return<void> gnssNavigationMessageCb(
701 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
702};
703
704Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
705 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800706 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700707
708 size_t dataLength = message.data.size();
709
710 std::vector<uint8_t> navigationData = message.data;
711 uint8_t* data = &(navigationData[0]);
712 if (dataLength == 0 || data == NULL) {
713 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
714 dataLength);
715 return Void();
716 }
717
718 JavaObject object(env, "android/location/GnssNavigationMessage");
719 SET(Type, static_cast<int32_t>(message.type));
720 SET(Svid, static_cast<int32_t>(message.svid));
721 SET(MessageId, static_cast<int32_t>(message.messageId));
722 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
723 object.callSetter("setData", data, dataLength);
724 SET(Status, static_cast<int32_t>(message.status));
725
726 jobject navigationMessage = object.get();
727 env->CallVoidMethod(mCallbacksObj,
728 method_reportNavigationMessages,
729 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800730 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700731 env->DeleteLocalRef(navigationMessage);
732 return Void();
733}
734
735/*
736 * GnssMeasurementCallback implements the callback methods required for the
737 * GnssMeasurement interface.
738 */
Wyatt Riley46ac9562018-03-02 20:16:58 -0800739struct GnssMeasurementCallback : public IGnssMeasurementCallback_V1_1 {
740 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800741 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700742 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800743 void translateGnssMeasurement_V1_0(
744 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800745 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700746 jobjectArray translateGnssMeasurements(
747 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800748 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800749 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700750 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800751 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800752 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700753 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
754};
755
756
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800757Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800758 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800759 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700760
761 jobject clock;
762 jobjectArray measurementArray;
763
764 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800765
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700766 measurementArray = translateGnssMeasurements(
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800767 env, data.measurements.data(), NULL, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700768 setMeasurementData(env, clock, measurementArray);
769
770 env->DeleteLocalRef(clock);
771 env->DeleteLocalRef(measurementArray);
772 return Void();
773}
774
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800775Return<void> GnssMeasurementCallback::GnssMeasurementCb(
776 const IGnssMeasurementCallback_V1_0::GnssData& data) {
777 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800778
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800779 jobject clock;
780 jobjectArray measurementArray;
781
782 clock = translateGnssClock(env, &data.clock);
783 measurementArray = translateGnssMeasurements(
784 env, NULL, data.measurements.data(), data.measurementCount);
785 setMeasurementData(env, clock, measurementArray);
786
787 env->DeleteLocalRef(clock);
788 env->DeleteLocalRef(measurementArray);
789 return Void();
790}
791
792// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
793void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
794 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800795 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700796 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700797
798 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800799 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700800 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800801 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700802 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800803 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700804 measurement->receivedSvTimeUncertaintyInNs);
805 SET(Cn0DbHz, measurement->cN0DbHz);
806 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800807 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700808 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800809 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700810 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
811 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800812 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700813 measurement->accumulatedDeltaRangeUncertaintyM);
814
815 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
816 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
817 }
818
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800819 // Intentionally not copying deprecated fields of carrierCycles,
820 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700821
822 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
823
824 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
825 SET(SnrInDb, measurement->snrDb);
826 }
Lifu Tang120480f2016-02-07 18:08:19 -0800827
gomo4402af62017-01-11 13:20:13 -0800828 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800829 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800830 }
Lifu Tang120480f2016-02-07 18:08:19 -0800831}
832
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700833jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800834 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700835 JavaObject object(env, "android/location/GnssClock");
836
837 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
838 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
839 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
840 }
841
842 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
843 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
844 }
845
846 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
847 SET(FullBiasNanos, clock->fullBiasNs);
848 }
849
850 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
851 SET(BiasNanos, clock->biasNs);
852 }
853
854 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
855 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
856 }
857
858 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
859 SET(DriftNanosPerSecond, clock->driftNsps);
860 }
861
862 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
863 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
864 }
865
866 SET(TimeNanos, clock->timeNs);
867 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
868
869 return object.get();
870}
871
872jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800873 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800874 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
875 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800876 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700877 return NULL;
878 }
879
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700880 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800881 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800882 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800883 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700884 NULL /* initialElement */);
885
Lifu Tang120480f2016-02-07 18:08:19 -0800886 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800887 JavaObject object(env, "android/location/GnssMeasurement");
Wyatt Riley46ac9562018-03-02 20:16:58 -0800888 if (measurements_v1_1 != NULL) {
889 translateGnssMeasurement_V1_0(env, &(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800890
891 // Set the V1_1 flag
892 SET(AccumulatedDeltaRangeState,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800893 static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800894 } else {
895 translateGnssMeasurement_V1_0(env, &(measurements_v1_0[i]), object);
896 }
897
898 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700899 }
900
Lifu Tang818aa2c2016-02-01 01:52:00 -0800901 env->DeleteLocalRef(gnssMeasurementClass);
902 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700903}
904
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700905void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
906 jobjectArray measurementArray) {
907 jclass gnssMeasurementsEventClass =
908 env->FindClass("android/location/GnssMeasurementsEvent");
909 jmethodID gnssMeasurementsEventCtor =
910 env->GetMethodID(
911 gnssMeasurementsEventClass,
912 "<init>",
913 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800914
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700915 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
916 gnssMeasurementsEventCtor,
917 clock,
918 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800919
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700920 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
921 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800922 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800923 env->DeleteLocalRef(gnssMeasurementsEventClass);
924 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700925}
926
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700927/*
928 * GnssNiCallback implements callback methods required by the IGnssNi interface.
929 */
930struct GnssNiCallback : public IGnssNiCallback {
931 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
932 override;
destradaaea8a8a62014-06-23 18:19:03 -0700933};
934
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700935Return<void> GnssNiCallback::niNotifyCb(
936 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800937 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700938 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
939 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
940
941 if (requestorId && text) {
942 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
943 notification.notificationId, notification.niType,
944 notification.notifyFlags, notification.timeoutSec,
945 notification.defaultResponse, requestorId, text,
946 notification.requestorIdEncoding,
947 notification.notificationIdEncoding);
948 } else {
949 ALOGE("%s: OOM Error\n", __func__);
950 }
951
952 if (requestorId) {
953 env->DeleteLocalRef(requestorId);
954 }
955
956 if (text) {
957 env->DeleteLocalRef(text);
958 }
959 checkAndClearExceptionFromCallback(env, __FUNCTION__);
960 return Void();
961}
962
963/*
964 * AGnssCallback implements callback methods required by the IAGnss interface.
965 */
966struct AGnssCallback : public IAGnssCallback {
967 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
968 Return<void> agnssStatusIpV6Cb(
969 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
970
971 Return<void> agnssStatusIpV4Cb(
972 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
973 private:
974 jbyteArray convertToIpV4(uint32_t ip);
975};
976
977Return<void> AGnssCallback::agnssStatusIpV6Cb(
978 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800979 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700980 jbyteArray byteArray = NULL;
981 bool isSupported = false;
982
983 byteArray = env->NewByteArray(16);
984 if (byteArray != NULL) {
985 env->SetByteArrayRegion(byteArray, 0, 16,
986 (const jbyte*)(agps_status.ipV6Addr.data()));
987 isSupported = true;
988 } else {
989 ALOGE("Unable to allocate byte array for IPv6 address.");
990 }
991
992 IF_ALOGD() {
993 // log the IP for reference in case there is a bogus value pushed by HAL
994 char str[INET6_ADDRSTRLEN];
995 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
996 ALOGD("AGPS IP is v6: %s", str);
997 }
998
999 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1000 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1001 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1002 agps_status.type, agps_status.status, byteArray);
1003
1004 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1005
1006 if (byteArray) {
1007 env->DeleteLocalRef(byteArray);
1008 }
1009
1010 return Void();
1011}
1012
1013Return<void> AGnssCallback::agnssStatusIpV4Cb(
1014 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001015 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001016 jbyteArray byteArray = NULL;
1017
1018 uint32_t ipAddr = agps_status.ipV4Addr;
1019 byteArray = convertToIpV4(ipAddr);
1020
1021 IF_ALOGD() {
1022 /*
1023 * log the IP for reference in case there is a bogus value pushed by
1024 * HAL.
1025 */
1026 char str[INET_ADDRSTRLEN];
1027 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1028 ALOGD("AGPS IP is v4: %s", str);
1029 }
1030
1031 jsize byteArrayLength =
1032 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
1033 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1034 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1035 agps_status.type, agps_status.status, byteArray);
1036
1037 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1038
1039 if (byteArray) {
1040 env->DeleteLocalRef(byteArray);
1041 }
1042 return Void();
1043}
1044
1045jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1046 if (INADDR_NONE == ip) {
1047 return NULL;
1048 }
1049
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001050 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001051 jbyteArray byteArray = env->NewByteArray(4);
1052 if (byteArray == NULL) {
1053 ALOGE("Unable to allocate byte array for IPv4 address");
1054 return NULL;
1055 }
1056
1057 jbyte ipv4[4];
1058 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1059 memcpy(ipv4, &ip, sizeof(ipv4));
1060 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1061 return byteArray;
1062}
1063
1064/*
1065 * AGnssRilCallback implements the callback methods required by the AGnssRil
1066 * interface.
1067 */
1068struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001069 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001070 Return<void> requestRefLocCb() override;
1071};
1072
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001073Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001074 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001075 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1076 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1077 return Void();
1078}
1079
1080Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001081 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001082 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1083 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1084 return Void();
1085}
1086
Wyatt Rileycf879db2017-01-12 13:57:38 -08001087/*
1088 * GnssBatchingCallback interface implements the callback methods
1089 * required by the IGnssBatching interface.
1090 */
1091struct GnssBatchingCallback : public IGnssBatchingCallback {
1092 /*
1093 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1094 * follow.
1095 */
1096 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001097 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001098 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001099};
1100
1101Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001102 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001103 JNIEnv* env = getJniEnv();
1104
1105 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1106 env->FindClass("android/location/Location"), nullptr);
1107
1108 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001109 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001110 env->SetObjectArrayElement(jLocations, i, jLocation);
1111 env->DeleteLocalRef(jLocation);
1112 }
1113
1114 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1115 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1116
1117 env->DeleteLocalRef(jLocations);
1118
1119 return Void();
1120}
1121
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001122static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001123 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1124 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001125 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001126 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001127 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1128 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1129 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1130 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001131 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1132 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001133 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1134 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1135 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001136 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001137 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1138 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1139 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1140 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001141 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001142 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001143 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001144 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1145 "(II)V");
1146 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1147 "(II)V");
1148 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1149 "(II)V");
1150 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1151 "(II)V");
1152 method_reportMeasurementData = env->GetMethodID(
1153 clazz,
1154 "reportMeasurementData",
1155 "(Landroid/location/GnssMeasurementsEvent;)V");
1156 method_reportNavigationMessages = env->GetMethodID(
1157 clazz,
1158 "reportNavigationMessage",
1159 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001160 method_reportLocationBatch = env->GetMethodID(
1161 clazz,
1162 "reportLocationBatch",
1163 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001164
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001165 /*
1166 * Save a pointer to JVM.
1167 */
1168 jint jvmStatus = env->GetJavaVM(&sJvm);
1169 if (jvmStatus != JNI_OK) {
1170 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1171 }
1172
gomo48f1a642017-11-10 20:35:46 -08001173 // TODO(b/31632518)
1174 gnssHal_V1_1 = IGnss_V1_1::getService();
1175 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001176 ALOGD("gnssHal 1.1 was null, trying 1.0");
Wyatt Riley46ac9562018-03-02 20:16:58 -08001177 gnssHal = IGnss_V1_0::getService();
gomo48f1a642017-11-10 20:35:46 -08001178 } else {
1179 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001180 }
1181
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001182 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001183 gnssHalDeathRecipient = new GnssDeathRecipient();
1184 hardware::Return<bool> linked = gnssHal->linkToDeath(
1185 gnssHalDeathRecipient, /*cookie*/ 0);
1186 if (!linked.isOk()) {
1187 ALOGE("Transaction error in linking to GnssHAL death: %s",
1188 linked.description().c_str());
1189 } else if (!linked) {
1190 ALOGW("Unable to link to GnssHal death notifications");
1191 } else {
1192 ALOGD("Link to death notification successful");
1193 }
1194
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001195 auto gnssXtra = gnssHal->getExtensionXtra();
1196 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001197 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001198 } else {
1199 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001200 }
1201
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001202 auto gnssRil = gnssHal->getExtensionAGnssRil();
1203 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001204 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001205 } else {
1206 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001207 }
1208
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001209 auto gnssAgnss = gnssHal->getExtensionAGnss();
1210 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001211 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001212 } else {
1213 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001214 }
1215
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001216 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1217 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001218 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001219 } else {
1220 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001221 }
1222
gomo48f1a642017-11-10 20:35:46 -08001223 if (gnssHal_V1_1 != nullptr) {
1224 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1225 if (!gnssMeasurement.isOk()) {
1226 ALOGD("Unable to get a handle to GnssMeasurement");
1227 } else {
1228 gnssMeasurementIface_V1_1 = gnssMeasurement;
1229 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1230 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001231 } else {
gomo48f1a642017-11-10 20:35:46 -08001232 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1233 if (!gnssMeasurement_V1_0.isOk()) {
1234 ALOGD("Unable to get a handle to GnssMeasurement");
1235 } else {
1236 gnssMeasurementIface = gnssMeasurement_V1_0;
1237 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238 }
1239
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001240 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1241 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001242 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001243 } else {
1244 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001245 }
1246
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001247 auto gnssNi = gnssHal->getExtensionGnssNi();
1248 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001249 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001250 } else {
1251 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001252 }
1253
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001254 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1255 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001256 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001257 } else {
1258 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001259 }
1260
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001261 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1262 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001263 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001264 } else {
1265 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001266 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001267
1268 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1269 if (!gnssBatching.isOk()) {
1270 ALOGD("Unable to get a handle to gnssBatching");
1271 } else {
1272 gnssBatchingIface = gnssBatching;
1273 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001274 } else {
1275 ALOGE("Unable to get GPS service\n");
1276 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001277}
1278
1279static jboolean android_location_GnssLocationProvider_is_supported(
1280 JNIEnv* /* env */, jclass /* clazz */) {
1281 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1282}
1283
1284static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1285 JNIEnv* /* env */, jclass /* clazz */) {
1286 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1287}
1288
1289static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1290 JNIEnv* /* env */, jclass /* jclazz */) {
1291 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1292}
1293
1294static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1295 /*
1296 * This must be set before calling into the HAL library.
1297 */
1298 if (!mCallbacksObj)
1299 mCallbacksObj = env->NewGlobalRef(obj);
1300
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001301 /*
1302 * Fail if the main interface fails to initialize
1303 */
1304 if (gnssHal == nullptr) {
1305 ALOGE("Unable to Initialize GNSS HAL\n");
1306 return JNI_FALSE;
1307 }
1308
Wyatt Rileyfb840922017-11-08 15:07:58 -08001309 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1310
1311 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001312 if (gnssHal_V1_1 != nullptr) {
1313 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001314 } else {
1315 result = gnssHal->setCallback(gnssCbIface);
1316 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001317 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001318 ALOGE("SetCallback for Gnss Interface fails\n");
1319 return JNI_FALSE;
1320 }
1321
1322 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1323 if (gnssXtraIface == nullptr) {
1324 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001325 } else {
1326 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001327 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001328 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001329 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001330 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001331 }
1332
1333 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1334 if (agnssIface != nullptr) {
1335 agnssIface->setCallback(aGnssCbIface);
1336 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001337 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001338 }
1339
1340 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1341 if (gnssGeofencingIface != nullptr) {
1342 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1343 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001344 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001345 }
1346
1347 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001348 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001349 gnssNiIface->setCallback(gnssNiCbIface);
1350 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001351 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001352 }
1353
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001354 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1355 if (agnssRilIface != nullptr) {
1356 agnssRilIface->setCallback(aGnssRilCbIface);
1357 } else {
1358 ALOGI("Unable to Initialize AGnss Ril interface\n");
1359 }
1360
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001361 return JNI_TRUE;
1362}
1363
1364static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1365 if (gnssHal != nullptr) {
1366 gnssHal->cleanup();
1367 }
1368}
1369
1370static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1371 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001372 jint preferred_time, jboolean low_power_mode) {
1373 Return<bool> result = false;
1374 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001375 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1376 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1377 min_interval,
1378 preferred_accuracy,
1379 preferred_time,
1380 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001381 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001382 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1383 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1384 min_interval,
1385 preferred_accuracy,
1386 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001387 }
1388 if (!result.isOk()) {
1389 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1390 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001391 } else {
gomo48f1a642017-11-10 20:35:46 -08001392 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001393 }
1394}
1395
1396static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1397 if (gnssHal != nullptr) {
1398 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001399 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001400 return JNI_FALSE;
1401 } else {
1402 return result;
1403 }
1404 } else {
1405 return JNI_FALSE;
1406 }
1407}
1408
1409static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1410 if (gnssHal != nullptr) {
1411 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001412 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001413 return JNI_FALSE;
1414 } else {
1415 return result;
1416 }
1417 } else {
1418 return JNI_FALSE;
1419 }
1420}
1421static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1422 jobject /* obj */,
1423 jint flags) {
1424 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001425 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001426 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001427 ALOGE("Error in deleting aiding data");
1428 }
1429 }
1430}
1431
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1433 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1434 IAGnssRil::AGnssRefLocation location;
1435
1436 if (agnssRilIface == nullptr) {
1437 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1438 return;
1439 }
1440
1441 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1442 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1443 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1444 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1445 location.cellID.mcc = mcc;
1446 location.cellID.mnc = mnc;
1447 location.cellID.lac = lac;
1448 location.cellID.cid = cid;
1449 break;
1450 default:
1451 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1452 return;
1453 break;
1454 }
1455
1456 agnssRilIface->setRefLocation(location);
1457}
1458
1459static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1460 jint type, jstring setid_string) {
1461 if (agnssRilIface == nullptr) {
1462 ALOGE("no AGPS RIL interface in agps_set_id");
1463 return;
1464 }
1465
1466 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1467 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1468 env->ReleaseStringUTFChars(setid_string, setid);
1469}
1470
1471static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1472 jbyteArray nmeaArray, jint buffer_size) {
1473 // this should only be called from within a call to reportNmea
1474 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1475 int length = GnssCallback::sNmeaStringLength;
1476 if (length > buffer_size)
1477 length = buffer_size;
1478 memcpy(nmea, GnssCallback::sNmeaString, length);
1479 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1480 return (jint) length;
1481}
1482
1483static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1484 jlong time, jlong timeReference, jint uncertainty) {
1485 if (gnssHal != nullptr) {
1486 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001487 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001488 ALOGE("%s: Gnss injectTime() failed", __func__);
1489 }
1490 }
1491}
1492
Yu-Han Yange7baef32018-02-09 13:58:17 -08001493static void android_location_GnssLocationProvider_inject_best_location(
1494 JNIEnv*,
1495 jobject,
1496 jint gnssLocationFlags,
1497 jdouble latitudeDegrees,
1498 jdouble longitudeDegrees,
1499 jdouble altitudeMeters,
1500 jfloat speedMetersPerSec,
1501 jfloat bearingDegrees,
1502 jfloat horizontalAccuracyMeters,
1503 jfloat verticalAccuracyMeters,
1504 jfloat speedAccuracyMetersPerSecond,
1505 jfloat bearingAccuracyDegrees,
1506 jlong timestamp) {
1507 if (gnssHal_V1_1 != nullptr) {
1508 GnssLocation location = createGnssLocation(
1509 gnssLocationFlags,
1510 latitudeDegrees,
1511 longitudeDegrees,
1512 altitudeMeters,
1513 speedMetersPerSec,
1514 bearingDegrees,
1515 horizontalAccuracyMeters,
1516 verticalAccuracyMeters,
1517 speedAccuracyMetersPerSecond,
1518 bearingAccuracyDegrees,
1519 timestamp);
1520 auto result = gnssHal_V1_1->injectBestLocation(location);
1521 if (!result.isOk() || !result) {
1522 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1523 }
1524 } else {
1525 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1526 }
1527}
1528
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001529static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1530 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1531 if (gnssHal != nullptr) {
1532 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001533 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001534 ALOGE("%s: Gnss injectLocation() failed", __func__);
1535 }
1536 }
1537}
1538
1539static jboolean android_location_GnssLocationProvider_supports_xtra(
1540 JNIEnv* /* env */, jobject /* obj */) {
1541 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1542}
1543
1544static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1545 jbyteArray data, jint length) {
1546 if (gnssXtraIface == nullptr) {
1547 ALOGE("XTRA Interface not supported");
1548 return;
1549 }
1550
1551 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1552 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1553 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1554}
1555
1556static void android_location_GnssLocationProvider_agps_data_conn_open(
1557 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1558 if (agnssIface == nullptr) {
1559 ALOGE("no AGPS interface in agps_data_conn_open");
1560 return;
1561 }
1562 if (apn == NULL) {
1563 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1564 return;
1565 }
1566
1567 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1568
1569 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001570 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001571 ALOGE("%s: Failed to set APN and its IP type", __func__);
1572 }
1573 env->ReleaseStringUTFChars(apn, apnStr);
1574}
1575
1576static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1577 jobject /* obj */) {
1578 if (agnssIface == nullptr) {
1579 ALOGE("%s: AGPS interface not supported", __func__);
1580 return;
1581 }
1582
1583 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001584 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001585 ALOGE("%s: Failed to close AGnss data connection", __func__);
1586 }
1587}
1588
1589static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1590 jobject /* obj */) {
1591 if (agnssIface == nullptr) {
1592 ALOGE("%s: AGPS interface not supported", __func__);
1593 return;
1594 }
1595
1596 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001597 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001598 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1599 }
1600}
1601
1602static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1603 jint type, jstring hostname, jint port) {
1604 if (agnssIface == nullptr) {
1605 ALOGE("no AGPS interface in set_agps_server");
1606 return;
1607 }
1608
1609 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1610 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1611 c_hostname,
1612 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001613 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1615 }
1616
1617 env->ReleaseStringUTFChars(hostname, c_hostname);
1618}
1619
1620static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1621 jobject /* obj */, jint notifId, jint response) {
1622 if (gnssNiIface == nullptr) {
1623 ALOGE("no NI interface in send_ni_response");
1624 return;
1625 }
1626
1627 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1628}
1629
1630static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1631 jobject /* obj */) {
1632 jstring result = NULL;
1633 /*
1634 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1635 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001636
1637 std::stringstream internalState;
1638
1639 if (gnssDebugIface == nullptr) {
1640 internalState << "Gnss Debug Interface not available" << std::endl;
1641 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001642 IGnssDebug::DebugData data;
1643 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1644 data = debugData;
1645 });
1646
Wyatt Riley268c6e02017-03-29 10:21:46 -07001647 internalState << "Gnss Location Data:: ";
1648 if (!data.position.valid) {
1649 internalState << "not valid";
1650 } else {
1651 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001652 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1653 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001654 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1655 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001656 << ", horizontalAccuracyMeters: "
1657 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001658 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001659 << ", speedAccuracyMetersPerSecond: "
1660 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001661 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001662 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001663 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001664 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001665
Wyatt Riley268c6e02017-03-29 10:21:46 -07001666 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1667 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1668 << ", frequencyUncertaintyNsPerSec: "
1669 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001670
1671 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001672 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1673 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001674 }
1675
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001676 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1677 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1678 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1679 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1681 internalState << "svid: " << data.satelliteDataArray[i].svid
1682 << ", constellation: "
1683 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1684 << ", ephemerisType: "
1685 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001686 << ", ephemerisSource: "
1687 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1688 << ", ephemerisHealth: "
1689 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1690 << ", serverPredictionIsAvailable: "
1691 << data.satelliteDataArray[i].serverPredictionIsAvailable
1692 << ", serverPredictionAgeSeconds: "
1693 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 << ", ephemerisAgeSeconds: "
1695 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1696 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001697 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001698
1699 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001700 return result;
1701}
1702
1703static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1704 jobject /* obj */,
1705 jboolean connected,
1706 jint type,
1707 jboolean roaming,
1708 jboolean available,
1709 jstring extraInfo,
1710 jstring apn) {
1711 if (agnssRilIface != nullptr) {
1712 auto result = agnssRilIface->updateNetworkState(connected,
1713 static_cast<IAGnssRil::NetworkType>(type),
1714 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001715 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001716 ALOGE("updateNetworkState failed");
1717 }
1718
1719 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1720 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001721 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001722 ALOGE("updateNetworkAvailability failed");
1723 }
1724
1725 env->ReleaseStringUTFChars(apn, c_apn);
1726 } else {
1727 ALOGE("AGnssRilInterface does not exist");
1728 }
1729}
1730
1731static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1732 JNIEnv* /* env */, jobject /* obj */) {
1733 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1734}
1735
1736static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1737 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1738 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1739 jint unknown_timer) {
1740 if (gnssGeofencingIface != nullptr) {
1741 auto result = gnssGeofencingIface->addGeofence(
1742 geofenceId, latitude, longitude, radius,
1743 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1744 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001745 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001746 } else {
1747 ALOGE("Geofence Interface not available");
1748 }
1749 return JNI_FALSE;
1750}
1751
1752static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1753 jobject /* obj */, jint geofenceId) {
1754 if (gnssGeofencingIface != nullptr) {
1755 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001756 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001757 } else {
1758 ALOGE("Geofence interface not available");
1759 }
1760 return JNI_FALSE;
1761}
1762
1763static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1764 jobject /* obj */, jint geofenceId) {
1765 if (gnssGeofencingIface != nullptr) {
1766 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001767 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001768 } else {
1769 ALOGE("Geofence interface not available");
1770 }
1771 return JNI_FALSE;
1772}
1773
1774static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1775 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1776 if (gnssGeofencingIface != nullptr) {
1777 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001778 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001779 } else {
1780 ALOGE("Geofence interface not available");
1781 }
1782 return JNI_FALSE;
1783}
1784
Lifu Tang30f95a72016-01-07 23:20:38 -08001785static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001786 JNIEnv* env, jclass clazz) {
1787 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001788 return JNI_TRUE;
1789 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001790
destradaaea8a8a62014-06-23 18:19:03 -07001791 return JNI_FALSE;
1792}
1793
Lifu Tang30f95a72016-01-07 23:20:38 -08001794static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001795 JNIEnv* /* env */,
1796 jobject /* obj */,
1797 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001798 if (gnssMeasurementIface == nullptr) {
1799 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001800 return JNI_FALSE;
1801 }
1802
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001804 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1805 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1806 if (gnssMeasurementIface_V1_1 != nullptr) {
1807 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1808 enableFullTracking);
1809 } else {
1810 if (enableFullTracking == JNI_TRUE) {
1811 // full tracking mode not supported in 1.0 HAL
1812 return JNI_FALSE;
1813 }
1814 result = gnssMeasurementIface->setCallback(cbIface);
1815 }
1816
1817 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001818 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1819 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001820 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001821 } else {
1822 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001823 }
1824
1825 return JNI_TRUE;
1826}
1827
Lifu Tang30f95a72016-01-07 23:20:38 -08001828static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001829 JNIEnv* env,
1830 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001831 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001832 ALOGE("Measurement interface not available");
1833 return JNI_FALSE;
1834 }
1835
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001836 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001837 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001838}
1839
Lifu Tang30f95a72016-01-07 23:20:38 -08001840static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001841 JNIEnv* env,
1842 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001843 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001844 return JNI_TRUE;
1845 }
1846 return JNI_FALSE;
1847}
1848
Lifu Tang30f95a72016-01-07 23:20:38 -08001849static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001850 JNIEnv* env,
1851 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001852 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001853 ALOGE("Navigation Message interface is not available.");
1854 return JNI_FALSE;
1855 }
1856
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001857 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1858 new GnssNavigationMessageCallback();
1859 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1860 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1861
1862 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1863 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001864 return JNI_FALSE;
1865 }
1866
1867 return JNI_TRUE;
1868}
1869
Lifu Tang30f95a72016-01-07 23:20:38 -08001870static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001871 JNIEnv* env,
1872 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001873 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001874 ALOGE("Navigation Message interface is not available.");
1875 return JNI_FALSE;
1876 }
1877
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001878 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001879 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001880}
1881
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001882static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1883 jobject,
1884 jint emergencySuplPdn) {
1885 if (gnssConfigurationIface == nullptr) {
1886 ALOGE("no GNSS configuration interface available");
1887 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001888 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001889
1890 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001891 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001892 return result;
1893 } else {
1894 return JNI_FALSE;
1895 }
1896}
1897
1898static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1899 jobject,
1900 jint version) {
1901 if (gnssConfigurationIface == nullptr) {
1902 ALOGE("no GNSS configuration interface available");
1903 return JNI_FALSE;
1904 }
1905 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001906 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001907 return result;
1908 } else {
1909 return JNI_FALSE;
1910 }
1911}
1912
1913static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1914 jobject,
1915 jint suplEs) {
1916 if (gnssConfigurationIface == nullptr) {
1917 ALOGE("no GNSS configuration interface available");
1918 return JNI_FALSE;
1919 }
1920
1921 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001922 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001923 return result;
1924 } else {
1925 return JNI_FALSE;
1926 }
1927}
1928
1929static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1930 jobject,
1931 jint mode) {
1932 if (gnssConfigurationIface == nullptr) {
1933 ALOGE("no GNSS configuration interface available");
1934 return JNI_FALSE;
1935 }
1936
1937 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001938 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001939 return result;
1940 } else {
1941 return JNI_FALSE;
1942 }
1943}
1944
1945static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1946 jobject,
1947 jint gpsLock) {
1948 if (gnssConfigurationIface == nullptr) {
1949 ALOGE("no GNSS configuration interface available");
1950 return JNI_FALSE;
1951 }
1952
1953 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001954 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001955 return result;
1956 } else {
1957 return JNI_FALSE;
1958 }
1959}
1960
1961static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1962 jobject,
1963 jint lppProfile) {
1964 if (gnssConfigurationIface == nullptr) {
1965 ALOGE("no GNSS configuration interface available");
1966 return JNI_FALSE;
1967 }
1968
1969 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1970
Steven Morelandd002a8b2017-01-03 17:18:24 -08001971 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001972 return result;
1973 } else {
1974 return JNI_FALSE;
1975 }
1976}
1977
1978static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1979 jobject,
1980 jint gnssPosProtocol) {
1981 if (gnssConfigurationIface == nullptr) {
1982 ALOGE("no GNSS configuration interface available");
1983 return JNI_FALSE;
1984 }
1985
1986 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001987 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001988 return result;
1989 } else {
1990 return JNI_FALSE;
1991 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001992}
1993
Wyatt Rileycf879db2017-01-12 13:57:38 -08001994static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1995 if (gnssBatchingIface == nullptr) {
1996 return 0; // batching not supported, size = 0
1997 }
1998 auto result = gnssBatchingIface->getBatchSize();
1999 if (result.isOk()) {
2000 return static_cast<jint>(result);
2001 } else {
2002 return 0; // failure in binder, don't support batching
2003 }
2004}
2005
2006static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
2007 if (gnssBatchingIface == nullptr) {
2008 return JNI_FALSE; // batching not supported
2009 }
2010 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2011
2012 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2013}
2014
2015static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
2016 if (gnssBatchingIface == nullptr) {
2017 return; // batching not supported
2018 }
2019 gnssBatchingIface->cleanup();
2020}
2021
2022static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
2023 jlong periodNanos, jboolean wakeOnFifoFull) {
2024 if (gnssBatchingIface == nullptr) {
2025 return JNI_FALSE; // batching not supported
2026 }
2027
2028 IGnssBatching::Options options;
2029 options.periodNanos = periodNanos;
2030 if (wakeOnFifoFull) {
2031 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2032 } else {
2033 options.flags = 0;
2034 }
2035
2036 return static_cast<jboolean>(gnssBatchingIface->start(options));
2037}
2038
2039static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
2040 if (gnssBatchingIface == nullptr) {
2041 return; // batching not supported
2042 }
2043
2044 gnssBatchingIface->flush();
2045}
2046
2047static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
2048 if (gnssBatchingIface == nullptr) {
2049 return JNI_FALSE; // batching not supported
2050 }
2051
2052 return gnssBatchingIface->stop();
2053}
2054
Daniel Micay76f6a862015-09-19 17:31:01 -04002055static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002057 {"class_init_native", "()V", reinterpret_cast<void *>(
2058 android_location_GnssLocationProvider_class_init_native)},
2059 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2060 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002061 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002062 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002063 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002064 reinterpret_cast<void *>(
2065 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
2066 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2067 {"native_cleanup", "()V", reinterpret_cast<void *>(
2068 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002069 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002070 "(IIIIIZ)Z",
2071 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002072 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2073 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002074 {"native_delete_aiding_data",
2075 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002076 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002077 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2078 android_location_GnssLocationProvider_read_nmea)},
2079 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2080 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002081 {"native_inject_best_location",
2082 "(IDDDFFFFFFJ)V",
2083 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002084 {"native_inject_location",
2085 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002086 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2087 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2088 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002089 {"native_inject_xtra_data",
2090 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002091 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002092 {"native_agps_data_conn_open",
2093 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002094 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002095 {"native_agps_data_conn_closed",
2096 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002097 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002098 {"native_agps_data_conn_failed",
2099 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002100 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002101 {"native_agps_set_id",
2102 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002103 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002104 {"native_agps_set_ref_location_cellid",
2105 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002106 reinterpret_cast<void *>(
2107 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002108 {"native_set_agps_server",
2109 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002110 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002111 {"native_send_ni_response",
2112 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002113 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002114 {"native_get_internal_state",
2115 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002116 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002117 {"native_update_network_state",
2118 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002119 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002120 {"native_is_geofence_supported",
2121 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002122 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002123 {"native_add_geofence",
2124 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002125 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002126 {"native_remove_geofence",
2127 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002128 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2129 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2130 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002131 {"native_resume_geofence",
2132 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002133 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002134 {"native_is_measurement_supported",
2135 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002136 reinterpret_cast<void *>(
2137 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002138 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002139 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002140 reinterpret_cast<void *>(
2141 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002142 {"native_stop_measurement_collection",
2143 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002144 reinterpret_cast<void *>(
2145 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002146 {"native_is_navigation_message_supported",
2147 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002148 reinterpret_cast<void *>(
2149 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002150 {"native_start_navigation_message_collection",
2151 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002152 reinterpret_cast<void *>(
2153 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002154 {"native_stop_navigation_message_collection",
2155 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002156 reinterpret_cast<void *>(
2157 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2158 {"native_set_supl_es",
2159 "(I)Z",
2160 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2161 {"native_set_supl_version",
2162 "(I)Z",
2163 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2164 {"native_set_supl_mode",
2165 "(I)Z",
2166 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2167 {"native_set_lpp_profile",
2168 "(I)Z",
2169 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2170 {"native_set_gnss_pos_protocol_select",
2171 "(I)Z",
2172 reinterpret_cast<void *>(
2173 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2174 {"native_set_gps_lock",
2175 "(I)Z",
2176 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2177 {"native_set_emergency_supl_pdn",
2178 "(I)Z",
2179 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002180 {"native_get_batch_size",
2181 "()I",
2182 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2183 {"native_init_batching",
2184 "()Z",
2185 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2186 {"native_start_batch",
2187 "(JZ)Z",
2188 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2189 {"native_flush_batch",
2190 "()V",
2191 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2192 {"native_stop_batch",
2193 "()Z",
2194 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2195 {"native_init_batching",
2196 "()Z",
2197 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2198 {"native_cleanup_batching",
2199 "()V",
2200 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201};
2202
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002203int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002204 return jniRegisterNativeMethods(
2205 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002206 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002207 sMethods,
2208 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002209}
2210
2211} /* namespace android */