blob: 8fd5be2a45ff8ff76093e1ea0643f07f83d05d99 [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;
Yu-Han Yang21988932018-01-23 15:07:37 -0800361 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700362 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800363
Wyatt Rileyfb840922017-11-08 15:07:58 -0800364 // New in 1.1
365 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
366
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700367 static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
368 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
369 static size_t sGnssSvListSize;
370
371 static const char* sNmeaString;
372 static size_t sNmeaStringLength;
373};
374
Wyatt Rileyfb840922017-11-08 15:07:58 -0800375Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
376 ALOGD("%s: name=%s\n", __func__, name.c_str());
377
Wyatt Rileyfb840922017-11-08 15:07:58 -0800378 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800379 jstring jstringName = env->NewStringUTF(name.c_str());
380 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800381 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800382
Wyatt Rileyfb840922017-11-08 15:07:58 -0800383 return Void();
384}
385
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700386IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
387 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
388const char* GnssCallback::sNmeaString = nullptr;
389size_t GnssCallback::sNmeaStringLength = 0;
390size_t GnssCallback::sGnssSvListSize = 0;
391
Wyatt Rileyfb840922017-11-08 15:07:58 -0800392Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800393 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800394
395 jobject jLocation = translateLocation(env, location);
396 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800397 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800398
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700399 env->CallVoidMethod(mCallbacksObj,
400 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800401 boolToJbool(hasLatLong),
402 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 checkAndClearExceptionFromCallback(env, __FUNCTION__);
404 return Void();
405}
406
407Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800408 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700409 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
410 checkAndClearExceptionFromCallback(env, __FUNCTION__);
411 return Void();
412}
413
414Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800415 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700416
417 sGnssSvListSize = svStatus.numSvs;
418 if (sGnssSvListSize > static_cast<uint32_t>(
419 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
420 ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
421 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
422 sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800423 }
424
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700425 // Copy GNSS SV info into sGnssSvList, if any.
426 if (svStatus.numSvs > 0) {
427 memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
Lifu Tang9363b942016-02-16 18:07:00 -0800428 }
destradaaea8a8a62014-06-23 18:19:03 -0700429
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700430 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
431 checkAndClearExceptionFromCallback(env, __FUNCTION__);
432 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700433}
434
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700435Return<void> GnssCallback::gnssNmeaCb(
436 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800437 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700438 /*
439 * The Java code will call back to read these values.
440 * We do this to avoid creating unnecessary String objects.
441 */
442 sNmeaString = nmea.c_str();
443 sNmeaStringLength = nmea.size();
444
445 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
446 checkAndClearExceptionFromCallback(env, __FUNCTION__);
447 return Void();
448}
449
450Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
451 ALOGD("%s: %du\n", __func__, capabilities);
452
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800453 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700454 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
455 checkAndClearExceptionFromCallback(env, __FUNCTION__);
456 return Void();
457}
458
459Return<void> GnssCallback::gnssAcquireWakelockCb() {
460 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
461 return Void();
462}
463
464Return<void> GnssCallback::gnssReleaseWakelockCb() {
465 release_wake_lock(WAKE_LOCK_NAME);
466 return Void();
467}
468
469Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800470 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700471 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
472 checkAndClearExceptionFromCallback(env, __FUNCTION__);
473 return Void();
474}
475
Yu-Han Yang21988932018-01-23 15:07:37 -0800476Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
477 // TODO(b/72405645): call into java implementation
478 return Void();
479}
480
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700481Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
482 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
483
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800484 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700485 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
486 info.yearOfHw);
487 checkAndClearExceptionFromCallback(env, __FUNCTION__);
488 return Void();
489}
490
491class GnssXtraCallback : public IGnssXtraCallback {
492 Return<void> downloadRequestCb() override;
493};
494
495/*
496 * GnssXtraCallback class implements the callback methods for the IGnssXtra
497 * interface.
498 */
499Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800500 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700501 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
502 checkAndClearExceptionFromCallback(env, __FUNCTION__);
503 return Void();
504}
505
506/*
507 * GnssGeofenceCallback class implements the callback methods for the
508 * IGnssGeofence interface.
509 */
510struct GnssGeofenceCallback : public IGnssGeofenceCallback {
511 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
512 Return<void> gnssGeofenceTransitionCb(
513 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800514 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700515 GeofenceTransition transition,
516 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
517 Return<void> gnssGeofenceStatusCb(
518 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800519 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700520 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
521 GeofenceStatus status) override;
522 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
523 GeofenceStatus status) override;
524 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
525 GeofenceStatus status) override;
526 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
527 GeofenceStatus status) override;
528};
529
530Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
531 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800532 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700533 GeofenceTransition transition,
534 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800535 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700536
Wyatt Riley5d229832017-02-10 17:06:00 -0800537 jobject jLocation = translateLocation(env, location);
538
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700539 env->CallVoidMethod(mCallbacksObj,
540 method_reportGeofenceTransition,
541 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800542 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700543 transition,
544 timestamp);
545
546 checkAndClearExceptionFromCallback(env, __FUNCTION__);
547 return Void();
548}
549
550Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
551 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800552 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800553 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800554
555 jobject jLocation = translateLocation(env, location);
556
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700557 env->CallVoidMethod(mCallbacksObj,
558 method_reportGeofenceStatus,
559 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800560 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700561 checkAndClearExceptionFromCallback(env, __FUNCTION__);
562 return Void();
563}
564
565Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
566 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800567 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700568 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
569 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
570 }
571
572 env->CallVoidMethod(mCallbacksObj,
573 method_reportGeofenceAddStatus,
574 geofenceId,
575 status);
576 checkAndClearExceptionFromCallback(env, __FUNCTION__);
577 return Void();
578}
579
580Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
581 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800582 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700583 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
584 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
585 }
586
587 env->CallVoidMethod(mCallbacksObj,
588 method_reportGeofenceRemoveStatus,
589 geofenceId, status);
590 checkAndClearExceptionFromCallback(env, __FUNCTION__);
591 return Void();
592}
593
594Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
595 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800596 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700597 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
598 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
599 }
600
601 env->CallVoidMethod(mCallbacksObj,
602 method_reportGeofencePauseStatus,
603 geofenceId, status);
604 checkAndClearExceptionFromCallback(env, __FUNCTION__);
605 return Void();
606}
607
608Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
609 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800610 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700611 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
612 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
613 }
614
615 env->CallVoidMethod(mCallbacksObj,
616 method_reportGeofenceResumeStatus,
617 geofenceId, status);
618 checkAndClearExceptionFromCallback(env, __FUNCTION__);
619 return Void();
620}
621
622/*
623 * GnssNavigationMessageCallback interface implements the callback methods
624 * required by the IGnssNavigationMessage interface.
625 */
626struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
627 /*
628 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
629 * follow.
630 */
631 Return<void> gnssNavigationMessageCb(
632 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
633};
634
635Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
636 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800637 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700638
639 size_t dataLength = message.data.size();
640
641 std::vector<uint8_t> navigationData = message.data;
642 uint8_t* data = &(navigationData[0]);
643 if (dataLength == 0 || data == NULL) {
644 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
645 dataLength);
646 return Void();
647 }
648
649 JavaObject object(env, "android/location/GnssNavigationMessage");
650 SET(Type, static_cast<int32_t>(message.type));
651 SET(Svid, static_cast<int32_t>(message.svid));
652 SET(MessageId, static_cast<int32_t>(message.messageId));
653 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
654 object.callSetter("setData", data, dataLength);
655 SET(Status, static_cast<int32_t>(message.status));
656
657 jobject navigationMessage = object.get();
658 env->CallVoidMethod(mCallbacksObj,
659 method_reportNavigationMessages,
660 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800661 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700662 env->DeleteLocalRef(navigationMessage);
663 return Void();
664}
665
666/*
667 * GnssMeasurementCallback implements the callback methods required for the
668 * GnssMeasurement interface.
669 */
670struct GnssMeasurementCallback : public IGnssMeasurementCallback {
671 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
672 private:
673 jobject translateGnssMeasurement(
674 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
675 jobject translateGnssClock(
676 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
677 jobjectArray translateGnssMeasurements(
678 JNIEnv* env,
679 const IGnssMeasurementCallback::GnssMeasurement* measurements,
680 size_t count);
681 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
682};
683
684
685Return<void> GnssMeasurementCallback::GnssMeasurementCb(
686 const IGnssMeasurementCallback::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800687 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700688
689 jobject clock;
690 jobjectArray measurementArray;
691
692 clock = translateGnssClock(env, &data.clock);
693 measurementArray = translateGnssMeasurements(
694 env, data.measurements.data(), data.measurementCount);
695 setMeasurementData(env, clock, measurementArray);
696
697 env->DeleteLocalRef(clock);
698 env->DeleteLocalRef(measurementArray);
699 return Void();
700}
701
702jobject GnssMeasurementCallback::translateGnssMeasurement(
703 JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
Lifu Tang120480f2016-02-07 18:08:19 -0800704 JavaObject object(env, "android/location/GnssMeasurement");
Lifu Tang120480f2016-02-07 18:08:19 -0800705
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700706 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700707
708 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800709 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700710 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800711 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700712 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800713 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700714 measurement->receivedSvTimeUncertaintyInNs);
715 SET(Cn0DbHz, measurement->cN0DbHz);
716 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800717 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700718 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800719 SET(AccumulatedDeltaRangeState,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700720 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
721 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800722 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700723 measurement->accumulatedDeltaRangeUncertaintyM);
724
725 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
726 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
727 }
728
729 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
730 SET(CarrierPhase, measurement->carrierPhase);
731 }
732
733 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
734 SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
735 }
736
737 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
738
739 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
740 SET(SnrInDb, measurement->snrDb);
741 }
Lifu Tang120480f2016-02-07 18:08:19 -0800742
gomo4402af62017-01-11 13:20:13 -0800743 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800744 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800745 }
746
Lifu Tang120480f2016-02-07 18:08:19 -0800747 return object.get();
748}
749
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700750jobject GnssMeasurementCallback::translateGnssClock(
751 JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
752 JavaObject object(env, "android/location/GnssClock");
753
754 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
755 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
756 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
757 }
758
759 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
760 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
761 }
762
763 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
764 SET(FullBiasNanos, clock->fullBiasNs);
765 }
766
767 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
768 SET(BiasNanos, clock->biasNs);
769 }
770
771 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
772 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
773 }
774
775 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
776 SET(DriftNanosPerSecond, clock->driftNsps);
777 }
778
779 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
780 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
781 }
782
783 SET(TimeNanos, clock->timeNs);
784 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
785
786 return object.get();
787}
788
789jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
790 const IGnssMeasurementCallback::GnssMeasurement*
791 measurements, size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800792 if (count == 0) {
destradaaea8a8a62014-06-23 18:19:03 -0700793 return NULL;
794 }
795
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700796 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800797 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800798 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800799 gnssMeasurementClass,
destradaaea8a8a62014-06-23 18:19:03 -0700800 NULL /* initialElement */);
801
Lifu Tang120480f2016-02-07 18:08:19 -0800802 for (uint16_t i = 0; i < count; ++i) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700803 jobject gnssMeasurement = translateGnssMeasurement(
Lifu Tange5a0e212016-01-25 18:02:17 -0800804 env,
Lifu Tang120480f2016-02-07 18:08:19 -0800805 &measurements[i]);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800806 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
807 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -0700808 }
809
Lifu Tang818aa2c2016-02-01 01:52:00 -0800810 env->DeleteLocalRef(gnssMeasurementClass);
811 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700812}
813
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700814void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
815 jobjectArray measurementArray) {
816 jclass gnssMeasurementsEventClass =
817 env->FindClass("android/location/GnssMeasurementsEvent");
818 jmethodID gnssMeasurementsEventCtor =
819 env->GetMethodID(
820 gnssMeasurementsEventClass,
821 "<init>",
822 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800823
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700824 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
825 gnssMeasurementsEventCtor,
826 clock,
827 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800828
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700829 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
830 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800831 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800832 env->DeleteLocalRef(gnssMeasurementsEventClass);
833 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700834}
835
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700836/*
837 * GnssNiCallback implements callback methods required by the IGnssNi interface.
838 */
839struct GnssNiCallback : public IGnssNiCallback {
840 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
841 override;
destradaaea8a8a62014-06-23 18:19:03 -0700842};
843
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700844Return<void> GnssNiCallback::niNotifyCb(
845 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800846 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700847 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
848 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
849
850 if (requestorId && text) {
851 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
852 notification.notificationId, notification.niType,
853 notification.notifyFlags, notification.timeoutSec,
854 notification.defaultResponse, requestorId, text,
855 notification.requestorIdEncoding,
856 notification.notificationIdEncoding);
857 } else {
858 ALOGE("%s: OOM Error\n", __func__);
859 }
860
861 if (requestorId) {
862 env->DeleteLocalRef(requestorId);
863 }
864
865 if (text) {
866 env->DeleteLocalRef(text);
867 }
868 checkAndClearExceptionFromCallback(env, __FUNCTION__);
869 return Void();
870}
871
872/*
873 * AGnssCallback implements callback methods required by the IAGnss interface.
874 */
875struct AGnssCallback : public IAGnssCallback {
876 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
877 Return<void> agnssStatusIpV6Cb(
878 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
879
880 Return<void> agnssStatusIpV4Cb(
881 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
882 private:
883 jbyteArray convertToIpV4(uint32_t ip);
884};
885
886Return<void> AGnssCallback::agnssStatusIpV6Cb(
887 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800888 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700889 jbyteArray byteArray = NULL;
890 bool isSupported = false;
891
892 byteArray = env->NewByteArray(16);
893 if (byteArray != NULL) {
894 env->SetByteArrayRegion(byteArray, 0, 16,
895 (const jbyte*)(agps_status.ipV6Addr.data()));
896 isSupported = true;
897 } else {
898 ALOGE("Unable to allocate byte array for IPv6 address.");
899 }
900
901 IF_ALOGD() {
902 // log the IP for reference in case there is a bogus value pushed by HAL
903 char str[INET6_ADDRSTRLEN];
904 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
905 ALOGD("AGPS IP is v6: %s", str);
906 }
907
908 jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
909 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
910 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
911 agps_status.type, agps_status.status, byteArray);
912
913 checkAndClearExceptionFromCallback(env, __FUNCTION__);
914
915 if (byteArray) {
916 env->DeleteLocalRef(byteArray);
917 }
918
919 return Void();
920}
921
922Return<void> AGnssCallback::agnssStatusIpV4Cb(
923 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800924 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700925 jbyteArray byteArray = NULL;
926
927 uint32_t ipAddr = agps_status.ipV4Addr;
928 byteArray = convertToIpV4(ipAddr);
929
930 IF_ALOGD() {
931 /*
932 * log the IP for reference in case there is a bogus value pushed by
933 * HAL.
934 */
935 char str[INET_ADDRSTRLEN];
936 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
937 ALOGD("AGPS IP is v4: %s", str);
938 }
939
940 jsize byteArrayLength =
941 byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
942 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
943 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
944 agps_status.type, agps_status.status, byteArray);
945
946 checkAndClearExceptionFromCallback(env, __FUNCTION__);
947
948 if (byteArray) {
949 env->DeleteLocalRef(byteArray);
950 }
951 return Void();
952}
953
954jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
955 if (INADDR_NONE == ip) {
956 return NULL;
957 }
958
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800959 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700960 jbyteArray byteArray = env->NewByteArray(4);
961 if (byteArray == NULL) {
962 ALOGE("Unable to allocate byte array for IPv4 address");
963 return NULL;
964 }
965
966 jbyte ipv4[4];
967 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
968 memcpy(ipv4, &ip, sizeof(ipv4));
969 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
970 return byteArray;
971}
972
973/*
974 * AGnssRilCallback implements the callback methods required by the AGnssRil
975 * interface.
976 */
977struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800978 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700979 Return<void> requestRefLocCb() override;
980};
981
Hridya Valsarajub39eb402017-01-11 08:07:40 -0800982Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800983 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700984 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
985 checkAndClearExceptionFromCallback(env, __FUNCTION__);
986 return Void();
987}
988
989Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800990 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
992 checkAndClearExceptionFromCallback(env, __FUNCTION__);
993 return Void();
994}
995
Wyatt Rileycf879db2017-01-12 13:57:38 -0800996/*
997 * GnssBatchingCallback interface implements the callback methods
998 * required by the IGnssBatching interface.
999 */
1000struct GnssBatchingCallback : public IGnssBatchingCallback {
1001 /*
1002 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1003 * follow.
1004 */
1005 Return<void> gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001006 const ::android::hardware::hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001007 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001008};
1009
1010Return<void> GnssBatchingCallback::gnssLocationBatchCb(
Wyatt Rileyfb840922017-11-08 15:07:58 -08001011 const ::android::hardware::hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001012 JNIEnv* env = getJniEnv();
1013
1014 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1015 env->FindClass("android/location/Location"), nullptr);
1016
1017 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001018 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001019 env->SetObjectArrayElement(jLocations, i, jLocation);
1020 env->DeleteLocalRef(jLocation);
1021 }
1022
1023 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1024 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1025
1026 env->DeleteLocalRef(jLocations);
1027
1028 return Void();
1029}
1030
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001031static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001032 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1033 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001034 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
1035 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
1036 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1037 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1038 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1039 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001040 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1041 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001042 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1043 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1044 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
1045 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1046 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1047 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1048 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001049 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001050 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001051 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001052 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1053 "(II)V");
1054 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1055 "(II)V");
1056 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1057 "(II)V");
1058 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1059 "(II)V");
1060 method_reportMeasurementData = env->GetMethodID(
1061 clazz,
1062 "reportMeasurementData",
1063 "(Landroid/location/GnssMeasurementsEvent;)V");
1064 method_reportNavigationMessages = env->GetMethodID(
1065 clazz,
1066 "reportNavigationMessage",
1067 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001068 method_reportLocationBatch = env->GetMethodID(
1069 clazz,
1070 "reportLocationBatch",
1071 "([Landroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001072
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001073 /*
1074 * Save a pointer to JVM.
1075 */
1076 jint jvmStatus = env->GetJavaVM(&sJvm);
1077 if (jvmStatus != JNI_OK) {
1078 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1079 }
1080
gomo48f1a642017-11-10 20:35:46 -08001081 // TODO(b/31632518)
1082 gnssHal_V1_1 = IGnss_V1_1::getService();
1083 if (gnssHal_V1_1 == nullptr) {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001084 ALOGD("gnssHal 1.1 was null, trying 1.0");
1085 gnssHal = IGnss::getService();
gomo48f1a642017-11-10 20:35:46 -08001086 } else {
1087 gnssHal = gnssHal_V1_1;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001088 }
1089
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001090 if (gnssHal != nullptr) {
gomo25208882017-04-15 02:05:25 -07001091 gnssHalDeathRecipient = new GnssDeathRecipient();
1092 hardware::Return<bool> linked = gnssHal->linkToDeath(
1093 gnssHalDeathRecipient, /*cookie*/ 0);
1094 if (!linked.isOk()) {
1095 ALOGE("Transaction error in linking to GnssHAL death: %s",
1096 linked.description().c_str());
1097 } else if (!linked) {
1098 ALOGW("Unable to link to GnssHal death notifications");
1099 } else {
1100 ALOGD("Link to death notification successful");
1101 }
1102
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001103 auto gnssXtra = gnssHal->getExtensionXtra();
1104 if (!gnssXtra.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001105 ALOGD("Unable to get a handle to Xtra");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001106 } else {
1107 gnssXtraIface = gnssXtra;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001108 }
1109
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001110 auto gnssRil = gnssHal->getExtensionAGnssRil();
1111 if (!gnssRil.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001112 ALOGD("Unable to get a handle to AGnssRil");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001113 } else {
1114 agnssRilIface = gnssRil;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001115 }
1116
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001117 auto gnssAgnss = gnssHal->getExtensionAGnss();
1118 if (!gnssAgnss.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001119 ALOGD("Unable to get a handle to AGnss");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001120 } else {
1121 agnssIface = gnssAgnss;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001122 }
1123
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001124 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1125 if (!gnssNavigationMessage.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001126 ALOGD("Unable to get a handle to GnssNavigationMessage");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001127 } else {
1128 gnssNavigationMessageIface = gnssNavigationMessage;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001129 }
1130
gomo48f1a642017-11-10 20:35:46 -08001131 if (gnssHal_V1_1 != nullptr) {
1132 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1133 if (!gnssMeasurement.isOk()) {
1134 ALOGD("Unable to get a handle to GnssMeasurement");
1135 } else {
1136 gnssMeasurementIface_V1_1 = gnssMeasurement;
1137 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1138 }
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001139 } else {
gomo48f1a642017-11-10 20:35:46 -08001140 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1141 if (!gnssMeasurement_V1_0.isOk()) {
1142 ALOGD("Unable to get a handle to GnssMeasurement");
1143 } else {
1144 gnssMeasurementIface = gnssMeasurement_V1_0;
1145 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001146 }
1147
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001148 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1149 if (!gnssDebug.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001150 ALOGD("Unable to get a handle to GnssDebug");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001151 } else {
1152 gnssDebugIface = gnssDebug;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001153 }
1154
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001155 auto gnssNi = gnssHal->getExtensionGnssNi();
1156 if (!gnssNi.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001157 ALOGD("Unable to get a handle to GnssNi");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001158 } else {
1159 gnssNiIface = gnssNi;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001160 }
1161
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001162 auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
1163 if (!gnssConfiguration.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001164 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001165 } else {
1166 gnssConfigurationIface = gnssConfiguration;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001167 }
1168
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001169 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1170 if (!gnssGeofencing.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001171 ALOGD("Unable to get a handle to GnssGeofencing");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001172 } else {
1173 gnssGeofencingIface = gnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001174 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001175
1176 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1177 if (!gnssBatching.isOk()) {
1178 ALOGD("Unable to get a handle to gnssBatching");
1179 } else {
1180 gnssBatchingIface = gnssBatching;
1181 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001182 } else {
1183 ALOGE("Unable to get GPS service\n");
1184 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001185}
1186
1187static jboolean android_location_GnssLocationProvider_is_supported(
1188 JNIEnv* /* env */, jclass /* clazz */) {
1189 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1190}
1191
1192static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
1193 JNIEnv* /* env */, jclass /* clazz */) {
1194 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1195}
1196
1197static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1198 JNIEnv* /* env */, jclass /* jclazz */) {
1199 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1200}
1201
1202static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1203 /*
1204 * This must be set before calling into the HAL library.
1205 */
1206 if (!mCallbacksObj)
1207 mCallbacksObj = env->NewGlobalRef(obj);
1208
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001209 /*
1210 * Fail if the main interface fails to initialize
1211 */
1212 if (gnssHal == nullptr) {
1213 ALOGE("Unable to Initialize GNSS HAL\n");
1214 return JNI_FALSE;
1215 }
1216
Wyatt Rileyfb840922017-11-08 15:07:58 -08001217 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1218
1219 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001220 if (gnssHal_V1_1 != nullptr) {
1221 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001222 } else {
1223 result = gnssHal->setCallback(gnssCbIface);
1224 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001225 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001226 ALOGE("SetCallback for Gnss Interface fails\n");
1227 return JNI_FALSE;
1228 }
1229
1230 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1231 if (gnssXtraIface == nullptr) {
1232 ALOGE("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001233 } else {
1234 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001235 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001236 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001237 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001238 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001239 }
1240
1241 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1242 if (agnssIface != nullptr) {
1243 agnssIface->setCallback(aGnssCbIface);
1244 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001245 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001246 }
1247
1248 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1249 if (gnssGeofencingIface != nullptr) {
1250 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1251 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001252 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001253 }
1254
1255 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001256 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001257 gnssNiIface->setCallback(gnssNiCbIface);
1258 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001259 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001260 }
1261
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001262 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1263 if (agnssRilIface != nullptr) {
1264 agnssRilIface->setCallback(aGnssRilCbIface);
1265 } else {
1266 ALOGI("Unable to Initialize AGnss Ril interface\n");
1267 }
1268
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001269 return JNI_TRUE;
1270}
1271
1272static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1273 if (gnssHal != nullptr) {
1274 gnssHal->cleanup();
1275 }
1276}
1277
1278static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1279 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001280 jint preferred_time, jboolean low_power_mode) {
1281 Return<bool> result = false;
1282 if (gnssHal_V1_1 != nullptr) {
1283 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
1284 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1285 min_interval,
1286 preferred_accuracy,
1287 preferred_time,
1288 low_power_mode);
1289 } else if (gnssHal != nullptr) {
1290 result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
1291 static_cast<IGnss::GnssPositionRecurrence>(recurrence),
1292 min_interval,
1293 preferred_accuracy,
1294 preferred_time);
1295 }
1296 if (!result.isOk()) {
1297 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1298 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001299 } else {
gomo48f1a642017-11-10 20:35:46 -08001300 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001301 }
1302}
1303
1304static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1305 if (gnssHal != nullptr) {
1306 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001307 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001308 return JNI_FALSE;
1309 } else {
1310 return result;
1311 }
1312 } else {
1313 return JNI_FALSE;
1314 }
1315}
1316
1317static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1318 if (gnssHal != nullptr) {
1319 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001320 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001321 return JNI_FALSE;
1322 } else {
1323 return result;
1324 }
1325 } else {
1326 return JNI_FALSE;
1327 }
1328}
1329static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1330 jobject /* obj */,
1331 jint flags) {
1332 if (gnssHal != nullptr) {
1333 auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001334 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001335 ALOGE("Error in deleting aiding data");
1336 }
1337 }
1338}
1339
1340/*
1341 * This enum is used by the read_sv_status method to combine the svid,
1342 * constellation and svFlag fields.
1343 */
1344enum ShiftWidth: uint8_t {
Yipeng Cao21717812017-04-27 18:35:24 -07001345 SVID_SHIFT_WIDTH = 8,
1346 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001347};
1348
1349static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
1350 jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
gomo4402af62017-01-11 13:20:13 -08001351 jfloatArray azumArray, jfloatArray carrierFreqArray) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001352 /*
1353 * This method should only be called from within a call to reportSvStatus.
1354 */
1355 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
1356 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
1357 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
1358 jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
gomo4402af62017-01-11 13:20:13 -08001359 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001360
1361 /*
1362 * Read GNSS SV info.
1363 */
1364 for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
1365 const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
1366 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
1367 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
1368 static_cast<uint32_t>(info.svFlag);
1369 cn0s[i] = info.cN0Dbhz;
1370 elev[i] = info.elevationDegrees;
1371 azim[i] = info.azimuthDegrees;
gomo4402af62017-01-11 13:20:13 -08001372 carrierFreq[i] = info.carrierFrequencyHz;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001373 }
1374
1375 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
1376 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
1377 env->ReleaseFloatArrayElements(elevArray, elev, 0);
1378 env->ReleaseFloatArrayElements(azumArray, azim, 0);
gomo4402af62017-01-11 13:20:13 -08001379 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001380 return static_cast<jint>(GnssCallback::sGnssSvListSize);
1381}
1382
1383static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1384 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1385 IAGnssRil::AGnssRefLocation location;
1386
1387 if (agnssRilIface == nullptr) {
1388 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1389 return;
1390 }
1391
1392 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1393 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1394 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1395 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1396 location.cellID.mcc = mcc;
1397 location.cellID.mnc = mnc;
1398 location.cellID.lac = lac;
1399 location.cellID.cid = cid;
1400 break;
1401 default:
1402 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1403 return;
1404 break;
1405 }
1406
1407 agnssRilIface->setRefLocation(location);
1408}
1409
1410static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1411 jint type, jstring setid_string) {
1412 if (agnssRilIface == nullptr) {
1413 ALOGE("no AGPS RIL interface in agps_set_id");
1414 return;
1415 }
1416
1417 const char *setid = env->GetStringUTFChars(setid_string, NULL);
1418 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1419 env->ReleaseStringUTFChars(setid_string, setid);
1420}
1421
1422static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1423 jbyteArray nmeaArray, jint buffer_size) {
1424 // this should only be called from within a call to reportNmea
1425 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1426 int length = GnssCallback::sNmeaStringLength;
1427 if (length > buffer_size)
1428 length = buffer_size;
1429 memcpy(nmea, GnssCallback::sNmeaString, length);
1430 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1431 return (jint) length;
1432}
1433
1434static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1435 jlong time, jlong timeReference, jint uncertainty) {
1436 if (gnssHal != nullptr) {
1437 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001438 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001439 ALOGE("%s: Gnss injectTime() failed", __func__);
1440 }
1441 }
1442}
1443
1444static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1445 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1446 if (gnssHal != nullptr) {
1447 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001448 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001449 ALOGE("%s: Gnss injectLocation() failed", __func__);
1450 }
1451 }
1452}
1453
1454static jboolean android_location_GnssLocationProvider_supports_xtra(
1455 JNIEnv* /* env */, jobject /* obj */) {
1456 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1457}
1458
1459static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1460 jbyteArray data, jint length) {
1461 if (gnssXtraIface == nullptr) {
1462 ALOGE("XTRA Interface not supported");
1463 return;
1464 }
1465
1466 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1467 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1468 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1469}
1470
1471static void android_location_GnssLocationProvider_agps_data_conn_open(
1472 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1473 if (agnssIface == nullptr) {
1474 ALOGE("no AGPS interface in agps_data_conn_open");
1475 return;
1476 }
1477 if (apn == NULL) {
1478 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1479 return;
1480 }
1481
1482 const char *apnStr = env->GetStringUTFChars(apn, NULL);
1483
1484 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001485 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001486 ALOGE("%s: Failed to set APN and its IP type", __func__);
1487 }
1488 env->ReleaseStringUTFChars(apn, apnStr);
1489}
1490
1491static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
1492 jobject /* obj */) {
1493 if (agnssIface == nullptr) {
1494 ALOGE("%s: AGPS interface not supported", __func__);
1495 return;
1496 }
1497
1498 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001499 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001500 ALOGE("%s: Failed to close AGnss data connection", __func__);
1501 }
1502}
1503
1504static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
1505 jobject /* obj */) {
1506 if (agnssIface == nullptr) {
1507 ALOGE("%s: AGPS interface not supported", __func__);
1508 return;
1509 }
1510
1511 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001512 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001513 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1514 }
1515}
1516
1517static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1518 jint type, jstring hostname, jint port) {
1519 if (agnssIface == nullptr) {
1520 ALOGE("no AGPS interface in set_agps_server");
1521 return;
1522 }
1523
1524 const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
1525 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1526 c_hostname,
1527 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001528 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001529 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1530 }
1531
1532 env->ReleaseStringUTFChars(hostname, c_hostname);
1533}
1534
1535static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1536 jobject /* obj */, jint notifId, jint response) {
1537 if (gnssNiIface == nullptr) {
1538 ALOGE("no NI interface in send_ni_response");
1539 return;
1540 }
1541
1542 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1543}
1544
1545static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1546 jobject /* obj */) {
1547 jstring result = NULL;
1548 /*
1549 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1550 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001551
1552 std::stringstream internalState;
1553
1554 if (gnssDebugIface == nullptr) {
1555 internalState << "Gnss Debug Interface not available" << std::endl;
1556 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001557 IGnssDebug::DebugData data;
1558 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1559 data = debugData;
1560 });
1561
Wyatt Riley268c6e02017-03-29 10:21:46 -07001562 internalState << "Gnss Location Data:: ";
1563 if (!data.position.valid) {
1564 internalState << "not valid";
1565 } else {
1566 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001567 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1568 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001569 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1570 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001571 << ", horizontalAccuracyMeters: "
1572 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001573 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001574 << ", speedAccuracyMetersPerSecond: "
1575 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001576 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001577 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001578 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001579 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001580
Wyatt Riley268c6e02017-03-29 10:21:46 -07001581 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1582 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1583 << ", frequencyUncertaintyNsPerSec: "
1584 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001585
1586 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001587 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1588 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001589 }
1590
Wyatt Riley77ca4f82017-06-30 18:13:44 -07001591 internalState << "constellation: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1592 << "ephemerisType: 0=Eph, 1=Alm, 2=?; "
1593 << "ephemerisSource: 0=Demod, 1=Supl, 2=Server, 3=?; "
1594 << "ephemerisHealth: 0=Good, 1=Bad, 2=?" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001595 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
1596 internalState << "svid: " << data.satelliteDataArray[i].svid
1597 << ", constellation: "
1598 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
1599 << ", ephemerisType: "
1600 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001601 << ", ephemerisSource: "
1602 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1603 << ", ephemerisHealth: "
1604 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1605 << ", serverPredictionIsAvailable: "
1606 << data.satelliteDataArray[i].serverPredictionIsAvailable
1607 << ", serverPredictionAgeSeconds: "
1608 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001609 << ", ephemerisAgeSeconds: "
1610 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1611 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001612 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001613
1614 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001615 return result;
1616}
1617
1618static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
1619 jobject /* obj */,
1620 jboolean connected,
1621 jint type,
1622 jboolean roaming,
1623 jboolean available,
1624 jstring extraInfo,
1625 jstring apn) {
1626 if (agnssRilIface != nullptr) {
1627 auto result = agnssRilIface->updateNetworkState(connected,
1628 static_cast<IAGnssRil::NetworkType>(type),
1629 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001630 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001631 ALOGE("updateNetworkState failed");
1632 }
1633
1634 const char *c_apn = env->GetStringUTFChars(apn, NULL);
1635 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001636 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001637 ALOGE("updateNetworkAvailability failed");
1638 }
1639
1640 env->ReleaseStringUTFChars(apn, c_apn);
1641 } else {
1642 ALOGE("AGnssRilInterface does not exist");
1643 }
1644}
1645
1646static jboolean android_location_GnssLocationProvider_is_geofence_supported(
1647 JNIEnv* /* env */, jobject /* obj */) {
1648 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1649}
1650
1651static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
1652 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1653 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1654 jint unknown_timer) {
1655 if (gnssGeofencingIface != nullptr) {
1656 auto result = gnssGeofencingIface->addGeofence(
1657 geofenceId, latitude, longitude, radius,
1658 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1659 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001660 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001661 } else {
1662 ALOGE("Geofence Interface not available");
1663 }
1664 return JNI_FALSE;
1665}
1666
1667static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
1668 jobject /* obj */, jint geofenceId) {
1669 if (gnssGeofencingIface != nullptr) {
1670 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001671 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001672 } else {
1673 ALOGE("Geofence interface not available");
1674 }
1675 return JNI_FALSE;
1676}
1677
1678static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
1679 jobject /* obj */, jint geofenceId) {
1680 if (gnssGeofencingIface != nullptr) {
1681 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001682 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683 } else {
1684 ALOGE("Geofence interface not available");
1685 }
1686 return JNI_FALSE;
1687}
1688
1689static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
1690 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1691 if (gnssGeofencingIface != nullptr) {
1692 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001693 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001694 } else {
1695 ALOGE("Geofence interface not available");
1696 }
1697 return JNI_FALSE;
1698}
1699
Lifu Tang30f95a72016-01-07 23:20:38 -08001700static jboolean android_location_GnssLocationProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001701 JNIEnv* env, jclass clazz) {
1702 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001703 return JNI_TRUE;
1704 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705
destradaaea8a8a62014-06-23 18:19:03 -07001706 return JNI_FALSE;
1707}
1708
Lifu Tang30f95a72016-01-07 23:20:38 -08001709static jboolean android_location_GnssLocationProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001710 JNIEnv* /* env */,
1711 jobject /* obj */,
1712 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001713 if (gnssMeasurementIface == nullptr) {
1714 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001715 return JNI_FALSE;
1716 }
1717
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001718 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001719 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
1720 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
1721 if (gnssMeasurementIface_V1_1 != nullptr) {
1722 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
1723 enableFullTracking);
1724 } else {
1725 if (enableFullTracking == JNI_TRUE) {
1726 // full tracking mode not supported in 1.0 HAL
1727 return JNI_FALSE;
1728 }
1729 result = gnssMeasurementIface->setCallback(cbIface);
1730 }
1731
1732 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001733 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1734 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001735 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001736 } else {
1737 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001738 }
1739
1740 return JNI_TRUE;
1741}
1742
Lifu Tang30f95a72016-01-07 23:20:38 -08001743static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001744 JNIEnv* env,
1745 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001746 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001747 ALOGE("Measurement interface not available");
1748 return JNI_FALSE;
1749 }
1750
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001751 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001752 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001753}
1754
Lifu Tang30f95a72016-01-07 23:20:38 -08001755static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001756 JNIEnv* env,
1757 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001758 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001759 return JNI_TRUE;
1760 }
1761 return JNI_FALSE;
1762}
1763
Lifu Tang30f95a72016-01-07 23:20:38 -08001764static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001765 JNIEnv* env,
1766 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001767 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001768 ALOGE("Navigation Message interface is not available.");
1769 return JNI_FALSE;
1770 }
1771
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001772 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1773 new GnssNavigationMessageCallback();
1774 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1775 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1776
1777 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1778 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001779 return JNI_FALSE;
1780 }
1781
1782 return JNI_TRUE;
1783}
1784
Lifu Tang30f95a72016-01-07 23:20:38 -08001785static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001786 JNIEnv* env,
1787 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001788 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001789 ALOGE("Navigation Message interface is not available.");
1790 return JNI_FALSE;
1791 }
1792
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001793 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001794 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001795}
1796
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001797static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1798 jobject,
1799 jint emergencySuplPdn) {
1800 if (gnssConfigurationIface == nullptr) {
1801 ALOGE("no GNSS configuration interface available");
1802 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001803 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001804
1805 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001806 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001807 return result;
1808 } else {
1809 return JNI_FALSE;
1810 }
1811}
1812
1813static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1814 jobject,
1815 jint version) {
1816 if (gnssConfigurationIface == nullptr) {
1817 ALOGE("no GNSS configuration interface available");
1818 return JNI_FALSE;
1819 }
1820 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001821 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001822 return result;
1823 } else {
1824 return JNI_FALSE;
1825 }
1826}
1827
1828static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1829 jobject,
1830 jint suplEs) {
1831 if (gnssConfigurationIface == nullptr) {
1832 ALOGE("no GNSS configuration interface available");
1833 return JNI_FALSE;
1834 }
1835
1836 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001837 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001838 return result;
1839 } else {
1840 return JNI_FALSE;
1841 }
1842}
1843
1844static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1845 jobject,
1846 jint mode) {
1847 if (gnssConfigurationIface == nullptr) {
1848 ALOGE("no GNSS configuration interface available");
1849 return JNI_FALSE;
1850 }
1851
1852 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001853 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001854 return result;
1855 } else {
1856 return JNI_FALSE;
1857 }
1858}
1859
1860static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1861 jobject,
1862 jint gpsLock) {
1863 if (gnssConfigurationIface == nullptr) {
1864 ALOGE("no GNSS configuration interface available");
1865 return JNI_FALSE;
1866 }
1867
1868 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001869 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001870 return result;
1871 } else {
1872 return JNI_FALSE;
1873 }
1874}
1875
1876static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
1877 jobject,
1878 jint lppProfile) {
1879 if (gnssConfigurationIface == nullptr) {
1880 ALOGE("no GNSS configuration interface available");
1881 return JNI_FALSE;
1882 }
1883
1884 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
1885
Steven Morelandd002a8b2017-01-03 17:18:24 -08001886 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001887 return result;
1888 } else {
1889 return JNI_FALSE;
1890 }
1891}
1892
1893static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
1894 jobject,
1895 jint gnssPosProtocol) {
1896 if (gnssConfigurationIface == nullptr) {
1897 ALOGE("no GNSS configuration interface available");
1898 return JNI_FALSE;
1899 }
1900
1901 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001902 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001903 return result;
1904 } else {
1905 return JNI_FALSE;
1906 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001907}
1908
Wyatt Rileycf879db2017-01-12 13:57:38 -08001909static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
1910 if (gnssBatchingIface == nullptr) {
1911 return 0; // batching not supported, size = 0
1912 }
1913 auto result = gnssBatchingIface->getBatchSize();
1914 if (result.isOk()) {
1915 return static_cast<jint>(result);
1916 } else {
1917 return 0; // failure in binder, don't support batching
1918 }
1919}
1920
1921static jboolean android_location_GnssLocationProvider_init_batching(JNIEnv*, jclass) {
1922 if (gnssBatchingIface == nullptr) {
1923 return JNI_FALSE; // batching not supported
1924 }
1925 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
1926
1927 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
1928}
1929
1930static void android_location_GnssLocationProvider_cleanup_batching(JNIEnv*, jclass) {
1931 if (gnssBatchingIface == nullptr) {
1932 return; // batching not supported
1933 }
1934 gnssBatchingIface->cleanup();
1935}
1936
1937static jboolean android_location_GnssLocationProvider_start_batch(JNIEnv*, jclass,
1938 jlong periodNanos, jboolean wakeOnFifoFull) {
1939 if (gnssBatchingIface == nullptr) {
1940 return JNI_FALSE; // batching not supported
1941 }
1942
1943 IGnssBatching::Options options;
1944 options.periodNanos = periodNanos;
1945 if (wakeOnFifoFull) {
1946 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
1947 } else {
1948 options.flags = 0;
1949 }
1950
1951 return static_cast<jboolean>(gnssBatchingIface->start(options));
1952}
1953
1954static void android_location_GnssLocationProvider_flush_batch(JNIEnv*, jclass) {
1955 if (gnssBatchingIface == nullptr) {
1956 return; // batching not supported
1957 }
1958
1959 gnssBatchingIface->flush();
1960}
1961
1962static jboolean android_location_GnssLocationProvider_stop_batch(JNIEnv*, jclass) {
1963 if (gnssBatchingIface == nullptr) {
1964 return JNI_FALSE; // batching not supported
1965 }
1966
1967 return gnssBatchingIface->stop();
1968}
1969
Daniel Micay76f6a862015-09-19 17:31:01 -04001970static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001972 {"class_init_native", "()V", reinterpret_cast<void *>(
1973 android_location_GnssLocationProvider_class_init_native)},
1974 {"native_is_supported", "()Z", reinterpret_cast<void *>(
1975 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07001976 {"native_is_agps_ril_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001977 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
destradaaef752b62015-04-17 13:10:47 -07001978 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001979 reinterpret_cast<void *>(
1980 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
1981 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
1982 {"native_cleanup", "()V", reinterpret_cast<void *>(
1983 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07001984 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08001985 "(IIIIIZ)Z",
1986 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001987 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
1988 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07001989 {"native_delete_aiding_data",
1990 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001991 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
destradaaea8a8a62014-06-23 18:19:03 -07001992 {"native_read_sv_status",
gomo4402af62017-01-11 13:20:13 -08001993 "([I[F[F[F[F)I",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001994 reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
1995 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
1996 android_location_GnssLocationProvider_read_nmea)},
1997 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
1998 android_location_GnssLocationProvider_inject_time)},
destradaaea8a8a62014-06-23 18:19:03 -07001999 {"native_inject_location",
2000 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002001 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2002 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2003 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002004 {"native_inject_xtra_data",
2005 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002006 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002007 {"native_agps_data_conn_open",
2008 "(Ljava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002009 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
destradaaea8a8a62014-06-23 18:19:03 -07002010 {"native_agps_data_conn_closed",
2011 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002012 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
destradaaea8a8a62014-06-23 18:19:03 -07002013 {"native_agps_data_conn_failed",
2014 "()V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002015 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
destradaaea8a8a62014-06-23 18:19:03 -07002016 {"native_agps_set_id",
2017 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002018 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002019 {"native_agps_set_ref_location_cellid",
2020 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002021 reinterpret_cast<void *>(
2022 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002023 {"native_set_agps_server",
2024 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002025 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002026 {"native_send_ni_response",
2027 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002028 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002029 {"native_get_internal_state",
2030 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002031 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002032 {"native_update_network_state",
2033 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002034 reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
destradaaea8a8a62014-06-23 18:19:03 -07002035 {"native_is_geofence_supported",
2036 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002037 reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002038 {"native_add_geofence",
2039 "(IDDDIIII)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002040 reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002041 {"native_remove_geofence",
2042 "(I)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002043 reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
2044 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2045 android_location_GnssLocationProvider_pause_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002046 {"native_resume_geofence",
2047 "(II)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002048 reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
destradaaea8a8a62014-06-23 18:19:03 -07002049 {"native_is_measurement_supported",
2050 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002051 reinterpret_cast<void *>(
2052 android_location_GnssLocationProvider_is_measurement_supported)},
destradaaea8a8a62014-06-23 18:19:03 -07002053 {"native_start_measurement_collection",
gomo48f1a642017-11-10 20:35:46 -08002054 "(Z)Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002055 reinterpret_cast<void *>(
2056 android_location_GnssLocationProvider_start_measurement_collection)},
destradaaea8a8a62014-06-23 18:19:03 -07002057 {"native_stop_measurement_collection",
2058 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002059 reinterpret_cast<void *>(
2060 android_location_GnssLocationProvider_stop_measurement_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002061 {"native_is_navigation_message_supported",
2062 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002063 reinterpret_cast<void *>(
2064 android_location_GnssLocationProvider_is_navigation_message_supported)},
destradaa4b3e3932014-07-21 18:01:47 -07002065 {"native_start_navigation_message_collection",
2066 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002067 reinterpret_cast<void *>(
2068 android_location_GnssLocationProvider_start_navigation_message_collection)},
destradaa4b3e3932014-07-21 18:01:47 -07002069 {"native_stop_navigation_message_collection",
2070 "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002071 reinterpret_cast<void *>(
2072 android_location_GnssLocationProvider_stop_navigation_message_collection)},
2073 {"native_set_supl_es",
2074 "(I)Z",
2075 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2076 {"native_set_supl_version",
2077 "(I)Z",
2078 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2079 {"native_set_supl_mode",
2080 "(I)Z",
2081 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2082 {"native_set_lpp_profile",
2083 "(I)Z",
2084 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2085 {"native_set_gnss_pos_protocol_select",
2086 "(I)Z",
2087 reinterpret_cast<void *>(
2088 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2089 {"native_set_gps_lock",
2090 "(I)Z",
2091 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2092 {"native_set_emergency_supl_pdn",
2093 "(I)Z",
2094 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002095 {"native_get_batch_size",
2096 "()I",
2097 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
2098 {"native_init_batching",
2099 "()Z",
2100 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2101 {"native_start_batch",
2102 "(JZ)Z",
2103 reinterpret_cast<void *>(android_location_GnssLocationProvider_start_batch)},
2104 {"native_flush_batch",
2105 "()V",
2106 reinterpret_cast<void *>(android_location_GnssLocationProvider_flush_batch)},
2107 {"native_stop_batch",
2108 "()Z",
2109 reinterpret_cast<void *>(android_location_GnssLocationProvider_stop_batch)},
2110 {"native_init_batching",
2111 "()Z",
2112 reinterpret_cast<void *>(android_location_GnssLocationProvider_init_batching)},
2113 {"native_cleanup_batching",
2114 "()V",
2115 reinterpret_cast<void *>(android_location_GnssLocationProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116};
2117
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002118int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
destradaaea8a8a62014-06-23 18:19:03 -07002119 return jniRegisterNativeMethods(
2120 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002121 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002122 sMethods,
2123 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124}
2125
2126} /* namespace android */