blob: 67bad0fab7c5a2c61e19f6487be716c7a3d8ce73 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Lifu Tang30f95a72016-01-07 23:20:38 -080017#define LOG_TAG "GnssLocationProvider"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwoodb8d90332010-10-18 17:59:48 -040019#define LOG_NDEBUG 0
Danke Xie22d1f9f2009-08-18 18:28:45 -040020
gomo48f1a642017-11-10 20:35:46 -080021#include <android/hardware/gnss/1.0/IGnss.h>
Wyatt Rileyfb840922017-11-08 15:07:58 -080022#include <android/hardware/gnss/1.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070023
gomo48f1a642017-11-10 20:35:46 -080024#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
25#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070026#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040028#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029#include "utils/Log.h"
30#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070031#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070032#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
destradaa931a37f2014-08-12 16:36:59 -070034#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080035#include <limits>
destradaa96a14702014-06-05 11:36:30 -070036#include <linux/in.h>
37#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080038#include <pthread.h>
39#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070040#include <cinttypes>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Mike Lockwoodf602d362010-06-20 14:28:16 -070042static jobject mCallbacksObj = NULL;
43
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044static jmethodID method_reportLocation;
45static jmethodID method_reportStatus;
46static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040047static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040048static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040049static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080050static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080051static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040053static jmethodID method_reportNiNotification;
Miguel Torroja1e84da82010-07-27 07:02:24 +020054static jmethodID method_requestRefLocation;
55static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040056static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070057static jmethodID method_reportGeofenceTransition;
58static jmethodID method_reportGeofenceStatus;
59static jmethodID method_reportGeofenceAddStatus;
60static jmethodID method_reportGeofenceRemoveStatus;
61static jmethodID method_reportGeofencePauseStatus;
62static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070063static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070064static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080065static jmethodID method_reportLocationBatch;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080067/*
68 * Save a pointer to JavaVm to attach/detach threads executing
69 * callback methods that need to make JNI calls.
70 */
71static JavaVM* sJvm;
72
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070073using android::OK;
74using android::sp;
gomo25208882017-04-15 02:05:25 -070075using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070076using android::status_t;
77using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070079using android::hardware::Return;
80using android::hardware::Void;
81using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070082using android::hardware::hidl_death_recipient;
83using android::hidl::base::V1_0::IBase;
Wyatt Rileyfb840922017-11-08 15:07:58 -080084using android::hardware::gnss::V1_0::GnssLocation;
85using android::hardware::gnss::V1_0::GnssLocationFlags;
gomo48f1a642017-11-10 20:35:46 -080086using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
87using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
88using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
89using android::hardware::gnss::V1_0::IGnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070090using android::hardware::gnss::V1_0::IAGnss;
91using android::hardware::gnss::V1_0::IAGnssCallback;
92using android::hardware::gnss::V1_0::IAGnssCallback;
93using android::hardware::gnss::V1_0::IAGnssRil;
94using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080095using android::hardware::gnss::V1_0::IGnssBatching;
96using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070097using android::hardware::gnss::V1_0::IGnssConfiguration;
98using android::hardware::gnss::V1_0::IGnssDebug;
99using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
100using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700101using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
102using android::hardware::gnss::V1_0::IGnssNavigationMessage;
103using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
104using android::hardware::gnss::V1_0::IGnssNi;
105using android::hardware::gnss::V1_0::IGnssNiCallback;
106using android::hardware::gnss::V1_0::IGnssXtra;
107using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800108using android::hardware::gnss::V1_1::IGnssCallback;
109
gomo25208882017-04-15 02:05:25 -0700110struct GnssDeathRecipient : virtual public hidl_death_recipient
111{
112 // hidl_death_recipient interface
113 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800114 // TODO(b/37460011): implement a better death recovery mechanism without
gomo25208882017-04-15 02:05:25 -0700115 // crashing system server process as described in go//treble-gnss-death
116 LOG_ALWAYS_FATAL("Abort due to IGNSS hidl service failure,"
117 " restarting system server");
118 }
119};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700120
gomo25208882017-04-15 02:05:25 -0700121sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700122sp<IGnss> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800123sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700124sp<IGnssXtra> gnssXtraIface = nullptr;
125sp<IAGnssRil> agnssRilIface = nullptr;
126sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
127sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800128sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700129sp<IGnssDebug> gnssDebugIface = nullptr;
130sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
131sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800132sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
133sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700134sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400136#define WAKE_LOCK_NAME "GPS"
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138namespace android {
139
Lifu Tang120480f2016-02-07 18:08:19 -0800140template<class T>
141class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700142 public:
143 // Helper function to call setter on a Java object.
144 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800145 JNIEnv* env,
146 jclass clazz,
147 jobject object,
148 const char* method_name,
149 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700150
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700151 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800152 static const char *const signature_;
153};
Lifu Tange5a0e212016-01-25 18:02:17 -0800154
Lifu Tang120480f2016-02-07 18:08:19 -0800155template<class T>
156void JavaMethodHelper<T>::callJavaMethod(
157 JNIEnv* env,
158 jclass clazz,
159 jobject object,
160 const char* method_name,
161 T value) {
162 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
163 env->CallVoidMethod(object, method, value);
164}
destradaaea8a8a62014-06-23 18:19:03 -0700165
Lifu Tang120480f2016-02-07 18:08:19 -0800166class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700167 public:
168 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800169 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700170 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800171
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700172 template<class T>
173 void callSetter(const char* method_name, T value);
174 template<class T>
175 void callSetter(const char* method_name, T* value, size_t size);
176 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800177
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700178 private:
179 JNIEnv* env_;
180 jclass clazz_;
181 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800182};
183
184JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
185 clazz_ = env_->FindClass(class_name);
186 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
187 object_ = env_->NewObject(clazz_, ctor);
188}
189
Wyatt Rileycf879db2017-01-12 13:57:38 -0800190JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
191 clazz_ = env_->FindClass(class_name);
192 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
193 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
194}
195
Lifu Tang120480f2016-02-07 18:08:19 -0800196JavaObject::~JavaObject() {
197 env_->DeleteLocalRef(clazz_);
198}
199
200template<class T>
201void JavaObject::callSetter(const char* method_name, T value) {
202 JavaMethodHelper<T>::callJavaMethod(
203 env_, clazz_, object_, method_name, value);
204}
205
206template<>
207void JavaObject::callSetter(
208 const char* method_name, uint8_t* value, size_t size) {
209 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700210 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800211 jmethodID method = env_->GetMethodID(
212 clazz_,
213 method_name,
214 "([B)V");
215 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700216 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800217}
218
219jobject JavaObject::get() {
220 return object_;
221}
222
223// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800224template<>
225const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
226template<>
227const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
228template<>
229const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
230template<>
231const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
232template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800233const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
234template<>
235const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800236template<>
237const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
238template<>
239const char *const JavaMethodHelper<float>::signature_ = "(F)V";
240template<>
241const char *const JavaMethodHelper<double>::signature_ = "(D)V";
242template<>
243const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
244
245#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800246
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700247static inline jboolean boolToJbool(bool value) {
248 return value ? JNI_TRUE : JNI_FALSE;
249}
Lifu Tang120480f2016-02-07 18:08:19 -0800250
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700251static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
252 if (env->ExceptionCheck()) {
253 ALOGE("An exception was thrown by callback '%s'.", methodName);
254 LOGE_EX(env);
255 env->ExceptionClear();
256 }
257}
destradaaea8a8a62014-06-23 18:19:03 -0700258
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800259class ScopedJniThreadAttach {
260public:
261 ScopedJniThreadAttach() {
262 /*
263 * attachResult will also be JNI_OK if the thead was already attached to
264 * JNI before the call to AttachCurrentThread().
265 */
266 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
267 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
268 attachResult);
269 }
270
271 ~ScopedJniThreadAttach() {
272 jint detachResult = sJvm->DetachCurrentThread();
273 /*
274 * Return if the thread was already detached. Log error for any other
275 * failure.
276 */
277 if (detachResult == JNI_EDETACHED) {
278 return;
279 }
280
281 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
282 detachResult);
283 }
284
285 JNIEnv* getEnv() {
286 /*
287 * Checking validity of mEnv in case the thread was detached elsewhere.
288 */
289 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
290 return mEnv;
291 }
292
293private:
294 JNIEnv* mEnv = nullptr;
295};
296
297thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
298
299static JNIEnv* getJniEnv() {
300 JNIEnv* env = AndroidRuntime::getJNIEnv();
301
302 /*
303 * If env is nullptr, the thread is not already attached to
304 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
305 * will detach it on thread exit.
306 */
307 if (env == nullptr) {
308 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
309 env = tJniThreadAttacher->getEnv();
310 }
311
312 return env;
313}
314
Wyatt Rileyfb840922017-11-08 15:07:58 -0800315static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800316 JavaObject object(env, "android/location/Location", "gps");
317
318 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800319 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800320 SET(Latitude, location.latitudeDegrees);
321 SET(Longitude, location.longitudeDegrees);
322 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800323 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800324 SET(Altitude, location.altitudeMeters);
325 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800326 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800327 SET(Speed, location.speedMetersPerSec);
328 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800329 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800330 SET(Bearing, location.bearingDegrees);
331 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800332 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800333 SET(Accuracy, location.horizontalAccuracyMeters);
334 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800335 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800336 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
337 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800338 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800339 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
340 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800341 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800342 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
343 }
344 SET(Time, location.timestamp);
345
346 return object.get();
347}
348
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700349/*
350 * GnssCallback class implements the callback methods for IGnss interface.
351 */
352struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800353 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700354 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
355 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
356 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
357 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
358 Return<void> gnssAcquireWakelockCb() override;
359 Return<void> gnssReleaseWakelockCb() override;
360 Return<void> gnssRequestTimeCb() override;
361 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800362
Wyatt Rileyfb840922017-11-08 15:07:58 -0800363 // New in 1.1
364 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
365
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700366 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
367 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
368 static size_t sGnssSvListSize;
369
370 static const char* sNmeaString;
371 static size_t sNmeaStringLength;
372};
373
Wyatt Rileyfb840922017-11-08 15:07:58 -0800374Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
375 ALOGD("%s: name=%s\n", __func__, name.c_str());
376
Wyatt Rileyfb840922017-11-08 15:07:58 -0800377 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800378 jstring jstringName = env->NewStringUTF(name.c_str());
379 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800380 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800381
Wyatt Rileyfb840922017-11-08 15:07:58 -0800382 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");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001034 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1035 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001036 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1037 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1038 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1039 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1040 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1041 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1042 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001043 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001044 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001045 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001046 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1047 "(II)V");
1048 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1049 "(II)V");
1050 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1051 "(II)V");
1052 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1053 "(II)V");
1054 method_reportMeasurementData = env->GetMethodID(
1055 clazz,
1056 "reportMeasurementData",
1057 "(Landroid/location/GnssMeasurementsEvent;)V");
1058 method_reportNavigationMessages = env->GetMethodID(
1059 clazz,
1060 "reportNavigationMessage",
1061 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001062 method_reportLocationBatch = env->GetMethodID(
1063 clazz,
1064 "reportLocationBatch",
1065 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001066
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001067 /*
1068 * Save a pointer to JVM.
1069 */
1070 jint jvmStatus = env->GetJavaVM(&sJvm);
1071 if (jvmStatus != JNI_OK) {
1072 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1073 }
1074
gomo48f1a642017-11-10 20:35:46 -08001075 // TODO(b/31632518)
1076 gnssHal_V1_1 = IGnss_V1_1::getService();
1077 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001078 ALOGD("gnssHal 1.1 was null, trying 1.0");
1079 gnssHal = IGnss::getService();
gomo48f1a642017-11-10 20:35:46 -08001080 } else {
1081 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001082 }
1083
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001084 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001085 gnssHalDeathRecipient = new GnssDeathRecipient();
1086 hardware::Return<bool> linked = gnssHal->linkToDeath(
1087 gnssHalDeathRecipient, /*cookie*/ 0);
1088 if (!linked.isOk()) {
1089 ALOGE("Transaction error in linking to GnssHAL death: %s",
1090 linked.description().c_str());
1091 } else if (!linked) {
1092 ALOGW("Unable to link to GnssHal death notifications");
1093 } else {
1094 ALOGD("Link to death notification successful");
1095 }
1096
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001097 auto gnssXtra = gnssHal->getExtensionXtra();
1098 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001099 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001100 } else {
1101 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001102 }
1103
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001104 auto gnssRil = gnssHal->getExtensionAGnssRil();
1105 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001106 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001107 } else {
1108 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001109 }
1110
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001111 auto gnssAgnss = gnssHal->getExtensionAGnss();
1112 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001113 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001114 } else {
1115 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001116 }
1117
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001118 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1119 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001120 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001121 } else {
1122 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001123 }
1124
gomo48f1a642017-11-10 20:35:46 -08001125 if (gnssHal_V1_1 != nullptr) {
1126 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1127 if (!gnssMeasurement.isOk()) {
1128 ALOGD("Unable to get a handle to GnssMeasurement");
1129 } else {
1130 gnssMeasurementIface_V1_1 = gnssMeasurement;
1131 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1132 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001133 } else {
gomo48f1a642017-11-10 20:35:46 -08001134 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1135 if (!gnssMeasurement_V1_0.isOk()) {
1136 ALOGD("Unable to get a handle to GnssMeasurement");
1137 } else {
1138 gnssMeasurementIface = gnssMeasurement_V1_0;
1139 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001140 }
1141
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001142 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1143 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001144 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001145 } else {
1146 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001147 }
1148
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001149 auto gnssNi = gnssHal->getExtensionGnssNi();
1150 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001151 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001152 } else {
1153 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001154 }
1155
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001156 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1157 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001158 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001159 } else {
1160 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001161 }
1162
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001163 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1164 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001165 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001166 } else {
1167 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001168 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001169
1170 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1171 if (!gnssBatching.isOk()) {
1172 ALOGD("Unable to get a handle to gnssBatching");
1173 } else {
1174 gnssBatchingIface = gnssBatching;
1175 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001176 } else {
1177 ALOGE("Unable to get GPS service\n");
1178 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001179}
1180
1181static jboolean android_location_GnssLocationProvider_is_supported(
1182 JNIEnv* /* env */, jclass /* clazz */) {
1183 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1184}
1185
1186static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1187 JNIEnv* /* env */, jclass /* clazz */) {
1188 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1189}
1190
1191static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1192 JNIEnv* /* env */, jclass /* jclazz */) {
1193 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1194}
1195
1196static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1197 /*
1198 * This must be set before calling into the HAL library.
1199 */
1200 if (!mCallbacksObj)
1201 mCallbacksObj = env->NewGlobalRef(obj);
1202
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001203 /*
1204 * Fail if the main interface fails to initialize
1205 */
1206 if (gnssHal == nullptr) {
1207 ALOGE("Unable to Initialize GNSS HAL\n");
1208 return JNI_FALSE;
1209 }
1210
Wyatt Rileyfb840922017-11-08 15:07:58 -08001211 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1212
1213 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001214 if (gnssHal_V1_1 != nullptr) {
1215 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001216 } else {
1217 result = gnssHal->setCallback(gnssCbIface);
1218 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001219 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001220 ALOGE("SetCallback for Gnss Interface fails\n");
1221 return JNI_FALSE;
1222 }
1223
1224 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1225 if (gnssXtraIface == nullptr) {
1226 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001227 } else {
1228 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001229 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001230 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001231 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001232 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001233 }
1234
1235 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1236 if (agnssIface != nullptr) {
1237 agnssIface->setCallback(aGnssCbIface);
1238 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001239 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001240 }
1241
1242 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1243 if (gnssGeofencingIface != nullptr) {
1244 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1245 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001246 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001247 }
1248
1249 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001250 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001251 gnssNiIface->setCallback(gnssNiCbIface);
1252 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001253 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001254 }
1255
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001256 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1257 if (agnssRilIface != nullptr) {
1258 agnssRilIface->setCallback(aGnssRilCbIface);
1259 } else {
1260 ALOGI("Unable to Initialize AGnss Ril interface\n");
1261 }
1262
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001263 return JNI_TRUE;
1264}
1265
1266static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1267 if (gnssHal != nullptr) {
1268 gnssHal->cleanup();
1269 }
1270}
1271
1272static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1273 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001274 jint preferred_time, jboolean low_power_mode) {
1275 Return<bool> result = false;
1276 if (gnssHal_V1_1 != nullptr) {
1277 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
1278 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1279 min_interval,
1280 preferred_accuracy,
1281 preferred_time,
1282 low_power_mode);
1283 } else if (gnssHal != nullptr) {
1284 result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1285 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1286 min_interval,
1287 preferred_accuracy,
1288 preferred_time);
1289 }
1290 if (!result.isOk()) {
1291 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1292 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001293 } else {
gomo48f1a642017-11-10 20:35:46 -08001294 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001295 }
1296}
1297
1298static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1299 if (gnssHal != nullptr) {
1300 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001301 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001302 return JNI_FALSE;
1303 } else {
1304 return result;
1305 }
1306 } else {
1307 return JNI_FALSE;
1308 }
1309}
1310
1311static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1312 if (gnssHal != nullptr) {
1313 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001314 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001315 return JNI_FALSE;
1316 } else {
1317 return result;
1318 }
1319 } else {
1320 return JNI_FALSE;
1321 }
1322}
1323static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1324 jobject /* obj */,
1325 jint flags) {
1326 if (gnssHal != nullptr) {
1327 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001328 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001329 ALOGE("Error in deleting aiding data");
1330 }
1331 }
1332}
1333
1334/*
1335 * This enum is used by the read_sv_status method to combine the svid,
1336 * constellation and svFlag fields.
1337 */
1338enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001339 SVID_SHIFT_WIDTH = 8,
1340 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001341};
1342
1343static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1344 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001345 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001346 /*
1347 * This method should only be called from within a call to reportSvStatus.
1348 */
1349 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1350 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1351 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1352 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001353 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001354
1355 /*
1356 * Read GNSS SV info.
1357 */
1358 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1359 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1360 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1361 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1362 static_cast<uint32_t>(info.svFlag);
1363 cn0s[i] = info.cN0Dbhz;
1364 elev[i] = info.elevationDegrees;
1365 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001366 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001367 }
1368
1369 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1370 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1371 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1372 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001373 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001374 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1375}
1376
1377static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1378 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1379 IAGnssRil::AGnssRefLocation location;
1380
1381 if (agnssRilIface == nullptr) {
1382 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1383 return;
1384 }
1385
1386 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1387 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1388 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1389 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1390 location.cellID.mcc = mcc;
1391 location.cellID.mnc = mnc;
1392 location.cellID.lac = lac;
1393 location.cellID.cid = cid;
1394 break;
1395 default:
1396 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1397 return;
1398 break;
1399 }
1400
1401 agnssRilIface->setRefLocation(location);
1402}
1403
1404static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1405 jint type, jstring setid_string) {
1406 if (agnssRilIface == nullptr) {
1407 ALOGE("no AGPS RIL interface in agps_set_id");
1408 return;
1409 }
1410
1411 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1412 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1413 env->ReleaseStringUTFChars(setid_string, setid);
1414}
1415
1416static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1417 jbyteArray nmeaArray, jint buffer_size) {
1418 // this should only be called from within a call to reportNmea
1419 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1420 int length = GnssCallback::sNmeaStringLength;
1421 if (length > buffer_size)
1422 length = buffer_size;
1423 memcpy(nmea, GnssCallback::sNmeaString, length);
1424 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1425 return (jint) length;
1426}
1427
1428static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1429 jlong time, jlong timeReference, jint uncertainty) {
1430 if (gnssHal != nullptr) {
1431 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001432 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001433 ALOGE("%s: Gnss injectTime() failed", __func__);
1434 }
1435 }
1436}
1437
1438static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1439 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1440 if (gnssHal != nullptr) {
1441 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001442 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001443 ALOGE("%s: Gnss injectLocation() failed", __func__);
1444 }
1445 }
1446}
1447
1448static jboolean android_location_GnssLocationProvider_supports_xtra(
1449 JNIEnv* /* env */, jobject /* obj */) {
1450 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1451}
1452
1453static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1454 jbyteArray data, jint length) {
1455 if (gnssXtraIface == nullptr) {
1456 ALOGE("XTRA Interface not supported");
1457 return;
1458 }
1459
1460 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1461 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1462 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1463}
1464
1465static void android_location_GnssLocationProvider_agps_data_conn_open(
1466 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1467 if (agnssIface == nullptr) {
1468 ALOGE("no AGPS interface in agps_data_conn_open");
1469 return;
1470 }
1471 if (apn == NULL) {
1472 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1473 return;
1474 }
1475
1476 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1477
1478 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001479 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001480 ALOGE("%s: Failed to set APN and its IP type", __func__);
1481 }
1482 env->ReleaseStringUTFChars(apn, apnStr);
1483}
1484
1485static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1486 jobject /* obj */) {
1487 if (agnssIface == nullptr) {
1488 ALOGE("%s: AGPS interface not supported", __func__);
1489 return;
1490 }
1491
1492 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001493 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001494 ALOGE("%s: Failed to close AGnss data connection", __func__);
1495 }
1496}
1497
1498static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1499 jobject /* obj */) {
1500 if (agnssIface == nullptr) {
1501 ALOGE("%s: AGPS interface not supported", __func__);
1502 return;
1503 }
1504
1505 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001506 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001507 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1508 }
1509}
1510
1511static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1512 jint type, jstring hostname, jint port) {
1513 if (agnssIface == nullptr) {
1514 ALOGE("no AGPS interface in set_agps_server");
1515 return;
1516 }
1517
1518 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1519 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1520 c_hostname,
1521 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001522 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001523 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1524 }
1525
1526 env->ReleaseStringUTFChars(hostname, c_hostname);
1527}
1528
1529static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1530 jobject /* obj */, jint notifId, jint response) {
1531 if (gnssNiIface == nullptr) {
1532 ALOGE("no NI interface in send_ni_response");
1533 return;
1534 }
1535
1536 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1537}
1538
1539static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1540 jobject /* obj */) {
1541 jstring result = NULL;
1542 /*
1543 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1544 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001545
1546 std::stringstream internalState;
1547
1548 if (gnssDebugIface == nullptr) {
1549 internalState << "Gnss Debug Interface not available" << std::endl;
1550 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001551 IGnssDebug::DebugData data;
1552 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1553 data = debugData;
1554 });
1555
Wyatt Riley268c6e02017-03-29 10:21:46 -07001556 internalState << "Gnss Location Data:: ";
1557 if (!data.position.valid) {
1558 internalState << "not valid";
1559 } else {
1560 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001561 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1562 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001563 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1564 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001565 << ", horizontalAccuracyMeters: "
1566 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001567 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001568 << ", speedAccuracyMetersPerSecond: "
1569 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001570 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001571 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001572 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001573 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001574
Wyatt Riley268c6e02017-03-29 10:21:46 -07001575 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1576 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1577 << ", frequencyUncertaintyNsPerSec: "
1578 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001579
1580 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001581 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1582 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001583 }
1584
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001585 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1586 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1587 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1588 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001589 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1590 internalState << "svid: " << data.satelliteDataArray[i].svid
1591 << ", constellation: "
1592 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1593 << ", ephemerisType: "
1594 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001595 << ", ephemerisSource: "
1596 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1597 << ", ephemerisHealth: "
1598 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1599 << ", serverPredictionIsAvailable: "
1600 << data.satelliteDataArray[i].serverPredictionIsAvailable
1601 << ", serverPredictionAgeSeconds: "
1602 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001603 << ", ephemerisAgeSeconds: "
1604 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1605 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001606 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001607
1608 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001609 return result;
1610}
1611
1612static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1613 jobject /* obj */,
1614 jboolean connected,
1615 jint type,
1616 jboolean roaming,
1617 jboolean available,
1618 jstring extraInfo,
1619 jstring apn) {
1620 if (agnssRilIface != nullptr) {
1621 auto result = agnssRilIface->updateNetworkState(connected,
1622 static_cast<IAGnssRil::NetworkType>(type),
1623 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001624 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001625 ALOGE("updateNetworkState failed");
1626 }
1627
1628 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1629 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001630 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001631 ALOGE("updateNetworkAvailability failed");
1632 }
1633
1634 env->ReleaseStringUTFChars(apn, c_apn);
1635 } else {
1636 ALOGE("AGnssRilInterface does not exist");
1637 }
1638}
1639
1640static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1641 JNIEnv* /* env */, jobject /* obj */) {
1642 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1643}
1644
1645static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1646 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1647 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1648 jint unknown_timer) {
1649 if (gnssGeofencingIface != nullptr) {
1650 auto result = gnssGeofencingIface->addGeofence(
1651 geofenceId, latitude, longitude, radius,
1652 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1653 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001654 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001655 } else {
1656 ALOGE("Geofence Interface not available");
1657 }
1658 return JNI_FALSE;
1659}
1660
1661static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1662 jobject /* obj */, jint geofenceId) {
1663 if (gnssGeofencingIface != nullptr) {
1664 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001665 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001666 } else {
1667 ALOGE("Geofence interface not available");
1668 }
1669 return JNI_FALSE;
1670}
1671
1672static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1673 jobject /* obj */, jint geofenceId) {
1674 if (gnssGeofencingIface != nullptr) {
1675 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001676 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001677 } else {
1678 ALOGE("Geofence interface not available");
1679 }
1680 return JNI_FALSE;
1681}
1682
1683static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1684 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1685 if (gnssGeofencingIface != nullptr) {
1686 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001687 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001688 } else {
1689 ALOGE("Geofence interface not available");
1690 }
1691 return JNI_FALSE;
1692}
1693
Lifu Tang30f95a72016-01-07 23:20:38 -08001694static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001695 JNIEnv* env, jclass clazz) {
1696 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001697 return JNI_TRUE;
1698 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001699
destradaaea8a8a62014-06-23 18:19:03 -07001700 return JNI_FALSE;
1701}
1702
Lifu Tang30f95a72016-01-07 23:20:38 -08001703static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001704 JNIEnv* /* env */,
1705 jobject /* obj */,
1706 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001707 if (gnssMeasurementIface == nullptr) {
1708 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001709 return JNI_FALSE;
1710 }
1711
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001712 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001713 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1714 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1715 if (gnssMeasurementIface_V1_1 != nullptr) {
1716 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1717 enableFullTracking);
1718 } else {
1719 if (enableFullTracking == JNI_TRUE) {
1720 // full tracking mode not supported in 1.0 HAL
1721 return JNI_FALSE;
1722 }
1723 result = gnssMeasurementIface->setCallback(cbIface);
1724 }
1725
1726 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001727 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1728 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001729 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001730 } else {
1731 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001732 }
1733
1734 return JNI_TRUE;
1735}
1736
Lifu Tang30f95a72016-01-07 23:20:38 -08001737static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001738 JNIEnv* env,
1739 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001740 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001741 ALOGE("Measurement interface not available");
1742 return JNI_FALSE;
1743 }
1744
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001745 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001746 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001747}
1748
Lifu Tang30f95a72016-01-07 23:20:38 -08001749static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001750 JNIEnv* env,
1751 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001752 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001753 return JNI_TRUE;
1754 }
1755 return JNI_FALSE;
1756}
1757
Lifu Tang30f95a72016-01-07 23:20:38 -08001758static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001759 JNIEnv* env,
1760 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001761 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001762 ALOGE("Navigation Message interface is not available.");
1763 return JNI_FALSE;
1764 }
1765
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1767 new GnssNavigationMessageCallback();
1768 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1769 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1770
1771 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1772 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001773 return JNI_FALSE;
1774 }
1775
1776 return JNI_TRUE;
1777}
1778
Lifu Tang30f95a72016-01-07 23:20:38 -08001779static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001780 JNIEnv* env,
1781 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001782 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001783 ALOGE("Navigation Message interface is not available.");
1784 return JNI_FALSE;
1785 }
1786
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001787 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001788 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001789}
1790
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001791static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1792 jobject,
1793 jint emergencySuplPdn) {
1794 if (gnssConfigurationIface == nullptr) {
1795 ALOGE("no GNSS configuration interface available");
1796 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001797 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001798
1799 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001800 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001801 return result;
1802 } else {
1803 return JNI_FALSE;
1804 }
1805}
1806
1807static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1808 jobject,
1809 jint version) {
1810 if (gnssConfigurationIface == nullptr) {
1811 ALOGE("no GNSS configuration interface available");
1812 return JNI_FALSE;
1813 }
1814 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001815 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001816 return result;
1817 } else {
1818 return JNI_FALSE;
1819 }
1820}
1821
1822static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1823 jobject,
1824 jint suplEs) {
1825 if (gnssConfigurationIface == nullptr) {
1826 ALOGE("no GNSS configuration interface available");
1827 return JNI_FALSE;
1828 }
1829
1830 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001831 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001832 return result;
1833 } else {
1834 return JNI_FALSE;
1835 }
1836}
1837
1838static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1839 jobject,
1840 jint mode) {
1841 if (gnssConfigurationIface == nullptr) {
1842 ALOGE("no GNSS configuration interface available");
1843 return JNI_FALSE;
1844 }
1845
1846 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001847 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001848 return result;
1849 } else {
1850 return JNI_FALSE;
1851 }
1852}
1853
1854static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1855 jobject,
1856 jint gpsLock) {
1857 if (gnssConfigurationIface == nullptr) {
1858 ALOGE("no GNSS configuration interface available");
1859 return JNI_FALSE;
1860 }
1861
1862 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001863 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001864 return result;
1865 } else {
1866 return JNI_FALSE;
1867 }
1868}
1869
1870static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1871 jobject,
1872 jint lppProfile) {
1873 if (gnssConfigurationIface == nullptr) {
1874 ALOGE("no GNSS configuration interface available");
1875 return JNI_FALSE;
1876 }
1877
1878 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1879
Steven Morelandd002a8b2017-01-03 17:18:24 -08001880 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001881 return result;
1882 } else {
1883 return JNI_FALSE;
1884 }
1885}
1886
1887static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1888 jobject,
1889 jint gnssPosProtocol) {
1890 if (gnssConfigurationIface == nullptr) {
1891 ALOGE("no GNSS configuration interface available");
1892 return JNI_FALSE;
1893 }
1894
1895 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001896 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001897 return result;
1898 } else {
1899 return JNI_FALSE;
1900 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001901}
1902
Wyatt Rileycf879db2017-01-12 13:57:38 -08001903static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1904 if (gnssBatchingIface == nullptr) {
1905 return 0; // batching not supported, size = 0
1906 }
1907 auto result = gnssBatchingIface->getBatchSize();
1908 if (result.isOk()) {
1909 return static_cast<jint>(result);
1910 } else {
1911 return 0; // failure in binder, don't support batching
1912 }
1913}
1914
1915static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1916 if (gnssBatchingIface == nullptr) {
1917 return JNI_FALSE; // batching not supported
1918 }
1919 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1920
1921 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1922}
1923
1924static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1925 if (gnssBatchingIface == nullptr) {
1926 return; // batching not supported
1927 }
1928 gnssBatchingIface->cleanup();
1929}
1930
1931static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1932 jlong periodNanos, jboolean wakeOnFifoFull) {
1933 if (gnssBatchingIface == nullptr) {
1934 return JNI_FALSE; // batching not supported
1935 }
1936
1937 IGnssBatching::Options options;
1938 options.periodNanos = periodNanos;
1939 if (wakeOnFifoFull) {
1940 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1941 } else {
1942 options.flags = 0;
1943 }
1944
1945 return static_cast<jboolean>(gnssBatchingIface->start(options));
1946}
1947
1948static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1949 if (gnssBatchingIface == nullptr) {
1950 return; // batching not supported
1951 }
1952
1953 gnssBatchingIface->flush();
1954}
1955
1956static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1957 if (gnssBatchingIface == nullptr) {
1958 return JNI_FALSE; // batching not supported
1959 }
1960
1961 return gnssBatchingIface->stop();
1962}
1963
Daniel Micay76f6a862015-09-19 17:31:01 -04001964static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001965 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001966 {"class_init_native", "()V", reinterpret_cast<void *>(
1967 android_location_GnssLocationProvider_class_init_native)},
1968 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1969 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001970 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001971 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001972 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001973 reinterpret_cast<void *>(
1974 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1975 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1976 {"native_cleanup", "()V", reinterpret_cast<void *>(
1977 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001978 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08001979 "(IIIIIZ)Z",
1980 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001981 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1982 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001983 {"native_delete_aiding_data",
1984 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001985 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001986 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001987 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001988 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1989 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1990 android_location_GnssLocationProvider_read_nmea)},
1991 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1992 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001993 {"native_inject_location",
1994 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001995 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
1996 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
1997 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07001998 {"native_inject_xtra_data",
1999 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002000 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002001 {"native_agps_data_conn_open",
2002 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002003 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002004 {"native_agps_data_conn_closed",
2005 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002006 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002007 {"native_agps_data_conn_failed",
2008 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002009 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002010 {"native_agps_set_id",
2011 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002012 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002013 {"native_agps_set_ref_location_cellid",
2014 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002015 reinterpret_cast<void *>(
2016 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002017 {"native_set_agps_server",
2018 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002019 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002020 {"native_send_ni_response",
2021 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002022 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002023 {"native_get_internal_state",
2024 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002025 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002026 {"native_update_network_state",
2027 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002028 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002029 {"native_is_geofence_supported",
2030 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002031 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002032 {"native_add_geofence",
2033 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002034 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002035 {"native_remove_geofence",
2036 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002037 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2038 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2039 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002040 {"native_resume_geofence",
2041 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002042 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002043 {"native_is_measurement_supported",
2044 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002045 reinterpret_cast<void *>(
2046 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002047 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002048 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002049 reinterpret_cast<void *>(
2050 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002051 {"native_stop_measurement_collection",
2052 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002053 reinterpret_cast<void *>(
2054 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002055 {"native_is_navigation_message_supported",
2056 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002057 reinterpret_cast<void *>(
2058 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002059 {"native_start_navigation_message_collection",
2060 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002061 reinterpret_cast<void *>(
2062 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002063 {"native_stop_navigation_message_collection",
2064 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002065 reinterpret_cast<void *>(
2066 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2067 {"native_set_supl_es",
2068 "(I)Z",
2069 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2070 {"native_set_supl_version",
2071 "(I)Z",
2072 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2073 {"native_set_supl_mode",
2074 "(I)Z",
2075 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2076 {"native_set_lpp_profile",
2077 "(I)Z",
2078 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2079 {"native_set_gnss_pos_protocol_select",
2080 "(I)Z",
2081 reinterpret_cast<void *>(
2082 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2083 {"native_set_gps_lock",
2084 "(I)Z",
2085 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2086 {"native_set_emergency_supl_pdn",
2087 "(I)Z",
2088 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002089 {"native_get_batch_size",
2090 "()I",
2091 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2092 {"native_init_batching",
2093 "()Z",
2094 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2095 {"native_start_batch",
2096 "(JZ)Z",
2097 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2098 {"native_flush_batch",
2099 "()V",
2100 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2101 {"native_stop_batch",
2102 "()Z",
2103 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2104 {"native_init_batching",
2105 "()Z",
2106 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2107 {"native_cleanup_batching",
2108 "()V",
2109 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110};
2111
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002112int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002113 return jniRegisterNativeMethods(
2114 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002115 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002116 sMethods,
2117 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118}
2119
2120} /* namespace android */