blob: c2771e4b931f9ba216fb1fbdd4716d2961a0c456 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lifu Tang30f95a72016-01-07 23:20:38 -080017#define LOG_TAG "GnssLocationProvider"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwoodb8d90332010-10-18 17:59:48 -040019#define LOG_NDEBUG 0
Danke Xie22d1f9f2009-08-18 18:28:45 -040020
gomo48f1a642017-11-10 20:35:46 -080021#include <android/hardware/gnss/1.0/IGnss.h>
Wyatt Rileyfb840922017-11-08 15:07:58 -080022#include <android/hardware/gnss/1.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070023
gomo48f1a642017-11-10 20:35:46 -080024#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
25#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070026#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040028#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029#include "utils/Log.h"
30#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070031#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070032#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
destradaa931a37f2014-08-12 16:36:59 -070034#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <limits>
destradaa96a14702014-06-05 11:36:30 -070036#include <linux/in.h>
37#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080038#include <pthread.h>
39#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070040#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Mike Lockwoodf602d362010-06-20 14:28:16 -070042static jobject mCallbacksObj = NULL;
43
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044static jmethodID method_reportLocation;
45static jmethodID method_reportStatus;
46static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040047static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040048static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040049static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080050static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080051static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040053static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080054static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020055static jmethodID method_requestRefLocation;
56static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040057static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070058static jmethodID method_reportGeofenceTransition;
59static jmethodID method_reportGeofenceStatus;
60static jmethodID method_reportGeofenceAddStatus;
61static jmethodID method_reportGeofenceRemoveStatus;
62static jmethodID method_reportGeofencePauseStatus;
63static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070064static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070065static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080066static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080068/*
69 * Save a pointer to JavaVm to attach/detach threads executing
70 * callback methods that need to make JNI calls.
71 */
72static JavaVM* sJvm;
73
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070074using android::OK;
75using android::sp;
gomo25208882017-04-15 02:05:25 -070076using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070077using android::status_t;
78using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070080using android::hardware::Return;
81using android::hardware::Void;
82using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070083using android::hardware::hidl_death_recipient;
84using android::hidl::base::V1_0::IBase;
Wyatt Rileyfb840922017-11-08 15:07:58 -080085using android::hardware::gnss::V1_0::GnssLocation;
86using android::hardware::gnss::V1_0::GnssLocationFlags;
gomo48f1a642017-11-10 20:35:46 -080087using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
88using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
89using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
90using android::hardware::gnss::V1_0::IGnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070091using android::hardware::gnss::V1_0::IAGnss;
92using android::hardware::gnss::V1_0::IAGnssCallback;
93using android::hardware::gnss::V1_0::IAGnssCallback;
94using android::hardware::gnss::V1_0::IAGnssRil;
95using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080096using android::hardware::gnss::V1_0::IGnssBatching;
97using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070098using android::hardware::gnss::V1_0::IGnssConfiguration;
99using android::hardware::gnss::V1_0::IGnssDebug;
100using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
101using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700102using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
103using android::hardware::gnss::V1_0::IGnssNavigationMessage;
104using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
105using android::hardware::gnss::V1_0::IGnssNi;
106using android::hardware::gnss::V1_0::IGnssNiCallback;
107using android::hardware::gnss::V1_0::IGnssXtra;
108using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800109using android::hardware::gnss::V1_1::IGnssCallback;
110
gomo25208882017-04-15 02:05:25 -0700111struct GnssDeathRecipient : virtual public hidl_death_recipient
112{
113 // hidl_death_recipient interface
114 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800115 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700116 // crashing system server process as described in go//treble-gnss-death
117 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
118 " restarting system server");
119 }
120};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700121
gomo25208882017-04-15 02:05:25 -0700122sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700123sp<IGnss> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800124sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700125sp<IGnssXtra> gnssXtraIface = nullptr;
126sp<IAGnssRil> agnssRilIface = nullptr;
127sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
128sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800129sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700130sp<IGnssDebug> gnssDebugIface = nullptr;
131sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
132sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800133sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
134sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700135sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400137#define WAKE_LOCK_NAME "GPS"
138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139namespace android {
140
Lifu Tang120480f2016-02-07 18:08:19 -0800141template<class T>
142class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700143 public:
144 // Helper function to call setter on a Java object.
145 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800146 JNIEnv* env,
147 jclass clazz,
148 jobject object,
149 const char* method_name,
150 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700151
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700152 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800153 static const char *const signature_;
154};
Lifu Tange5a0e212016-01-25 18:02:17 -0800155
Lifu Tang120480f2016-02-07 18:08:19 -0800156template<class T>
157void JavaMethodHelper<T>::callJavaMethod(
158 JNIEnv* env,
159 jclass clazz,
160 jobject object,
161 const char* method_name,
162 T value) {
163 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
164 env->CallVoidMethod(object, method, value);
165}
destradaaea8a8a62014-06-23 18:19:03 -0700166
Lifu Tang120480f2016-02-07 18:08:19 -0800167class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700168 public:
169 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800170 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700171 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800172
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700173 template<class T>
174 void callSetter(const char* method_name, T value);
175 template<class T>
176 void callSetter(const char* method_name, T* value, size_t size);
177 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800178
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700179 private:
180 JNIEnv* env_;
181 jclass clazz_;
182 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800183};
184
185JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
186 clazz_ = env_->FindClass(class_name);
187 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
188 object_ = env_->NewObject(clazz_, ctor);
189}
190
Wyatt Rileycf879db2017-01-12 13:57:38 -0800191JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
192 clazz_ = env_->FindClass(class_name);
193 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
194 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
195}
196
Lifu Tang120480f2016-02-07 18:08:19 -0800197JavaObject::~JavaObject() {
198 env_->DeleteLocalRef(clazz_);
199}
200
201template<class T>
202void JavaObject::callSetter(const char* method_name, T value) {
203 JavaMethodHelper<T>::callJavaMethod(
204 env_, clazz_, object_, method_name, value);
205}
206
207template<>
208void JavaObject::callSetter(
209 const char* method_name, uint8_t* value, size_t size) {
210 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700211 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800212 jmethodID method = env_->GetMethodID(
213 clazz_,
214 method_name,
215 "([B)V");
216 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700217 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800218}
219
220jobject JavaObject::get() {
221 return object_;
222}
223
224// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800225template<>
226const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
227template<>
228const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
229template<>
230const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
231template<>
232const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
233template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800234const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
235template<>
236const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800237template<>
238const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
239template<>
240const char *const JavaMethodHelper<float>::signature_ = "(F)V";
241template<>
242const char *const JavaMethodHelper<double>::signature_ = "(D)V";
243template<>
244const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
245
246#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800247
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700248static inline jboolean boolToJbool(bool value) {
249 return value ? JNI_TRUE : JNI_FALSE;
250}
Lifu Tang120480f2016-02-07 18:08:19 -0800251
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700252static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
253 if (env->ExceptionCheck()) {
254 ALOGE("An exception was thrown by callback '%s'.", methodName);
255 LOGE_EX(env);
256 env->ExceptionClear();
257 }
258}
destradaaea8a8a62014-06-23 18:19:03 -0700259
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800260class ScopedJniThreadAttach {
261public:
262 ScopedJniThreadAttach() {
263 /*
264 * attachResult will also be JNI_OK if the thead was already attached to
265 * JNI before the call to AttachCurrentThread().
266 */
267 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
268 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
269 attachResult);
270 }
271
272 ~ScopedJniThreadAttach() {
273 jint detachResult = sJvm->DetachCurrentThread();
274 /*
275 * Return if the thread was already detached. Log error for any other
276 * failure.
277 */
278 if (detachResult == JNI_EDETACHED) {
279 return;
280 }
281
282 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
283 detachResult);
284 }
285
286 JNIEnv* getEnv() {
287 /*
288 * Checking validity of mEnv in case the thread was detached elsewhere.
289 */
290 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
291 return mEnv;
292 }
293
294private:
295 JNIEnv* mEnv = nullptr;
296};
297
298thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
299
300static JNIEnv* getJniEnv() {
301 JNIEnv* env = AndroidRuntime::getJNIEnv();
302
303 /*
304 * If env is nullptr, the thread is not already attached to
305 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
306 * will detach it on thread exit.
307 */
308 if (env == nullptr) {
309 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
310 env = tJniThreadAttacher->getEnv();
311 }
312
313 return env;
314}
315
Wyatt Rileyfb840922017-11-08 15:07:58 -0800316static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800317 JavaObject object(env, "android/location/Location", "gps");
318
319 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800320 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800321 SET(Latitude, location.latitudeDegrees);
322 SET(Longitude, location.longitudeDegrees);
323 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800324 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800325 SET(Altitude, location.altitudeMeters);
326 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800327 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800328 SET(Speed, location.speedMetersPerSec);
329 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800330 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800331 SET(Bearing, location.bearingDegrees);
332 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800333 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800334 SET(Accuracy, location.horizontalAccuracyMeters);
335 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
338 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800339 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800340 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
341 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800342 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800343 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
344 }
345 SET(Time, location.timestamp);
346
347 return object.get();
348}
349
Yu-Han Yange7baef32018-02-09 13:58:17 -0800350static GnssLocation createGnssLocation(
351 jint gnssLocationFlags,
352 jdouble latitudeDegrees,
353 jdouble longitudeDegrees,
354 jdouble altitudeMeters,
355 jfloat speedMetersPerSec,
356 jfloat bearingDegrees,
357 jfloat horizontalAccuracyMeters,
358 jfloat verticalAccuracyMeters,
359 jfloat speedAccuracyMetersPerSecond,
360 jfloat bearingAccuracyDegrees,
361 jlong timestamp) {
362 GnssLocation location;
363 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
364 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
365 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
366 location.altitudeMeters = static_cast<double>(altitudeMeters);
367 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
368 location.bearingDegrees = static_cast<float>(bearingDegrees);
369 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
370 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
371 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
372 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
373 location.timestamp = static_cast<uint64_t>(timestamp);
374
375 return location;
376}
377
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700378/*
379 * GnssCallback class implements the callback methods for IGnss interface.
380 */
381struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800382 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700383 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
384 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
385 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
386 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
387 Return<void> gnssAcquireWakelockCb() override;
388 Return<void> gnssReleaseWakelockCb() override;
389 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800390 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700391 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800392
Wyatt Rileyfb840922017-11-08 15:07:58 -0800393 // New in 1.1
394 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
395
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700396 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
397 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
398 static size_t sGnssSvListSize;
399
400 static const char* sNmeaString;
401 static size_t sNmeaStringLength;
402};
403
Wyatt Rileyfb840922017-11-08 15:07:58 -0800404Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
405 ALOGD("%s: name=%s\n", __func__, name.c_str());
406
Wyatt Rileyfb840922017-11-08 15:07:58 -0800407 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800408 jstring jstringName = env->NewStringUTF(name.c_str());
409 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800410 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800411
Wyatt Rileyfb840922017-11-08 15:07:58 -0800412 return Void();
413}
414
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700415IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
416 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
417const char* GnssCallback::sNmeaString = nullptr;
418size_t GnssCallback::sNmeaStringLength = 0;
419size_t GnssCallback::sGnssSvListSize = 0;
420
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__);
433 return Void();
434}
435
436Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800437 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700438 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
439 checkAndClearExceptionFromCallback(env, __FUNCTION__);
440 return Void();
441}
442
443Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800444 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700445
446 sGnssSvListSize = svStatus.numSvs;
447 if (sGnssSvListSize > static_cast<uint32_t>(
448 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
449 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
450 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
451 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800452 }
453
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700454 // Copy GNSS SV info into sGnssSvList, if any.
455 if (svStatus.numSvs > 0) {
456 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800457 }
destradaaea8a8a62014-06-23 18:19:03 -0700458
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700459 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
460 checkAndClearExceptionFromCallback(env, __FUNCTION__);
461 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700462}
463
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700464Return<void> GnssCallback::gnssNmeaCb(
465 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800466 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700467 /*
468 * The Java code will call back to read these values.
469 * We do this to avoid creating unnecessary String objects.
470 */
471 sNmeaString = nmea.c_str();
472 sNmeaStringLength = nmea.size();
473
474 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
475 checkAndClearExceptionFromCallback(env, __FUNCTION__);
476 return Void();
477}
478
479Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
480 ALOGD("%s: %du\n", __func__, capabilities);
481
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800482 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700483 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
484 checkAndClearExceptionFromCallback(env, __FUNCTION__);
485 return Void();
486}
487
488Return<void> GnssCallback::gnssAcquireWakelockCb() {
489 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
490 return Void();
491}
492
493Return<void> GnssCallback::gnssReleaseWakelockCb() {
494 release_wake_lock(WAKE_LOCK_NAME);
495 return Void();
496}
497
498Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800499 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700500 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
501 checkAndClearExceptionFromCallback(env, __FUNCTION__);
502 return Void();
503}
504
Yu-Han Yang21988932018-01-23 15:07:37 -0800505Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800506 JNIEnv* env = getJniEnv();
507 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
508 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800509 return Void();
510}
511
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700512Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
513 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
514
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800515 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700516 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
517 info.yearOfHw);
518 checkAndClearExceptionFromCallback(env, __FUNCTION__);
519 return Void();
520}
521
522class GnssXtraCallback : public IGnssXtraCallback {
523 Return<void> downloadRequestCb() override;
524};
525
526/*
527 * GnssXtraCallback class implements the callback methods for the IGnssXtra
528 * interface.
529 */
530Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800531 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700532 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
533 checkAndClearExceptionFromCallback(env, __FUNCTION__);
534 return Void();
535}
536
537/*
538 * GnssGeofenceCallback class implements the callback methods for the
539 * IGnssGeofence interface.
540 */
541struct GnssGeofenceCallback : public IGnssGeofenceCallback {
542 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
543 Return<void> gnssGeofenceTransitionCb(
544 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800545 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700546 GeofenceTransition transition,
547 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
548 Return<void> gnssGeofenceStatusCb(
549 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800550 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700551 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
552 GeofenceStatus status) override;
553 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
554 GeofenceStatus status) override;
555 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
556 GeofenceStatus status) override;
557 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
558 GeofenceStatus status) override;
559};
560
561Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
562 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800563 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700564 GeofenceTransition transition,
565 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800566 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700567
Wyatt Riley5d229832017-02-10 17:06:00 -0800568 jobject jLocation = translateLocation(env, location);
569
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700570 env->CallVoidMethod(mCallbacksObj,
571 method_reportGeofenceTransition,
572 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800573 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700574 transition,
575 timestamp);
576
577 checkAndClearExceptionFromCallback(env, __FUNCTION__);
578 return Void();
579}
580
581Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
582 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800583 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800584 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800585
586 jobject jLocation = translateLocation(env, location);
587
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700588 env->CallVoidMethod(mCallbacksObj,
589 method_reportGeofenceStatus,
590 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800591 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700592 checkAndClearExceptionFromCallback(env, __FUNCTION__);
593 return Void();
594}
595
596Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
597 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800598 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700599 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
600 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
601 }
602
603 env->CallVoidMethod(mCallbacksObj,
604 method_reportGeofenceAddStatus,
605 geofenceId,
606 status);
607 checkAndClearExceptionFromCallback(env, __FUNCTION__);
608 return Void();
609}
610
611Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
612 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800613 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700614 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
615 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
616 }
617
618 env->CallVoidMethod(mCallbacksObj,
619 method_reportGeofenceRemoveStatus,
620 geofenceId, status);
621 checkAndClearExceptionFromCallback(env, __FUNCTION__);
622 return Void();
623}
624
625Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
626 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800627 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700628 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
629 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
630 }
631
632 env->CallVoidMethod(mCallbacksObj,
633 method_reportGeofencePauseStatus,
634 geofenceId, status);
635 checkAndClearExceptionFromCallback(env, __FUNCTION__);
636 return Void();
637}
638
639Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
640 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800641 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700642 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
643 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
644 }
645
646 env->CallVoidMethod(mCallbacksObj,
647 method_reportGeofenceResumeStatus,
648 geofenceId, status);
649 checkAndClearExceptionFromCallback(env, __FUNCTION__);
650 return Void();
651}
652
653/*
654 * GnssNavigationMessageCallback interface implements the callback methods
655 * required by the IGnssNavigationMessage interface.
656 */
657struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
658 /*
659 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
660 * follow.
661 */
662 Return<void> gnssNavigationMessageCb(
663 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
664};
665
666Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
667 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800668 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700669
670 size_t dataLength = message.data.size();
671
672 std::vector<uint8_t> navigationData = message.data;
673 uint8_t* data = &(navigationData[0]);
674 if (dataLength == 0 || data == NULL) {
675 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
676 dataLength);
677 return Void();
678 }
679
680 JavaObject object(env, "android/location/GnssNavigationMessage");
681 SET(Type, static_cast<int32_t>(message.type));
682 SET(Svid, static_cast<int32_t>(message.svid));
683 SET(MessageId, static_cast<int32_t>(message.messageId));
684 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
685 object.callSetter("setData", data, dataLength);
686 SET(Status, static_cast<int32_t>(message.status));
687
688 jobject navigationMessage = object.get();
689 env->CallVoidMethod(mCallbacksObj,
690 method_reportNavigationMessages,
691 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800692 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693 env->DeleteLocalRef(navigationMessage);
694 return Void();
695}
696
697/*
698 * GnssMeasurementCallback implements the callback methods required for the
699 * GnssMeasurement interface.
700 */
701struct GnssMeasurementCallback : public IGnssMeasurementCallback {
702 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
703 private:
704 jobject translateGnssMeasurement(
705 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
706 jobject translateGnssClock(
707 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
708 jobjectArray translateGnssMeasurements(
709 JNIEnv* env,
710 const IGnssMeasurementCallback::GnssMeasurement* measurements,
711 size_t count);
712 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
713};
714
715
716Return<void> GnssMeasurementCallback::GnssMeasurementCb(
717 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800718 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700719
720 jobject clock;
721 jobjectArray measurementArray;
722
723 clock = translateGnssClock(env, &data.clock);
724 measurementArray = translateGnssMeasurements(
725 env, data.measurements.data(), data.measurementCount);
726 setMeasurementData(env, clock, measurementArray);
727
728 env->DeleteLocalRef(clock);
729 env->DeleteLocalRef(measurementArray);
730 return Void();
731}
732
733jobject GnssMeasurementCallback::translateGnssMeasurement(
734 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800735 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800736
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700737 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700738
739 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800740 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700741 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800742 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700743 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800744 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700745 measurement->receivedSvTimeUncertaintyInNs);
746 SET(Cn0DbHz, measurement->cN0DbHz);
747 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800748 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700749 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800750 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700751 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
752 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800753 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700754 measurement->accumulatedDeltaRangeUncertaintyM);
755
756 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
757 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
758 }
759
760 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
761 SET(CarrierPhase, measurement->carrierPhase);
762 }
763
764 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
765 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
766 }
767
768 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
769
770 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
771 SET(SnrInDb, measurement->snrDb);
772 }
Lifu Tang120480f2016-02-07 18:08:19 -0800773
gomo4402af62017-01-11 13:20:13 -0800774 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800775 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800776 }
777
Lifu Tang120480f2016-02-07 18:08:19 -0800778 return object.get();
779}
780
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700781jobject GnssMeasurementCallback::translateGnssClock(
782 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
783 JavaObject object(env, "android/location/GnssClock");
784
785 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
786 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
787 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
788 }
789
790 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
791 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
792 }
793
794 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
795 SET(FullBiasNanos, clock->fullBiasNs);
796 }
797
798 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
799 SET(BiasNanos, clock->biasNs);
800 }
801
802 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
803 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
804 }
805
806 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
807 SET(DriftNanosPerSecond, clock->driftNsps);
808 }
809
810 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
811 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
812 }
813
814 SET(TimeNanos, clock->timeNs);
815 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
816
817 return object.get();
818}
819
820jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
821 const IGnssMeasurementCallback::GnssMeasurement*
822 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800823 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700824 return NULL;
825 }
826
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700827 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800828 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800829 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800830 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700831 NULL /* initialElement */);
832
Lifu Tang120480f2016-02-07 18:08:19 -0800833 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700834 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800835 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800836 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800837 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
838 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700839 }
840
Lifu Tang818aa2c2016-02-01 01:52:00 -0800841 env->DeleteLocalRef(gnssMeasurementClass);
842 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700843}
844
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700845void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
846 jobjectArray measurementArray) {
847 jclass gnssMeasurementsEventClass =
848 env->FindClass("android/location/GnssMeasurementsEvent");
849 jmethodID gnssMeasurementsEventCtor =
850 env->GetMethodID(
851 gnssMeasurementsEventClass,
852 "<init>",
853 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800854
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700855 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
856 gnssMeasurementsEventCtor,
857 clock,
858 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800859
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700860 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
861 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800862 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800863 env->DeleteLocalRef(gnssMeasurementsEventClass);
864 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700865}
866
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700867/*
868 * GnssNiCallback implements callback methods required by the IGnssNi interface.
869 */
870struct GnssNiCallback : public IGnssNiCallback {
871 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
872 override;
destradaaea8a8a62014-06-23 18:19:03 -0700873};
874
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700875Return<void> GnssNiCallback::niNotifyCb(
876 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800877 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700878 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
879 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
880
881 if (requestorId && text) {
882 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
883 notification.notificationId, notification.niType,
884 notification.notifyFlags, notification.timeoutSec,
885 notification.defaultResponse, requestorId, text,
886 notification.requestorIdEncoding,
887 notification.notificationIdEncoding);
888 } else {
889 ALOGE("%s: OOM Error\n", __func__);
890 }
891
892 if (requestorId) {
893 env->DeleteLocalRef(requestorId);
894 }
895
896 if (text) {
897 env->DeleteLocalRef(text);
898 }
899 checkAndClearExceptionFromCallback(env, __FUNCTION__);
900 return Void();
901}
902
903/*
904 * AGnssCallback implements callback methods required by the IAGnss interface.
905 */
906struct AGnssCallback : public IAGnssCallback {
907 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
908 Return<void> agnssStatusIpV6Cb(
909 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
910
911 Return<void> agnssStatusIpV4Cb(
912 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
913 private:
914 jbyteArray convertToIpV4(uint32_t ip);
915};
916
917Return<void> AGnssCallback::agnssStatusIpV6Cb(
918 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800919 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700920 jbyteArray byteArray = NULL;
921 bool isSupported = false;
922
923 byteArray = env->NewByteArray(16);
924 if (byteArray != NULL) {
925 env->SetByteArrayRegion(byteArray, 0, 16,
926 (const jbyte*)(agps_status.ipV6Addr.data()));
927 isSupported = true;
928 } else {
929 ALOGE("Unable to allocate byte array for IPv6 address.");
930 }
931
932 IF_ALOGD() {
933 // log the IP for reference in case there is a bogus value pushed by HAL
934 char str[INET6_ADDRSTRLEN];
935 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
936 ALOGD("AGPS IP is v6: %s", str);
937 }
938
939 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
940 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
941 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
942 agps_status.type, agps_status.status, byteArray);
943
944 checkAndClearExceptionFromCallback(env, __FUNCTION__);
945
946 if (byteArray) {
947 env->DeleteLocalRef(byteArray);
948 }
949
950 return Void();
951}
952
953Return<void> AGnssCallback::agnssStatusIpV4Cb(
954 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800955 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700956 jbyteArray byteArray = NULL;
957
958 uint32_t ipAddr = agps_status.ipV4Addr;
959 byteArray = convertToIpV4(ipAddr);
960
961 IF_ALOGD() {
962 /*
963 * log the IP for reference in case there is a bogus value pushed by
964 * HAL.
965 */
966 char str[INET_ADDRSTRLEN];
967 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
968 ALOGD("AGPS IP is v4: %s", str);
969 }
970
971 jsize byteArrayLength =
972 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
973 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
974 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
975 agps_status.type, agps_status.status, byteArray);
976
977 checkAndClearExceptionFromCallback(env, __FUNCTION__);
978
979 if (byteArray) {
980 env->DeleteLocalRef(byteArray);
981 }
982 return Void();
983}
984
985jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
986 if (INADDR_NONE == ip) {
987 return NULL;
988 }
989
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800990 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991 jbyteArray byteArray = env->NewByteArray(4);
992 if (byteArray == NULL) {
993 ALOGE("Unable to allocate byte array for IPv4 address");
994 return NULL;
995 }
996
997 jbyte ipv4[4];
998 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
999 memcpy(ipv4, &ip, sizeof(ipv4));
1000 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1001 return byteArray;
1002}
1003
1004/*
1005 * AGnssRilCallback implements the callback methods required by the AGnssRil
1006 * interface.
1007 */
1008struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001009 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001010 Return<void> requestRefLocCb() override;
1011};
1012
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001013Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001014 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001015 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1016 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1017 return Void();
1018}
1019
1020Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001021 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001022 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1023 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1024 return Void();
1025}
1026
Wyatt Rileycf879db2017-01-12 13:57:38 -08001027/*
1028 * GnssBatchingCallback interface implements the callback methods
1029 * required by the IGnssBatching interface.
1030 */
1031struct GnssBatchingCallback : public IGnssBatchingCallback {
1032 /*
1033 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1034 * follow.
1035 */
1036 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001037 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001038 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001039};
1040
1041Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001042 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001043 JNIEnv* env = getJniEnv();
1044
1045 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1046 env->FindClass("android/location/Location"), nullptr);
1047
1048 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001049 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001050 env->SetObjectArrayElement(jLocations, i, jLocation);
1051 env->DeleteLocalRef(jLocation);
1052 }
1053
1054 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1055 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1056
1057 env->DeleteLocalRef(jLocations);
1058
1059 return Void();
1060}
1061
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001062static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001063 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1064 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001065 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1066 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1067 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1068 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1069 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1070 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001071 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1072 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001073 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1074 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1075 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001076 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001077 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1078 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1079 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1080 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001081 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001082 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001083 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001084 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1085 "(II)V");
1086 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1087 "(II)V");
1088 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1089 "(II)V");
1090 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1091 "(II)V");
1092 method_reportMeasurementData = env->GetMethodID(
1093 clazz,
1094 "reportMeasurementData",
1095 "(Landroid/location/GnssMeasurementsEvent;)V");
1096 method_reportNavigationMessages = env->GetMethodID(
1097 clazz,
1098 "reportNavigationMessage",
1099 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001100 method_reportLocationBatch = env->GetMethodID(
1101 clazz,
1102 "reportLocationBatch",
1103 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001104
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001105 /*
1106 * Save a pointer to JVM.
1107 */
1108 jint jvmStatus = env->GetJavaVM(&sJvm);
1109 if (jvmStatus != JNI_OK) {
1110 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1111 }
1112
gomo48f1a642017-11-10 20:35:46 -08001113 // TODO(b/31632518)
1114 gnssHal_V1_1 = IGnss_V1_1::getService();
1115 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001116 ALOGD("gnssHal 1.1 was null, trying 1.0");
1117 gnssHal = IGnss::getService();
gomo48f1a642017-11-10 20:35:46 -08001118 } else {
1119 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001120 }
1121
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001122 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001123 gnssHalDeathRecipient = new GnssDeathRecipient();
1124 hardware::Return<bool> linked = gnssHal->linkToDeath(
1125 gnssHalDeathRecipient, /*cookie*/ 0);
1126 if (!linked.isOk()) {
1127 ALOGE("Transaction error in linking to GnssHAL death: %s",
1128 linked.description().c_str());
1129 } else if (!linked) {
1130 ALOGW("Unable to link to GnssHal death notifications");
1131 } else {
1132 ALOGD("Link to death notification successful");
1133 }
1134
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001135 auto gnssXtra = gnssHal->getExtensionXtra();
1136 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001137 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001138 } else {
1139 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001140 }
1141
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001142 auto gnssRil = gnssHal->getExtensionAGnssRil();
1143 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001144 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001145 } else {
1146 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001147 }
1148
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001149 auto gnssAgnss = gnssHal->getExtensionAGnss();
1150 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001151 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001152 } else {
1153 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001154 }
1155
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001156 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1157 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001158 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001159 } else {
1160 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001161 }
1162
gomo48f1a642017-11-10 20:35:46 -08001163 if (gnssHal_V1_1 != nullptr) {
1164 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1165 if (!gnssMeasurement.isOk()) {
1166 ALOGD("Unable to get a handle to GnssMeasurement");
1167 } else {
1168 gnssMeasurementIface_V1_1 = gnssMeasurement;
1169 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1170 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001171 } else {
gomo48f1a642017-11-10 20:35:46 -08001172 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1173 if (!gnssMeasurement_V1_0.isOk()) {
1174 ALOGD("Unable to get a handle to GnssMeasurement");
1175 } else {
1176 gnssMeasurementIface = gnssMeasurement_V1_0;
1177 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001178 }
1179
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001180 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1181 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001182 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001183 } else {
1184 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001185 }
1186
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001187 auto gnssNi = gnssHal->getExtensionGnssNi();
1188 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001189 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001190 } else {
1191 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001192 }
1193
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001194 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1195 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001196 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001197 } else {
1198 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001199 }
1200
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001201 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1202 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001203 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001204 } else {
1205 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001206 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001207
1208 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1209 if (!gnssBatching.isOk()) {
1210 ALOGD("Unable to get a handle to gnssBatching");
1211 } else {
1212 gnssBatchingIface = gnssBatching;
1213 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001214 } else {
1215 ALOGE("Unable to get GPS service\n");
1216 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001217}
1218
1219static jboolean android_location_GnssLocationProvider_is_supported(
1220 JNIEnv* /* env */, jclass /* clazz */) {
1221 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1222}
1223
1224static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1225 JNIEnv* /* env */, jclass /* clazz */) {
1226 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1227}
1228
1229static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1230 JNIEnv* /* env */, jclass /* jclazz */) {
1231 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1232}
1233
1234static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1235 /*
1236 * This must be set before calling into the HAL library.
1237 */
1238 if (!mCallbacksObj)
1239 mCallbacksObj = env->NewGlobalRef(obj);
1240
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001241 /*
1242 * Fail if the main interface fails to initialize
1243 */
1244 if (gnssHal == nullptr) {
1245 ALOGE("Unable to Initialize GNSS HAL\n");
1246 return JNI_FALSE;
1247 }
1248
Wyatt Rileyfb840922017-11-08 15:07:58 -08001249 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1250
1251 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001252 if (gnssHal_V1_1 != nullptr) {
1253 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001254 } else {
1255 result = gnssHal->setCallback(gnssCbIface);
1256 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001257 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001258 ALOGE("SetCallback for Gnss Interface fails\n");
1259 return JNI_FALSE;
1260 }
1261
1262 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1263 if (gnssXtraIface == nullptr) {
1264 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001265 } else {
1266 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001267 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001268 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001269 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001270 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001271 }
1272
1273 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1274 if (agnssIface != nullptr) {
1275 agnssIface->setCallback(aGnssCbIface);
1276 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001277 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001278 }
1279
1280 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1281 if (gnssGeofencingIface != nullptr) {
1282 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1283 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001284 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001285 }
1286
1287 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001288 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001289 gnssNiIface->setCallback(gnssNiCbIface);
1290 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001291 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001292 }
1293
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001294 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1295 if (agnssRilIface != nullptr) {
1296 agnssRilIface->setCallback(aGnssRilCbIface);
1297 } else {
1298 ALOGI("Unable to Initialize AGnss Ril interface\n");
1299 }
1300
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001301 return JNI_TRUE;
1302}
1303
1304static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1305 if (gnssHal != nullptr) {
1306 gnssHal->cleanup();
1307 }
1308}
1309
1310static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1311 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001312 jint preferred_time, jboolean low_power_mode) {
1313 Return<bool> result = false;
1314 if (gnssHal_V1_1 != nullptr) {
1315 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
1316 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1317 min_interval,
1318 preferred_accuracy,
1319 preferred_time,
1320 low_power_mode);
1321 } else if (gnssHal != nullptr) {
1322 result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1323 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1324 min_interval,
1325 preferred_accuracy,
1326 preferred_time);
1327 }
1328 if (!result.isOk()) {
1329 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1330 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001331 } else {
gomo48f1a642017-11-10 20:35:46 -08001332 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001333 }
1334}
1335
1336static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1337 if (gnssHal != nullptr) {
1338 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001339 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001340 return JNI_FALSE;
1341 } else {
1342 return result;
1343 }
1344 } else {
1345 return JNI_FALSE;
1346 }
1347}
1348
1349static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1350 if (gnssHal != nullptr) {
1351 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001352 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001353 return JNI_FALSE;
1354 } else {
1355 return result;
1356 }
1357 } else {
1358 return JNI_FALSE;
1359 }
1360}
1361static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1362 jobject /* obj */,
1363 jint flags) {
1364 if (gnssHal != nullptr) {
1365 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001366 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001367 ALOGE("Error in deleting aiding data");
1368 }
1369 }
1370}
1371
1372/*
1373 * This enum is used by the read_sv_status method to combine the svid,
1374 * constellation and svFlag fields.
1375 */
1376enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001377 SVID_SHIFT_WIDTH = 8,
1378 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001379};
1380
1381static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1382 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001383 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001384 /*
1385 * This method should only be called from within a call to reportSvStatus.
1386 */
1387 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1388 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1389 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1390 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001391 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001392
1393 /*
1394 * Read GNSS SV info.
1395 */
1396 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1397 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1398 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1399 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1400 static_cast<uint32_t>(info.svFlag);
1401 cn0s[i] = info.cN0Dbhz;
1402 elev[i] = info.elevationDegrees;
1403 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001404 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001405 }
1406
1407 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1408 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1409 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1410 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001411 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001412 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1413}
1414
1415static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1416 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1417 IAGnssRil::AGnssRefLocation location;
1418
1419 if (agnssRilIface == nullptr) {
1420 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1421 return;
1422 }
1423
1424 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1425 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1426 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1427 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1428 location.cellID.mcc = mcc;
1429 location.cellID.mnc = mnc;
1430 location.cellID.lac = lac;
1431 location.cellID.cid = cid;
1432 break;
1433 default:
1434 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1435 return;
1436 break;
1437 }
1438
1439 agnssRilIface->setRefLocation(location);
1440}
1441
1442static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1443 jint type, jstring setid_string) {
1444 if (agnssRilIface == nullptr) {
1445 ALOGE("no AGPS RIL interface in agps_set_id");
1446 return;
1447 }
1448
1449 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1450 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1451 env->ReleaseStringUTFChars(setid_string, setid);
1452}
1453
1454static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1455 jbyteArray nmeaArray, jint buffer_size) {
1456 // this should only be called from within a call to reportNmea
1457 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1458 int length = GnssCallback::sNmeaStringLength;
1459 if (length > buffer_size)
1460 length = buffer_size;
1461 memcpy(nmea, GnssCallback::sNmeaString, length);
1462 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1463 return (jint) length;
1464}
1465
1466static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1467 jlong time, jlong timeReference, jint uncertainty) {
1468 if (gnssHal != nullptr) {
1469 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001470 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001471 ALOGE("%s: Gnss injectTime() failed", __func__);
1472 }
1473 }
1474}
1475
Yu-Han Yange7baef32018-02-09 13:58:17 -08001476static void android_location_GnssLocationProvider_inject_best_location(
1477 JNIEnv*,
1478 jobject,
1479 jint gnssLocationFlags,
1480 jdouble latitudeDegrees,
1481 jdouble longitudeDegrees,
1482 jdouble altitudeMeters,
1483 jfloat speedMetersPerSec,
1484 jfloat bearingDegrees,
1485 jfloat horizontalAccuracyMeters,
1486 jfloat verticalAccuracyMeters,
1487 jfloat speedAccuracyMetersPerSecond,
1488 jfloat bearingAccuracyDegrees,
1489 jlong timestamp) {
1490 if (gnssHal_V1_1 != nullptr) {
1491 GnssLocation location = createGnssLocation(
1492 gnssLocationFlags,
1493 latitudeDegrees,
1494 longitudeDegrees,
1495 altitudeMeters,
1496 speedMetersPerSec,
1497 bearingDegrees,
1498 horizontalAccuracyMeters,
1499 verticalAccuracyMeters,
1500 speedAccuracyMetersPerSecond,
1501 bearingAccuracyDegrees,
1502 timestamp);
1503 auto result = gnssHal_V1_1->injectBestLocation(location);
1504 if (!result.isOk() || !result) {
1505 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1506 }
1507 } else {
1508 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1509 }
1510}
1511
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001512static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1513 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1514 if (gnssHal != nullptr) {
1515 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001516 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001517 ALOGE("%s: Gnss injectLocation() failed", __func__);
1518 }
1519 }
1520}
1521
1522static jboolean android_location_GnssLocationProvider_supports_xtra(
1523 JNIEnv* /* env */, jobject /* obj */) {
1524 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1525}
1526
1527static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1528 jbyteArray data, jint length) {
1529 if (gnssXtraIface == nullptr) {
1530 ALOGE("XTRA Interface not supported");
1531 return;
1532 }
1533
1534 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1535 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1536 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1537}
1538
1539static void android_location_GnssLocationProvider_agps_data_conn_open(
1540 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1541 if (agnssIface == nullptr) {
1542 ALOGE("no AGPS interface in agps_data_conn_open");
1543 return;
1544 }
1545 if (apn == NULL) {
1546 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1547 return;
1548 }
1549
1550 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1551
1552 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001553 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001554 ALOGE("%s: Failed to set APN and its IP type", __func__);
1555 }
1556 env->ReleaseStringUTFChars(apn, apnStr);
1557}
1558
1559static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1560 jobject /* obj */) {
1561 if (agnssIface == nullptr) {
1562 ALOGE("%s: AGPS interface not supported", __func__);
1563 return;
1564 }
1565
1566 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001567 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001568 ALOGE("%s: Failed to close AGnss data connection", __func__);
1569 }
1570}
1571
1572static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1573 jobject /* obj */) {
1574 if (agnssIface == nullptr) {
1575 ALOGE("%s: AGPS interface not supported", __func__);
1576 return;
1577 }
1578
1579 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001580 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001581 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1582 }
1583}
1584
1585static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1586 jint type, jstring hostname, jint port) {
1587 if (agnssIface == nullptr) {
1588 ALOGE("no AGPS interface in set_agps_server");
1589 return;
1590 }
1591
1592 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1593 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1594 c_hostname,
1595 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001596 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001597 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1598 }
1599
1600 env->ReleaseStringUTFChars(hostname, c_hostname);
1601}
1602
1603static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1604 jobject /* obj */, jint notifId, jint response) {
1605 if (gnssNiIface == nullptr) {
1606 ALOGE("no NI interface in send_ni_response");
1607 return;
1608 }
1609
1610 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1611}
1612
1613static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1614 jobject /* obj */) {
1615 jstring result = NULL;
1616 /*
1617 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1618 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001619
1620 std::stringstream internalState;
1621
1622 if (gnssDebugIface == nullptr) {
1623 internalState << "Gnss Debug Interface not available" << std::endl;
1624 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001625 IGnssDebug::DebugData data;
1626 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1627 data = debugData;
1628 });
1629
Wyatt Riley268c6e02017-03-29 10:21:46 -07001630 internalState << "Gnss Location Data:: ";
1631 if (!data.position.valid) {
1632 internalState << "not valid";
1633 } else {
1634 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001635 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1636 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001637 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1638 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001639 << ", horizontalAccuracyMeters: "
1640 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001641 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001642 << ", speedAccuracyMetersPerSecond: "
1643 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001644 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001645 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001646 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001647 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001648
Wyatt Riley268c6e02017-03-29 10:21:46 -07001649 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1650 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1651 << ", frequencyUncertaintyNsPerSec: "
1652 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001653
1654 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001655 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1656 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001657 }
1658
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001659 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1660 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1661 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1662 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001663 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1664 internalState << "svid: " << data.satelliteDataArray[i].svid
1665 << ", constellation: "
1666 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1667 << ", ephemerisType: "
1668 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001669 << ", ephemerisSource: "
1670 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1671 << ", ephemerisHealth: "
1672 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1673 << ", serverPredictionIsAvailable: "
1674 << data.satelliteDataArray[i].serverPredictionIsAvailable
1675 << ", serverPredictionAgeSeconds: "
1676 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001677 << ", ephemerisAgeSeconds: "
1678 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1679 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001680 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001681
1682 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683 return result;
1684}
1685
1686static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1687 jobject /* obj */,
1688 jboolean connected,
1689 jint type,
1690 jboolean roaming,
1691 jboolean available,
1692 jstring extraInfo,
1693 jstring apn) {
1694 if (agnssRilIface != nullptr) {
1695 auto result = agnssRilIface->updateNetworkState(connected,
1696 static_cast<IAGnssRil::NetworkType>(type),
1697 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001698 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001699 ALOGE("updateNetworkState failed");
1700 }
1701
1702 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1703 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001704 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 ALOGE("updateNetworkAvailability failed");
1706 }
1707
1708 env->ReleaseStringUTFChars(apn, c_apn);
1709 } else {
1710 ALOGE("AGnssRilInterface does not exist");
1711 }
1712}
1713
1714static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1715 JNIEnv* /* env */, jobject /* obj */) {
1716 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1717}
1718
1719static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1720 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1721 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1722 jint unknown_timer) {
1723 if (gnssGeofencingIface != nullptr) {
1724 auto result = gnssGeofencingIface->addGeofence(
1725 geofenceId, latitude, longitude, radius,
1726 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1727 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001728 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001729 } else {
1730 ALOGE("Geofence Interface not available");
1731 }
1732 return JNI_FALSE;
1733}
1734
1735static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1736 jobject /* obj */, jint geofenceId) {
1737 if (gnssGeofencingIface != nullptr) {
1738 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001739 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001740 } else {
1741 ALOGE("Geofence interface not available");
1742 }
1743 return JNI_FALSE;
1744}
1745
1746static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1747 jobject /* obj */, jint geofenceId) {
1748 if (gnssGeofencingIface != nullptr) {
1749 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001750 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001751 } else {
1752 ALOGE("Geofence interface not available");
1753 }
1754 return JNI_FALSE;
1755}
1756
1757static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1758 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1759 if (gnssGeofencingIface != nullptr) {
1760 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001761 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001762 } else {
1763 ALOGE("Geofence interface not available");
1764 }
1765 return JNI_FALSE;
1766}
1767
Lifu Tang30f95a72016-01-07 23:20:38 -08001768static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001769 JNIEnv* env, jclass clazz) {
1770 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001771 return JNI_TRUE;
1772 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001773
destradaaea8a8a62014-06-23 18:19:03 -07001774 return JNI_FALSE;
1775}
1776
Lifu Tang30f95a72016-01-07 23:20:38 -08001777static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001778 JNIEnv* /* env */,
1779 jobject /* obj */,
1780 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001781 if (gnssMeasurementIface == nullptr) {
1782 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001783 return JNI_FALSE;
1784 }
1785
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001786 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001787 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1788 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1789 if (gnssMeasurementIface_V1_1 != nullptr) {
1790 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1791 enableFullTracking);
1792 } else {
1793 if (enableFullTracking == JNI_TRUE) {
1794 // full tracking mode not supported in 1.0 HAL
1795 return JNI_FALSE;
1796 }
1797 result = gnssMeasurementIface->setCallback(cbIface);
1798 }
1799
1800 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001801 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1802 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001803 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001804 } else {
1805 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001806 }
1807
1808 return JNI_TRUE;
1809}
1810
Lifu Tang30f95a72016-01-07 23:20:38 -08001811static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001812 JNIEnv* env,
1813 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001814 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001815 ALOGE("Measurement interface not available");
1816 return JNI_FALSE;
1817 }
1818
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001819 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001820 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001821}
1822
Lifu Tang30f95a72016-01-07 23:20:38 -08001823static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001824 JNIEnv* env,
1825 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001826 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001827 return JNI_TRUE;
1828 }
1829 return JNI_FALSE;
1830}
1831
Lifu Tang30f95a72016-01-07 23:20:38 -08001832static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001833 JNIEnv* env,
1834 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001835 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001836 ALOGE("Navigation Message interface is not available.");
1837 return JNI_FALSE;
1838 }
1839
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001840 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1841 new GnssNavigationMessageCallback();
1842 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1843 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1844
1845 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1846 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001847 return JNI_FALSE;
1848 }
1849
1850 return JNI_TRUE;
1851}
1852
Lifu Tang30f95a72016-01-07 23:20:38 -08001853static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001854 JNIEnv* env,
1855 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001856 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001857 ALOGE("Navigation Message interface is not available.");
1858 return JNI_FALSE;
1859 }
1860
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001861 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001862 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001863}
1864
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001865static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1866 jobject,
1867 jint emergencySuplPdn) {
1868 if (gnssConfigurationIface == nullptr) {
1869 ALOGE("no GNSS configuration interface available");
1870 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001871 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001872
1873 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001874 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001875 return result;
1876 } else {
1877 return JNI_FALSE;
1878 }
1879}
1880
1881static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1882 jobject,
1883 jint version) {
1884 if (gnssConfigurationIface == nullptr) {
1885 ALOGE("no GNSS configuration interface available");
1886 return JNI_FALSE;
1887 }
1888 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001889 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001890 return result;
1891 } else {
1892 return JNI_FALSE;
1893 }
1894}
1895
1896static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1897 jobject,
1898 jint suplEs) {
1899 if (gnssConfigurationIface == nullptr) {
1900 ALOGE("no GNSS configuration interface available");
1901 return JNI_FALSE;
1902 }
1903
1904 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001905 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001906 return result;
1907 } else {
1908 return JNI_FALSE;
1909 }
1910}
1911
1912static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1913 jobject,
1914 jint mode) {
1915 if (gnssConfigurationIface == nullptr) {
1916 ALOGE("no GNSS configuration interface available");
1917 return JNI_FALSE;
1918 }
1919
1920 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001921 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001922 return result;
1923 } else {
1924 return JNI_FALSE;
1925 }
1926}
1927
1928static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1929 jobject,
1930 jint gpsLock) {
1931 if (gnssConfigurationIface == nullptr) {
1932 ALOGE("no GNSS configuration interface available");
1933 return JNI_FALSE;
1934 }
1935
1936 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001937 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001938 return result;
1939 } else {
1940 return JNI_FALSE;
1941 }
1942}
1943
1944static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1945 jobject,
1946 jint lppProfile) {
1947 if (gnssConfigurationIface == nullptr) {
1948 ALOGE("no GNSS configuration interface available");
1949 return JNI_FALSE;
1950 }
1951
1952 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1953
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_gnss_pos_protocol_select(JNIEnv*,
1962 jobject,
1963 jint gnssPosProtocol) {
1964 if (gnssConfigurationIface == nullptr) {
1965 ALOGE("no GNSS configuration interface available");
1966 return JNI_FALSE;
1967 }
1968
1969 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001970 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001971 return result;
1972 } else {
1973 return JNI_FALSE;
1974 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001975}
1976
Wyatt Rileycf879db2017-01-12 13:57:38 -08001977static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1978 if (gnssBatchingIface == nullptr) {
1979 return 0; // batching not supported, size = 0
1980 }
1981 auto result = gnssBatchingIface->getBatchSize();
1982 if (result.isOk()) {
1983 return static_cast<jint>(result);
1984 } else {
1985 return 0; // failure in binder, don't support batching
1986 }
1987}
1988
1989static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1990 if (gnssBatchingIface == nullptr) {
1991 return JNI_FALSE; // batching not supported
1992 }
1993 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1994
1995 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1996}
1997
1998static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1999 if (gnssBatchingIface == nullptr) {
2000 return; // batching not supported
2001 }
2002 gnssBatchingIface->cleanup();
2003}
2004
2005static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
2006 jlong periodNanos, jboolean wakeOnFifoFull) {
2007 if (gnssBatchingIface == nullptr) {
2008 return JNI_FALSE; // batching not supported
2009 }
2010
2011 IGnssBatching::Options options;
2012 options.periodNanos = periodNanos;
2013 if (wakeOnFifoFull) {
2014 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2015 } else {
2016 options.flags = 0;
2017 }
2018
2019 return static_cast<jboolean>(gnssBatchingIface->start(options));
2020}
2021
2022static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
2023 if (gnssBatchingIface == nullptr) {
2024 return; // batching not supported
2025 }
2026
2027 gnssBatchingIface->flush();
2028}
2029
2030static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
2031 if (gnssBatchingIface == nullptr) {
2032 return JNI_FALSE; // batching not supported
2033 }
2034
2035 return gnssBatchingIface->stop();
2036}
2037
Daniel Micay76f6a862015-09-19 17:31:01 -04002038static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002039 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002040 {"class_init_native", "()V", reinterpret_cast<void *>(
2041 android_location_GnssLocationProvider_class_init_native)},
2042 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2043 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002044 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002045 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07002046 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002047 reinterpret_cast<void *>(
2048 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
2049 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2050 {"native_cleanup", "()V", reinterpret_cast<void *>(
2051 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002052 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002053 "(IIIIIZ)Z",
2054 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002055 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2056 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002057 {"native_delete_aiding_data",
2058 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002059 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002060 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08002061 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002062 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
2063 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2064 android_location_GnssLocationProvider_read_nmea)},
2065 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2066 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002067 {"native_inject_best_location",
2068 "(IDDDFFFFFFJ)V",
2069 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002070 {"native_inject_location",
2071 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002072 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2073 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2074 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002075 {"native_inject_xtra_data",
2076 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002077 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002078 {"native_agps_data_conn_open",
2079 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002080 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002081 {"native_agps_data_conn_closed",
2082 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002083 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002084 {"native_agps_data_conn_failed",
2085 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002086 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002087 {"native_agps_set_id",
2088 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002089 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002090 {"native_agps_set_ref_location_cellid",
2091 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002092 reinterpret_cast<void *>(
2093 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002094 {"native_set_agps_server",
2095 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002096 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002097 {"native_send_ni_response",
2098 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002099 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002100 {"native_get_internal_state",
2101 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002102 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002103 {"native_update_network_state",
2104 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002105 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002106 {"native_is_geofence_supported",
2107 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002108 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002109 {"native_add_geofence",
2110 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002111 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002112 {"native_remove_geofence",
2113 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002114 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2115 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2116 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002117 {"native_resume_geofence",
2118 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002119 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002120 {"native_is_measurement_supported",
2121 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002122 reinterpret_cast<void *>(
2123 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002124 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002125 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002126 reinterpret_cast<void *>(
2127 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002128 {"native_stop_measurement_collection",
2129 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002130 reinterpret_cast<void *>(
2131 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002132 {"native_is_navigation_message_supported",
2133 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002134 reinterpret_cast<void *>(
2135 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002136 {"native_start_navigation_message_collection",
2137 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002138 reinterpret_cast<void *>(
2139 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002140 {"native_stop_navigation_message_collection",
2141 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002142 reinterpret_cast<void *>(
2143 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2144 {"native_set_supl_es",
2145 "(I)Z",
2146 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2147 {"native_set_supl_version",
2148 "(I)Z",
2149 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2150 {"native_set_supl_mode",
2151 "(I)Z",
2152 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2153 {"native_set_lpp_profile",
2154 "(I)Z",
2155 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2156 {"native_set_gnss_pos_protocol_select",
2157 "(I)Z",
2158 reinterpret_cast<void *>(
2159 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2160 {"native_set_gps_lock",
2161 "(I)Z",
2162 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2163 {"native_set_emergency_supl_pdn",
2164 "(I)Z",
2165 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002166 {"native_get_batch_size",
2167 "()I",
2168 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2169 {"native_init_batching",
2170 "()Z",
2171 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2172 {"native_start_batch",
2173 "(JZ)Z",
2174 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2175 {"native_flush_batch",
2176 "()V",
2177 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2178 {"native_stop_batch",
2179 "()Z",
2180 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2181 {"native_init_batching",
2182 "()Z",
2183 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2184 {"native_cleanup_batching",
2185 "()V",
2186 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187};
2188
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002189int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002190 return jniRegisterNativeMethods(
2191 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002192 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002193 sMethods,
2194 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002195}
2196
2197} /* namespace android */