blob: 246bd426e68c5abfb506cf0587c84471a4b1465e [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040052static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020053static jmethodID method_requestRefLocation;
54static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040055static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070056static jmethodID method_reportGeofenceTransition;
57static jmethodID method_reportGeofenceStatus;
58static jmethodID method_reportGeofenceAddStatus;
59static jmethodID method_reportGeofenceRemoveStatus;
60static jmethodID method_reportGeofencePauseStatus;
61static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070062static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070063static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080064static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080066/*
67 * Save a pointer to JavaVm to attach/detach threads executing
68 * callback methods that need to make JNI calls.
69 */
70static JavaVM* sJvm;
71
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070072using android::OK;
73using android::sp;
gomo25208882017-04-15 02:05:25 -070074using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070075using android::status_t;
76using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070078using android::hardware::Return;
79using android::hardware::Void;
80using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070081using android::hardware::hidl_death_recipient;
82using android::hidl::base::V1_0::IBase;
Wyatt Rileyfb840922017-11-08 15:07:58 -080083using android::hardware::gnss::V1_0::GnssLocation;
84using android::hardware::gnss::V1_0::GnssLocationFlags;
gomo48f1a642017-11-10 20:35:46 -080085using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
86using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
87using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
88using android::hardware::gnss::V1_0::IGnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070089using android::hardware::gnss::V1_0::IAGnss;
90using android::hardware::gnss::V1_0::IAGnssCallback;
91using android::hardware::gnss::V1_0::IAGnssCallback;
92using android::hardware::gnss::V1_0::IAGnssRil;
93using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080094using android::hardware::gnss::V1_0::IGnssBatching;
95using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070096using android::hardware::gnss::V1_0::IGnssConfiguration;
97using android::hardware::gnss::V1_0::IGnssDebug;
98using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
99using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700100using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
101using android::hardware::gnss::V1_0::IGnssNavigationMessage;
102using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
103using android::hardware::gnss::V1_0::IGnssNi;
104using android::hardware::gnss::V1_0::IGnssNiCallback;
105using android::hardware::gnss::V1_0::IGnssXtra;
106using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800107using android::hardware::gnss::V1_1::IGnssCallback;
108
gomo25208882017-04-15 02:05:25 -0700109struct GnssDeathRecipient : virtual public hidl_death_recipient
110{
111 // hidl_death_recipient interface
112 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800113 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700114 // crashing system server process as described in go//treble-gnss-death
115 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
116 " restarting system server");
117 }
118};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700119
gomo25208882017-04-15 02:05:25 -0700120sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700121sp<IGnss> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800122sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700123sp<IGnssXtra> gnssXtraIface = nullptr;
124sp<IAGnssRil> agnssRilIface = nullptr;
125sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
126sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800127sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700128sp<IGnssDebug> gnssDebugIface = nullptr;
129sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
130sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800131sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
132sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700133sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400135#define WAKE_LOCK_NAME "GPS"
136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137namespace android {
138
Lifu Tang120480f2016-02-07 18:08:19 -0800139template<class T>
140class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700141 public:
142 // Helper function to call setter on a Java object.
143 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800144 JNIEnv* env,
145 jclass clazz,
146 jobject object,
147 const char* method_name,
148 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700149
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700150 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800151 static const char *const signature_;
152};
Lifu Tange5a0e212016-01-25 18:02:17 -0800153
Lifu Tang120480f2016-02-07 18:08:19 -0800154template<class T>
155void JavaMethodHelper<T>::callJavaMethod(
156 JNIEnv* env,
157 jclass clazz,
158 jobject object,
159 const char* method_name,
160 T value) {
161 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
162 env->CallVoidMethod(object, method, value);
163}
destradaaea8a8a62014-06-23 18:19:03 -0700164
Lifu Tang120480f2016-02-07 18:08:19 -0800165class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700166 public:
167 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800168 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700169 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800170
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700171 template<class T>
172 void callSetter(const char* method_name, T value);
173 template<class T>
174 void callSetter(const char* method_name, T* value, size_t size);
175 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800176
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700177 private:
178 JNIEnv* env_;
179 jclass clazz_;
180 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800181};
182
183JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
184 clazz_ = env_->FindClass(class_name);
185 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
186 object_ = env_->NewObject(clazz_, ctor);
187}
188
Wyatt Rileycf879db2017-01-12 13:57:38 -0800189JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
190 clazz_ = env_->FindClass(class_name);
191 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
192 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
193}
194
Lifu Tang120480f2016-02-07 18:08:19 -0800195JavaObject::~JavaObject() {
196 env_->DeleteLocalRef(clazz_);
197}
198
199template<class T>
200void JavaObject::callSetter(const char* method_name, T value) {
201 JavaMethodHelper<T>::callJavaMethod(
202 env_, clazz_, object_, method_name, value);
203}
204
205template<>
206void JavaObject::callSetter(
207 const char* method_name, uint8_t* value, size_t size) {
208 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700209 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800210 jmethodID method = env_->GetMethodID(
211 clazz_,
212 method_name,
213 "([B)V");
214 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700215 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800216}
217
218jobject JavaObject::get() {
219 return object_;
220}
221
222// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800223template<>
224const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
225template<>
226const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
227template<>
228const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
229template<>
230const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
231template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800232const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
233template<>
234const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800235template<>
236const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
237template<>
238const char *const JavaMethodHelper<float>::signature_ = "(F)V";
239template<>
240const char *const JavaMethodHelper<double>::signature_ = "(D)V";
241template<>
242const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
243
244#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800245
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700246static inline jboolean boolToJbool(bool value) {
247 return value ? JNI_TRUE : JNI_FALSE;
248}
Lifu Tang120480f2016-02-07 18:08:19 -0800249
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700250static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
251 if (env->ExceptionCheck()) {
252 ALOGE("An exception was thrown by callback '%s'.", methodName);
253 LOGE_EX(env);
254 env->ExceptionClear();
255 }
256}
destradaaea8a8a62014-06-23 18:19:03 -0700257
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800258class ScopedJniThreadAttach {
259public:
260 ScopedJniThreadAttach() {
261 /*
262 * attachResult will also be JNI_OK if the thead was already attached to
263 * JNI before the call to AttachCurrentThread().
264 */
265 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
266 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
267 attachResult);
268 }
269
270 ~ScopedJniThreadAttach() {
271 jint detachResult = sJvm->DetachCurrentThread();
272 /*
273 * Return if the thread was already detached. Log error for any other
274 * failure.
275 */
276 if (detachResult == JNI_EDETACHED) {
277 return;
278 }
279
280 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
281 detachResult);
282 }
283
284 JNIEnv* getEnv() {
285 /*
286 * Checking validity of mEnv in case the thread was detached elsewhere.
287 */
288 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
289 return mEnv;
290 }
291
292private:
293 JNIEnv* mEnv = nullptr;
294};
295
296thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
297
298static JNIEnv* getJniEnv() {
299 JNIEnv* env = AndroidRuntime::getJNIEnv();
300
301 /*
302 * If env is nullptr, the thread is not already attached to
303 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
304 * will detach it on thread exit.
305 */
306 if (env == nullptr) {
307 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
308 env = tJniThreadAttacher->getEnv();
309 }
310
311 return env;
312}
313
Wyatt Rileyfb840922017-11-08 15:07:58 -0800314static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800315 JavaObject object(env, "android/location/Location", "gps");
316
317 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800318 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800319 SET(Latitude, location.latitudeDegrees);
320 SET(Longitude, location.longitudeDegrees);
321 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800322 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800323 SET(Altitude, location.altitudeMeters);
324 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800325 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800326 SET(Speed, location.speedMetersPerSec);
327 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800328 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800329 SET(Bearing, location.bearingDegrees);
330 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800331 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800332 SET(Accuracy, location.horizontalAccuracyMeters);
333 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800334 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800335 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
336 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800337 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800338 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
339 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800340 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800341 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
342 }
343 SET(Time, location.timestamp);
344
345 return object.get();
346}
347
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700348/*
349 * GnssCallback class implements the callback methods for IGnss interface.
350 */
351struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800352 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700353 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
354 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
355 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
356 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
357 Return<void> gnssAcquireWakelockCb() override;
358 Return<void> gnssReleaseWakelockCb() override;
359 Return<void> gnssRequestTimeCb() override;
360 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800361
Wyatt Rileyfb840922017-11-08 15:07:58 -0800362 // New in 1.1
363 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
364
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700365 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
366 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
367 static size_t sGnssSvListSize;
368
369 static const char* sNmeaString;
370 static size_t sNmeaStringLength;
371};
372
Wyatt Rileyfb840922017-11-08 15:07:58 -0800373Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
374 ALOGD("%s: name=%s\n", __func__, name.c_str());
375
376 // TODO(b/38003769): build Java code to connect to below code
377 /*
378 JNIEnv* env = getJniEnv();
379 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareName, name);
380 checkAndClearExceptionFromCallback(env, __FUNCTION__);
381 */
382 return Void();
383}
384
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700385IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
386 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
387const char* GnssCallback::sNmeaString = nullptr;
388size_t GnssCallback::sNmeaStringLength = 0;
389size_t GnssCallback::sGnssSvListSize = 0;
390
Wyatt Rileyfb840922017-11-08 15:07:58 -0800391Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800392 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800393
394 jobject jLocation = translateLocation(env, location);
395 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800396 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800397
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700398 env->CallVoidMethod(mCallbacksObj,
399 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800400 boolToJbool(hasLatLong),
401 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700402 checkAndClearExceptionFromCallback(env, __FUNCTION__);
403 return Void();
404}
405
406Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800407 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700408 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
409 checkAndClearExceptionFromCallback(env, __FUNCTION__);
410 return Void();
411}
412
413Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800414 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700415
416 sGnssSvListSize = svStatus.numSvs;
417 if (sGnssSvListSize > static_cast<uint32_t>(
418 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
419 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
420 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
421 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800422 }
423
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700424 // Copy GNSS SV info into sGnssSvList, if any.
425 if (svStatus.numSvs > 0) {
426 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800427 }
destradaaea8a8a62014-06-23 18:19:03 -0700428
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700429 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
430 checkAndClearExceptionFromCallback(env, __FUNCTION__);
431 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700432}
433
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700434Return<void> GnssCallback::gnssNmeaCb(
435 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800436 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700437 /*
438 * The Java code will call back to read these values.
439 * We do this to avoid creating unnecessary String objects.
440 */
441 sNmeaString = nmea.c_str();
442 sNmeaStringLength = nmea.size();
443
444 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
445 checkAndClearExceptionFromCallback(env, __FUNCTION__);
446 return Void();
447}
448
449Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
450 ALOGD("%s: %du\n", __func__, capabilities);
451
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800452 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700453 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
454 checkAndClearExceptionFromCallback(env, __FUNCTION__);
455 return Void();
456}
457
458Return<void> GnssCallback::gnssAcquireWakelockCb() {
459 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
460 return Void();
461}
462
463Return<void> GnssCallback::gnssReleaseWakelockCb() {
464 release_wake_lock(WAKE_LOCK_NAME);
465 return Void();
466}
467
468Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800469 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700470 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
471 checkAndClearExceptionFromCallback(env, __FUNCTION__);
472 return Void();
473}
474
475Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
476 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
477
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800478 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700479 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
480 info.yearOfHw);
481 checkAndClearExceptionFromCallback(env, __FUNCTION__);
482 return Void();
483}
484
485class GnssXtraCallback : public IGnssXtraCallback {
486 Return<void> downloadRequestCb() override;
487};
488
489/*
490 * GnssXtraCallback class implements the callback methods for the IGnssXtra
491 * interface.
492 */
493Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800494 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700495 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
496 checkAndClearExceptionFromCallback(env, __FUNCTION__);
497 return Void();
498}
499
500/*
501 * GnssGeofenceCallback class implements the callback methods for the
502 * IGnssGeofence interface.
503 */
504struct GnssGeofenceCallback : public IGnssGeofenceCallback {
505 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
506 Return<void> gnssGeofenceTransitionCb(
507 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800508 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700509 GeofenceTransition transition,
510 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
511 Return<void> gnssGeofenceStatusCb(
512 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800513 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700514 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
515 GeofenceStatus status) override;
516 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
517 GeofenceStatus status) override;
518 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
519 GeofenceStatus status) override;
520 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
521 GeofenceStatus status) override;
522};
523
524Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
525 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800526 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700527 GeofenceTransition transition,
528 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800529 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700530
Wyatt Riley5d229832017-02-10 17:06:00 -0800531 jobject jLocation = translateLocation(env, location);
532
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700533 env->CallVoidMethod(mCallbacksObj,
534 method_reportGeofenceTransition,
535 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800536 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700537 transition,
538 timestamp);
539
540 checkAndClearExceptionFromCallback(env, __FUNCTION__);
541 return Void();
542}
543
544Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
545 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800546 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800547 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800548
549 jobject jLocation = translateLocation(env, location);
550
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700551 env->CallVoidMethod(mCallbacksObj,
552 method_reportGeofenceStatus,
553 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800554 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700555 checkAndClearExceptionFromCallback(env, __FUNCTION__);
556 return Void();
557}
558
559Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
560 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800561 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700562 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
563 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
564 }
565
566 env->CallVoidMethod(mCallbacksObj,
567 method_reportGeofenceAddStatus,
568 geofenceId,
569 status);
570 checkAndClearExceptionFromCallback(env, __FUNCTION__);
571 return Void();
572}
573
574Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
575 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800576 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700577 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
578 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
579 }
580
581 env->CallVoidMethod(mCallbacksObj,
582 method_reportGeofenceRemoveStatus,
583 geofenceId, status);
584 checkAndClearExceptionFromCallback(env, __FUNCTION__);
585 return Void();
586}
587
588Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
589 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800590 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700591 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
592 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
593 }
594
595 env->CallVoidMethod(mCallbacksObj,
596 method_reportGeofencePauseStatus,
597 geofenceId, status);
598 checkAndClearExceptionFromCallback(env, __FUNCTION__);
599 return Void();
600}
601
602Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
603 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800604 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700605 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
606 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
607 }
608
609 env->CallVoidMethod(mCallbacksObj,
610 method_reportGeofenceResumeStatus,
611 geofenceId, status);
612 checkAndClearExceptionFromCallback(env, __FUNCTION__);
613 return Void();
614}
615
616/*
617 * GnssNavigationMessageCallback interface implements the callback methods
618 * required by the IGnssNavigationMessage interface.
619 */
620struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
621 /*
622 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
623 * follow.
624 */
625 Return<void> gnssNavigationMessageCb(
626 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
627};
628
629Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
630 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800631 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700632
633 size_t dataLength = message.data.size();
634
635 std::vector<uint8_t> navigationData = message.data;
636 uint8_t* data = &(navigationData[0]);
637 if (dataLength == 0 || data == NULL) {
638 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
639 dataLength);
640 return Void();
641 }
642
643 JavaObject object(env, "android/location/GnssNavigationMessage");
644 SET(Type, static_cast<int32_t>(message.type));
645 SET(Svid, static_cast<int32_t>(message.svid));
646 SET(MessageId, static_cast<int32_t>(message.messageId));
647 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
648 object.callSetter("setData", data, dataLength);
649 SET(Status, static_cast<int32_t>(message.status));
650
651 jobject navigationMessage = object.get();
652 env->CallVoidMethod(mCallbacksObj,
653 method_reportNavigationMessages,
654 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800655 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700656 env->DeleteLocalRef(navigationMessage);
657 return Void();
658}
659
660/*
661 * GnssMeasurementCallback implements the callback methods required for the
662 * GnssMeasurement interface.
663 */
664struct GnssMeasurementCallback : public IGnssMeasurementCallback {
665 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
666 private:
667 jobject translateGnssMeasurement(
668 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
669 jobject translateGnssClock(
670 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
671 jobjectArray translateGnssMeasurements(
672 JNIEnv* env,
673 const IGnssMeasurementCallback::GnssMeasurement* measurements,
674 size_t count);
675 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
676};
677
678
679Return<void> GnssMeasurementCallback::GnssMeasurementCb(
680 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800681 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700682
683 jobject clock;
684 jobjectArray measurementArray;
685
686 clock = translateGnssClock(env, &data.clock);
687 measurementArray = translateGnssMeasurements(
688 env, data.measurements.data(), data.measurementCount);
689 setMeasurementData(env, clock, measurementArray);
690
691 env->DeleteLocalRef(clock);
692 env->DeleteLocalRef(measurementArray);
693 return Void();
694}
695
696jobject GnssMeasurementCallback::translateGnssMeasurement(
697 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800698 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800699
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700700 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700701
702 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800703 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700704 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800705 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700706 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800707 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700708 measurement->receivedSvTimeUncertaintyInNs);
709 SET(Cn0DbHz, measurement->cN0DbHz);
710 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800711 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700712 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800713 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700714 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
715 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800716 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700717 measurement->accumulatedDeltaRangeUncertaintyM);
718
719 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
720 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
721 }
722
723 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
724 SET(CarrierPhase, measurement->carrierPhase);
725 }
726
727 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
728 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
729 }
730
731 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
732
733 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
734 SET(SnrInDb, measurement->snrDb);
735 }
Lifu Tang120480f2016-02-07 18:08:19 -0800736
gomo4402af62017-01-11 13:20:13 -0800737 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800738 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800739 }
740
Lifu Tang120480f2016-02-07 18:08:19 -0800741 return object.get();
742}
743
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700744jobject GnssMeasurementCallback::translateGnssClock(
745 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
746 JavaObject object(env, "android/location/GnssClock");
747
748 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
749 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
750 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
751 }
752
753 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
754 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
755 }
756
757 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
758 SET(FullBiasNanos, clock->fullBiasNs);
759 }
760
761 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
762 SET(BiasNanos, clock->biasNs);
763 }
764
765 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
766 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
767 }
768
769 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
770 SET(DriftNanosPerSecond, clock->driftNsps);
771 }
772
773 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
774 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
775 }
776
777 SET(TimeNanos, clock->timeNs);
778 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
779
780 return object.get();
781}
782
783jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
784 const IGnssMeasurementCallback::GnssMeasurement*
785 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800786 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700787 return NULL;
788 }
789
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700790 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800791 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800792 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800793 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700794 NULL /* initialElement */);
795
Lifu Tang120480f2016-02-07 18:08:19 -0800796 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700797 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800798 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800799 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800800 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
801 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700802 }
803
Lifu Tang818aa2c2016-02-01 01:52:00 -0800804 env->DeleteLocalRef(gnssMeasurementClass);
805 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700806}
807
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700808void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
809 jobjectArray measurementArray) {
810 jclass gnssMeasurementsEventClass =
811 env->FindClass("android/location/GnssMeasurementsEvent");
812 jmethodID gnssMeasurementsEventCtor =
813 env->GetMethodID(
814 gnssMeasurementsEventClass,
815 "<init>",
816 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800817
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700818 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
819 gnssMeasurementsEventCtor,
820 clock,
821 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800822
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700823 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
824 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800825 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800826 env->DeleteLocalRef(gnssMeasurementsEventClass);
827 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700828}
829
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700830/*
831 * GnssNiCallback implements callback methods required by the IGnssNi interface.
832 */
833struct GnssNiCallback : public IGnssNiCallback {
834 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
835 override;
destradaaea8a8a62014-06-23 18:19:03 -0700836};
837
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700838Return<void> GnssNiCallback::niNotifyCb(
839 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800840 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700841 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
842 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
843
844 if (requestorId && text) {
845 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
846 notification.notificationId, notification.niType,
847 notification.notifyFlags, notification.timeoutSec,
848 notification.defaultResponse, requestorId, text,
849 notification.requestorIdEncoding,
850 notification.notificationIdEncoding);
851 } else {
852 ALOGE("%s: OOM Error\n", __func__);
853 }
854
855 if (requestorId) {
856 env->DeleteLocalRef(requestorId);
857 }
858
859 if (text) {
860 env->DeleteLocalRef(text);
861 }
862 checkAndClearExceptionFromCallback(env, __FUNCTION__);
863 return Void();
864}
865
866/*
867 * AGnssCallback implements callback methods required by the IAGnss interface.
868 */
869struct AGnssCallback : public IAGnssCallback {
870 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
871 Return<void> agnssStatusIpV6Cb(
872 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
873
874 Return<void> agnssStatusIpV4Cb(
875 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
876 private:
877 jbyteArray convertToIpV4(uint32_t ip);
878};
879
880Return<void> AGnssCallback::agnssStatusIpV6Cb(
881 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800882 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700883 jbyteArray byteArray = NULL;
884 bool isSupported = false;
885
886 byteArray = env->NewByteArray(16);
887 if (byteArray != NULL) {
888 env->SetByteArrayRegion(byteArray, 0, 16,
889 (const jbyte*)(agps_status.ipV6Addr.data()));
890 isSupported = true;
891 } else {
892 ALOGE("Unable to allocate byte array for IPv6 address.");
893 }
894
895 IF_ALOGD() {
896 // log the IP for reference in case there is a bogus value pushed by HAL
897 char str[INET6_ADDRSTRLEN];
898 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
899 ALOGD("AGPS IP is v6: %s", str);
900 }
901
902 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
903 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
904 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
905 agps_status.type, agps_status.status, byteArray);
906
907 checkAndClearExceptionFromCallback(env, __FUNCTION__);
908
909 if (byteArray) {
910 env->DeleteLocalRef(byteArray);
911 }
912
913 return Void();
914}
915
916Return<void> AGnssCallback::agnssStatusIpV4Cb(
917 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800918 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700919 jbyteArray byteArray = NULL;
920
921 uint32_t ipAddr = agps_status.ipV4Addr;
922 byteArray = convertToIpV4(ipAddr);
923
924 IF_ALOGD() {
925 /*
926 * log the IP for reference in case there is a bogus value pushed by
927 * HAL.
928 */
929 char str[INET_ADDRSTRLEN];
930 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
931 ALOGD("AGPS IP is v4: %s", str);
932 }
933
934 jsize byteArrayLength =
935 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
936 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
937 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
938 agps_status.type, agps_status.status, byteArray);
939
940 checkAndClearExceptionFromCallback(env, __FUNCTION__);
941
942 if (byteArray) {
943 env->DeleteLocalRef(byteArray);
944 }
945 return Void();
946}
947
948jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
949 if (INADDR_NONE == ip) {
950 return NULL;
951 }
952
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800953 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700954 jbyteArray byteArray = env->NewByteArray(4);
955 if (byteArray == NULL) {
956 ALOGE("Unable to allocate byte array for IPv4 address");
957 return NULL;
958 }
959
960 jbyte ipv4[4];
961 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
962 memcpy(ipv4, &ip, sizeof(ipv4));
963 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
964 return byteArray;
965}
966
967/*
968 * AGnssRilCallback implements the callback methods required by the AGnssRil
969 * interface.
970 */
971struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800972 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700973 Return<void> requestRefLocCb() override;
974};
975
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800976Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800977 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700978 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
979 checkAndClearExceptionFromCallback(env, __FUNCTION__);
980 return Void();
981}
982
983Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800984 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700985 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
986 checkAndClearExceptionFromCallback(env, __FUNCTION__);
987 return Void();
988}
989
Wyatt Rileycf879db2017-01-12 13:57:38 -0800990/*
991 * GnssBatchingCallback interface implements the callback methods
992 * required by the IGnssBatching interface.
993 */
994struct GnssBatchingCallback : public IGnssBatchingCallback {
995 /*
996 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
997 * follow.
998 */
999 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001000 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001001 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001002};
1003
1004Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001005 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001006 JNIEnv* env = getJniEnv();
1007
1008 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1009 env->FindClass("android/location/Location"), nullptr);
1010
1011 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001012 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001013 env->SetObjectArrayElement(jLocations, i, jLocation);
1014 env->DeleteLocalRef(jLocation);
1015 }
1016
1017 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1018 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1019
1020 env->DeleteLocalRef(jLocations);
1021
1022 return Void();
1023}
1024
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001025static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001026 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1027 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001028 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1029 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1030 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1031 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1032 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1033 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
1034 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1035 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1036 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1037 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1038 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1039 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1040 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001041 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001042 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001043 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001044 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1045 "(II)V");
1046 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1047 "(II)V");
1048 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1049 "(II)V");
1050 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1051 "(II)V");
1052 method_reportMeasurementData = env->GetMethodID(
1053 clazz,
1054 "reportMeasurementData",
1055 "(Landroid/location/GnssMeasurementsEvent;)V");
1056 method_reportNavigationMessages = env->GetMethodID(
1057 clazz,
1058 "reportNavigationMessage",
1059 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001060 method_reportLocationBatch = env->GetMethodID(
1061 clazz,
1062 "reportLocationBatch",
1063 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001064
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001065 /*
1066 * Save a pointer to JVM.
1067 */
1068 jint jvmStatus = env->GetJavaVM(&sJvm);
1069 if (jvmStatus != JNI_OK) {
1070 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1071 }
1072
gomo48f1a642017-11-10 20:35:46 -08001073 // TODO(b/31632518)
1074 gnssHal_V1_1 = IGnss_V1_1::getService();
1075 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001076 ALOGD("gnssHal 1.1 was null, trying 1.0");
1077 gnssHal = IGnss::getService();
gomo48f1a642017-11-10 20:35:46 -08001078 } else {
1079 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001080 }
1081
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001082 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001083 gnssHalDeathRecipient = new GnssDeathRecipient();
1084 hardware::Return<bool> linked = gnssHal->linkToDeath(
1085 gnssHalDeathRecipient, /*cookie*/ 0);
1086 if (!linked.isOk()) {
1087 ALOGE("Transaction error in linking to GnssHAL death: %s",
1088 linked.description().c_str());
1089 } else if (!linked) {
1090 ALOGW("Unable to link to GnssHal death notifications");
1091 } else {
1092 ALOGD("Link to death notification successful");
1093 }
1094
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001095 auto gnssXtra = gnssHal->getExtensionXtra();
1096 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001097 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001098 } else {
1099 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001100 }
1101
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001102 auto gnssRil = gnssHal->getExtensionAGnssRil();
1103 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001104 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001105 } else {
1106 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001107 }
1108
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001109 auto gnssAgnss = gnssHal->getExtensionAGnss();
1110 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001111 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001112 } else {
1113 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114 }
1115
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001116 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1117 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001118 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001119 } else {
1120 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001121 }
1122
gomo48f1a642017-11-10 20:35:46 -08001123 if (gnssHal_V1_1 != nullptr) {
1124 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1125 if (!gnssMeasurement.isOk()) {
1126 ALOGD("Unable to get a handle to GnssMeasurement");
1127 } else {
1128 gnssMeasurementIface_V1_1 = gnssMeasurement;
1129 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1130 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001131 } else {
gomo48f1a642017-11-10 20:35:46 -08001132 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1133 if (!gnssMeasurement_V1_0.isOk()) {
1134 ALOGD("Unable to get a handle to GnssMeasurement");
1135 } else {
1136 gnssMeasurementIface = gnssMeasurement_V1_0;
1137 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001138 }
1139
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001140 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1141 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001142 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001143 } else {
1144 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001145 }
1146
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001147 auto gnssNi = gnssHal->getExtensionGnssNi();
1148 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001149 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001150 } else {
1151 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001152 }
1153
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001154 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1155 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001156 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001157 } else {
1158 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001159 }
1160
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001161 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1162 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001163 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001164 } else {
1165 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001166 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001167
1168 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1169 if (!gnssBatching.isOk()) {
1170 ALOGD("Unable to get a handle to gnssBatching");
1171 } else {
1172 gnssBatchingIface = gnssBatching;
1173 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001174 } else {
1175 ALOGE("Unable to get GPS service\n");
1176 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001177}
1178
1179static jboolean android_location_GnssLocationProvider_is_supported(
1180 JNIEnv* /* env */, jclass /* clazz */) {
1181 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1182}
1183
1184static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1185 JNIEnv* /* env */, jclass /* clazz */) {
1186 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1187}
1188
1189static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1190 JNIEnv* /* env */, jclass /* jclazz */) {
1191 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1192}
1193
1194static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1195 /*
1196 * This must be set before calling into the HAL library.
1197 */
1198 if (!mCallbacksObj)
1199 mCallbacksObj = env->NewGlobalRef(obj);
1200
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001201 /*
1202 * Fail if the main interface fails to initialize
1203 */
1204 if (gnssHal == nullptr) {
1205 ALOGE("Unable to Initialize GNSS HAL\n");
1206 return JNI_FALSE;
1207 }
1208
Wyatt Rileyfb840922017-11-08 15:07:58 -08001209 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1210
1211 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001212 if (gnssHal_V1_1 != nullptr) {
1213 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001214 } else {
1215 result = gnssHal->setCallback(gnssCbIface);
1216 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001217 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001218 ALOGE("SetCallback for Gnss Interface fails\n");
1219 return JNI_FALSE;
1220 }
1221
1222 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1223 if (gnssXtraIface == nullptr) {
1224 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001225 } else {
1226 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001227 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001228 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001229 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001230 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001231 }
1232
1233 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1234 if (agnssIface != nullptr) {
1235 agnssIface->setCallback(aGnssCbIface);
1236 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001237 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238 }
1239
1240 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1241 if (gnssGeofencingIface != nullptr) {
1242 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1243 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001244 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001245 }
1246
1247 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001248 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001249 gnssNiIface->setCallback(gnssNiCbIface);
1250 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001251 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001252 }
1253
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001254 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1255 if (agnssRilIface != nullptr) {
1256 agnssRilIface->setCallback(aGnssRilCbIface);
1257 } else {
1258 ALOGI("Unable to Initialize AGnss Ril interface\n");
1259 }
1260
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001261 return JNI_TRUE;
1262}
1263
1264static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1265 if (gnssHal != nullptr) {
1266 gnssHal->cleanup();
1267 }
1268}
1269
1270static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1271 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001272 jint preferred_time, jboolean low_power_mode) {
1273 Return<bool> result = false;
1274 if (gnssHal_V1_1 != nullptr) {
1275 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
1276 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1277 min_interval,
1278 preferred_accuracy,
1279 preferred_time,
1280 low_power_mode);
1281 } else if (gnssHal != nullptr) {
1282 result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1283 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1284 min_interval,
1285 preferred_accuracy,
1286 preferred_time);
1287 }
1288 if (!result.isOk()) {
1289 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1290 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001291 } else {
gomo48f1a642017-11-10 20:35:46 -08001292 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001293 }
1294}
1295
1296static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1297 if (gnssHal != nullptr) {
1298 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001299 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001300 return JNI_FALSE;
1301 } else {
1302 return result;
1303 }
1304 } else {
1305 return JNI_FALSE;
1306 }
1307}
1308
1309static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1310 if (gnssHal != nullptr) {
1311 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001312 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001313 return JNI_FALSE;
1314 } else {
1315 return result;
1316 }
1317 } else {
1318 return JNI_FALSE;
1319 }
1320}
1321static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1322 jobject /* obj */,
1323 jint flags) {
1324 if (gnssHal != nullptr) {
1325 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001326 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001327 ALOGE("Error in deleting aiding data");
1328 }
1329 }
1330}
1331
1332/*
1333 * This enum is used by the read_sv_status method to combine the svid,
1334 * constellation and svFlag fields.
1335 */
1336enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001337 SVID_SHIFT_WIDTH = 8,
1338 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001339};
1340
1341static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1342 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001343 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001344 /*
1345 * This method should only be called from within a call to reportSvStatus.
1346 */
1347 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1348 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1349 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1350 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001351 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001352
1353 /*
1354 * Read GNSS SV info.
1355 */
1356 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1357 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1358 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1359 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1360 static_cast<uint32_t>(info.svFlag);
1361 cn0s[i] = info.cN0Dbhz;
1362 elev[i] = info.elevationDegrees;
1363 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001364 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001365 }
1366
1367 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1368 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1369 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1370 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001371 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001372 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1373}
1374
1375static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1376 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1377 IAGnssRil::AGnssRefLocation location;
1378
1379 if (agnssRilIface == nullptr) {
1380 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1381 return;
1382 }
1383
1384 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1385 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1386 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1387 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1388 location.cellID.mcc = mcc;
1389 location.cellID.mnc = mnc;
1390 location.cellID.lac = lac;
1391 location.cellID.cid = cid;
1392 break;
1393 default:
1394 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1395 return;
1396 break;
1397 }
1398
1399 agnssRilIface->setRefLocation(location);
1400}
1401
1402static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1403 jint type, jstring setid_string) {
1404 if (agnssRilIface == nullptr) {
1405 ALOGE("no AGPS RIL interface in agps_set_id");
1406 return;
1407 }
1408
1409 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1410 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1411 env->ReleaseStringUTFChars(setid_string, setid);
1412}
1413
1414static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1415 jbyteArray nmeaArray, jint buffer_size) {
1416 // this should only be called from within a call to reportNmea
1417 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1418 int length = GnssCallback::sNmeaStringLength;
1419 if (length > buffer_size)
1420 length = buffer_size;
1421 memcpy(nmea, GnssCallback::sNmeaString, length);
1422 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1423 return (jint) length;
1424}
1425
1426static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1427 jlong time, jlong timeReference, jint uncertainty) {
1428 if (gnssHal != nullptr) {
1429 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001430 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001431 ALOGE("%s: Gnss injectTime() failed", __func__);
1432 }
1433 }
1434}
1435
1436static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1437 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1438 if (gnssHal != nullptr) {
1439 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001440 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001441 ALOGE("%s: Gnss injectLocation() failed", __func__);
1442 }
1443 }
1444}
1445
1446static jboolean android_location_GnssLocationProvider_supports_xtra(
1447 JNIEnv* /* env */, jobject /* obj */) {
1448 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1449}
1450
1451static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1452 jbyteArray data, jint length) {
1453 if (gnssXtraIface == nullptr) {
1454 ALOGE("XTRA Interface not supported");
1455 return;
1456 }
1457
1458 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1459 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1460 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1461}
1462
1463static void android_location_GnssLocationProvider_agps_data_conn_open(
1464 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1465 if (agnssIface == nullptr) {
1466 ALOGE("no AGPS interface in agps_data_conn_open");
1467 return;
1468 }
1469 if (apn == NULL) {
1470 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1471 return;
1472 }
1473
1474 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1475
1476 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001477 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001478 ALOGE("%s: Failed to set APN and its IP type", __func__);
1479 }
1480 env->ReleaseStringUTFChars(apn, apnStr);
1481}
1482
1483static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1484 jobject /* obj */) {
1485 if (agnssIface == nullptr) {
1486 ALOGE("%s: AGPS interface not supported", __func__);
1487 return;
1488 }
1489
1490 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001491 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001492 ALOGE("%s: Failed to close AGnss data connection", __func__);
1493 }
1494}
1495
1496static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1497 jobject /* obj */) {
1498 if (agnssIface == nullptr) {
1499 ALOGE("%s: AGPS interface not supported", __func__);
1500 return;
1501 }
1502
1503 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001504 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001505 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1506 }
1507}
1508
1509static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1510 jint type, jstring hostname, jint port) {
1511 if (agnssIface == nullptr) {
1512 ALOGE("no AGPS interface in set_agps_server");
1513 return;
1514 }
1515
1516 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1517 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1518 c_hostname,
1519 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001520 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001521 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1522 }
1523
1524 env->ReleaseStringUTFChars(hostname, c_hostname);
1525}
1526
1527static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1528 jobject /* obj */, jint notifId, jint response) {
1529 if (gnssNiIface == nullptr) {
1530 ALOGE("no NI interface in send_ni_response");
1531 return;
1532 }
1533
1534 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1535}
1536
1537static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1538 jobject /* obj */) {
1539 jstring result = NULL;
1540 /*
1541 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1542 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001543
1544 std::stringstream internalState;
1545
1546 if (gnssDebugIface == nullptr) {
1547 internalState << "Gnss Debug Interface not available" << std::endl;
1548 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001549 IGnssDebug::DebugData data;
1550 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1551 data = debugData;
1552 });
1553
Wyatt Riley268c6e02017-03-29 10:21:46 -07001554 internalState << "Gnss Location Data:: ";
1555 if (!data.position.valid) {
1556 internalState << "not valid";
1557 } else {
1558 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001559 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1560 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001561 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1562 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001563 << ", horizontalAccuracyMeters: "
1564 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001565 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001566 << ", speedAccuracyMetersPerSecond: "
1567 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001568 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001569 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001570 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001571 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001572
Wyatt Riley268c6e02017-03-29 10:21:46 -07001573 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1574 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1575 << ", frequencyUncertaintyNsPerSec: "
1576 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001577
1578 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001579 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1580 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001581 }
1582
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001583 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1584 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1585 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1586 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001587 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1588 internalState << "svid: " << data.satelliteDataArray[i].svid
1589 << ", constellation: "
1590 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1591 << ", ephemerisType: "
1592 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001593 << ", ephemerisSource: "
1594 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1595 << ", ephemerisHealth: "
1596 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1597 << ", serverPredictionIsAvailable: "
1598 << data.satelliteDataArray[i].serverPredictionIsAvailable
1599 << ", serverPredictionAgeSeconds: "
1600 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001601 << ", ephemerisAgeSeconds: "
1602 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1603 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001604 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001605
1606 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001607 return result;
1608}
1609
1610static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1611 jobject /* obj */,
1612 jboolean connected,
1613 jint type,
1614 jboolean roaming,
1615 jboolean available,
1616 jstring extraInfo,
1617 jstring apn) {
1618 if (agnssRilIface != nullptr) {
1619 auto result = agnssRilIface->updateNetworkState(connected,
1620 static_cast<IAGnssRil::NetworkType>(type),
1621 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001622 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001623 ALOGE("updateNetworkState failed");
1624 }
1625
1626 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1627 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001628 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001629 ALOGE("updateNetworkAvailability failed");
1630 }
1631
1632 env->ReleaseStringUTFChars(apn, c_apn);
1633 } else {
1634 ALOGE("AGnssRilInterface does not exist");
1635 }
1636}
1637
1638static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1639 JNIEnv* /* env */, jobject /* obj */) {
1640 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1641}
1642
1643static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1644 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1645 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1646 jint unknown_timer) {
1647 if (gnssGeofencingIface != nullptr) {
1648 auto result = gnssGeofencingIface->addGeofence(
1649 geofenceId, latitude, longitude, radius,
1650 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1651 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001652 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001653 } else {
1654 ALOGE("Geofence Interface not available");
1655 }
1656 return JNI_FALSE;
1657}
1658
1659static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1660 jobject /* obj */, jint geofenceId) {
1661 if (gnssGeofencingIface != nullptr) {
1662 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001663 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001664 } else {
1665 ALOGE("Geofence interface not available");
1666 }
1667 return JNI_FALSE;
1668}
1669
1670static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1671 jobject /* obj */, jint geofenceId) {
1672 if (gnssGeofencingIface != nullptr) {
1673 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001674 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001675 } else {
1676 ALOGE("Geofence interface not available");
1677 }
1678 return JNI_FALSE;
1679}
1680
1681static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1682 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1683 if (gnssGeofencingIface != nullptr) {
1684 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001685 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001686 } else {
1687 ALOGE("Geofence interface not available");
1688 }
1689 return JNI_FALSE;
1690}
1691
Lifu Tang30f95a72016-01-07 23:20:38 -08001692static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693 JNIEnv* env, jclass clazz) {
1694 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001695 return JNI_TRUE;
1696 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001697
destradaaea8a8a62014-06-23 18:19:03 -07001698 return JNI_FALSE;
1699}
1700
Lifu Tang30f95a72016-01-07 23:20:38 -08001701static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001702 JNIEnv* /* env */,
1703 jobject /* obj */,
1704 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 if (gnssMeasurementIface == nullptr) {
1706 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001707 return JNI_FALSE;
1708 }
1709
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001710 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001711 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1712 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1713 if (gnssMeasurementIface_V1_1 != nullptr) {
1714 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1715 enableFullTracking);
1716 } else {
1717 if (enableFullTracking == JNI_TRUE) {
1718 // full tracking mode not supported in 1.0 HAL
1719 return JNI_FALSE;
1720 }
1721 result = gnssMeasurementIface->setCallback(cbIface);
1722 }
1723
1724 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001725 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1726 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001727 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001728 } else {
1729 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001730 }
1731
1732 return JNI_TRUE;
1733}
1734
Lifu Tang30f95a72016-01-07 23:20:38 -08001735static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001736 JNIEnv* env,
1737 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001738 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001739 ALOGE("Measurement interface not available");
1740 return JNI_FALSE;
1741 }
1742
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001743 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001744 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001745}
1746
Lifu Tang30f95a72016-01-07 23:20:38 -08001747static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001748 JNIEnv* env,
1749 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001751 return JNI_TRUE;
1752 }
1753 return JNI_FALSE;
1754}
1755
Lifu Tang30f95a72016-01-07 23:20:38 -08001756static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001757 JNIEnv* env,
1758 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001759 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001760 ALOGE("Navigation Message interface is not available.");
1761 return JNI_FALSE;
1762 }
1763
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001764 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1765 new GnssNavigationMessageCallback();
1766 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1767 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1768
1769 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1770 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001771 return JNI_FALSE;
1772 }
1773
1774 return JNI_TRUE;
1775}
1776
Lifu Tang30f95a72016-01-07 23:20:38 -08001777static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001778 JNIEnv* env,
1779 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001780 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001781 ALOGE("Navigation Message interface is not available.");
1782 return JNI_FALSE;
1783 }
1784
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001785 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001786 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001787}
1788
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001789static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1790 jobject,
1791 jint emergencySuplPdn) {
1792 if (gnssConfigurationIface == nullptr) {
1793 ALOGE("no GNSS configuration interface available");
1794 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001795 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001796
1797 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001798 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001799 return result;
1800 } else {
1801 return JNI_FALSE;
1802 }
1803}
1804
1805static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1806 jobject,
1807 jint version) {
1808 if (gnssConfigurationIface == nullptr) {
1809 ALOGE("no GNSS configuration interface available");
1810 return JNI_FALSE;
1811 }
1812 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001813 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001814 return result;
1815 } else {
1816 return JNI_FALSE;
1817 }
1818}
1819
1820static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1821 jobject,
1822 jint suplEs) {
1823 if (gnssConfigurationIface == nullptr) {
1824 ALOGE("no GNSS configuration interface available");
1825 return JNI_FALSE;
1826 }
1827
1828 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001829 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001830 return result;
1831 } else {
1832 return JNI_FALSE;
1833 }
1834}
1835
1836static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1837 jobject,
1838 jint mode) {
1839 if (gnssConfigurationIface == nullptr) {
1840 ALOGE("no GNSS configuration interface available");
1841 return JNI_FALSE;
1842 }
1843
1844 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001845 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001846 return result;
1847 } else {
1848 return JNI_FALSE;
1849 }
1850}
1851
1852static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1853 jobject,
1854 jint gpsLock) {
1855 if (gnssConfigurationIface == nullptr) {
1856 ALOGE("no GNSS configuration interface available");
1857 return JNI_FALSE;
1858 }
1859
1860 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001861 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001862 return result;
1863 } else {
1864 return JNI_FALSE;
1865 }
1866}
1867
1868static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1869 jobject,
1870 jint lppProfile) {
1871 if (gnssConfigurationIface == nullptr) {
1872 ALOGE("no GNSS configuration interface available");
1873 return JNI_FALSE;
1874 }
1875
1876 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1877
Steven Morelandd002a8b2017-01-03 17:18:24 -08001878 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001879 return result;
1880 } else {
1881 return JNI_FALSE;
1882 }
1883}
1884
1885static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1886 jobject,
1887 jint gnssPosProtocol) {
1888 if (gnssConfigurationIface == nullptr) {
1889 ALOGE("no GNSS configuration interface available");
1890 return JNI_FALSE;
1891 }
1892
1893 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001894 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001895 return result;
1896 } else {
1897 return JNI_FALSE;
1898 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001899}
1900
Wyatt Rileycf879db2017-01-12 13:57:38 -08001901static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1902 if (gnssBatchingIface == nullptr) {
1903 return 0; // batching not supported, size = 0
1904 }
1905 auto result = gnssBatchingIface->getBatchSize();
1906 if (result.isOk()) {
1907 return static_cast<jint>(result);
1908 } else {
1909 return 0; // failure in binder, don't support batching
1910 }
1911}
1912
1913static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1914 if (gnssBatchingIface == nullptr) {
1915 return JNI_FALSE; // batching not supported
1916 }
1917 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1918
1919 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1920}
1921
1922static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1923 if (gnssBatchingIface == nullptr) {
1924 return; // batching not supported
1925 }
1926 gnssBatchingIface->cleanup();
1927}
1928
1929static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1930 jlong periodNanos, jboolean wakeOnFifoFull) {
1931 if (gnssBatchingIface == nullptr) {
1932 return JNI_FALSE; // batching not supported
1933 }
1934
1935 IGnssBatching::Options options;
1936 options.periodNanos = periodNanos;
1937 if (wakeOnFifoFull) {
1938 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1939 } else {
1940 options.flags = 0;
1941 }
1942
1943 return static_cast<jboolean>(gnssBatchingIface->start(options));
1944}
1945
1946static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1947 if (gnssBatchingIface == nullptr) {
1948 return; // batching not supported
1949 }
1950
1951 gnssBatchingIface->flush();
1952}
1953
1954static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1955 if (gnssBatchingIface == nullptr) {
1956 return JNI_FALSE; // batching not supported
1957 }
1958
1959 return gnssBatchingIface->stop();
1960}
1961
Daniel Micay76f6a862015-09-19 17:31:01 -04001962static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001963 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001964 {"class_init_native", "()V", reinterpret_cast<void *>(
1965 android_location_GnssLocationProvider_class_init_native)},
1966 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1967 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001968 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001969 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001970 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001971 reinterpret_cast<void *>(
1972 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1973 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1974 {"native_cleanup", "()V", reinterpret_cast<void *>(
1975 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001976 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08001977 "(IIIIIZ)Z",
1978 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001979 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1980 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001981 {"native_delete_aiding_data",
1982 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001983 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001984 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001985 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001986 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1987 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1988 android_location_GnssLocationProvider_read_nmea)},
1989 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1990 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001991 {"native_inject_location",
1992 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001993 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1994 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1995 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001996 {"native_inject_xtra_data",
1997 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001998 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001999 {"native_agps_data_conn_open",
2000 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002001 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002002 {"native_agps_data_conn_closed",
2003 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002004 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002005 {"native_agps_data_conn_failed",
2006 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002007 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002008 {"native_agps_set_id",
2009 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002010 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002011 {"native_agps_set_ref_location_cellid",
2012 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002013 reinterpret_cast<void *>(
2014 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002015 {"native_set_agps_server",
2016 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002017 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002018 {"native_send_ni_response",
2019 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002020 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002021 {"native_get_internal_state",
2022 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002023 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002024 {"native_update_network_state",
2025 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002026 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002027 {"native_is_geofence_supported",
2028 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002029 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002030 {"native_add_geofence",
2031 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002032 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002033 {"native_remove_geofence",
2034 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002035 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2036 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2037 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002038 {"native_resume_geofence",
2039 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002040 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002041 {"native_is_measurement_supported",
2042 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002043 reinterpret_cast<void *>(
2044 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002045 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002046 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002047 reinterpret_cast<void *>(
2048 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002049 {"native_stop_measurement_collection",
2050 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002051 reinterpret_cast<void *>(
2052 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002053 {"native_is_navigation_message_supported",
2054 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002055 reinterpret_cast<void *>(
2056 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002057 {"native_start_navigation_message_collection",
2058 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002059 reinterpret_cast<void *>(
2060 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002061 {"native_stop_navigation_message_collection",
2062 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002063 reinterpret_cast<void *>(
2064 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2065 {"native_set_supl_es",
2066 "(I)Z",
2067 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2068 {"native_set_supl_version",
2069 "(I)Z",
2070 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2071 {"native_set_supl_mode",
2072 "(I)Z",
2073 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2074 {"native_set_lpp_profile",
2075 "(I)Z",
2076 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2077 {"native_set_gnss_pos_protocol_select",
2078 "(I)Z",
2079 reinterpret_cast<void *>(
2080 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2081 {"native_set_gps_lock",
2082 "(I)Z",
2083 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2084 {"native_set_emergency_supl_pdn",
2085 "(I)Z",
2086 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002087 {"native_get_batch_size",
2088 "()I",
2089 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2090 {"native_init_batching",
2091 "()Z",
2092 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2093 {"native_start_batch",
2094 "(JZ)Z",
2095 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2096 {"native_flush_batch",
2097 "()V",
2098 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2099 {"native_stop_batch",
2100 "()Z",
2101 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2102 {"native_init_batching",
2103 "()Z",
2104 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2105 {"native_cleanup_batching",
2106 "()V",
2107 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002108};
2109
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002110int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002111 return jniRegisterNativeMethods(
2112 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002113 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002114 sMethods,
2115 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116}
2117
2118} /* namespace android */