blob: 4d0556c7507aa571568d1c8547d41eeeae1bac24 [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>
Yu-Han Yang88d79102018-11-14 14:20:57 -080023#include <android/hardware/gnss/2.0/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070024
gomo48f1a642017-11-10 20:35:46 -080025#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
26#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Yu-Han Yang88d79102018-11-14 14:20:57 -080027#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070028#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040030#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031#include "utils/Log.h"
32#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070033#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070034#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035
destradaa931a37f2014-08-12 16:36:59 -070036#include <arpa/inet.h>
Lifu Tang38bce792016-02-24 17:17:38 -080037#include <limits>
destradaa96a14702014-06-05 11:36:30 -070038#include <linux/in.h>
39#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080040#include <pthread.h>
41#include <string.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070042#include <cinttypes>
Wyatt Rileyb6a50f02018-05-03 13:59:04 -070043#include <iomanip>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
WyattRiley840c0b22018-10-31 09:03:53 -070045static jobject mCallbacksObj = nullptr;
Mike Lockwoodf602d362010-06-20 14:28:16 -070046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047static jmethodID method_reportLocation;
48static jmethodID method_reportStatus;
49static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040050static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040051static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040052static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080053static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080054static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040056static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080057static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020058static jmethodID method_requestRefLocation;
59static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040060static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070061static jmethodID method_reportGeofenceTransition;
62static jmethodID method_reportGeofenceStatus;
63static jmethodID method_reportGeofenceAddStatus;
64static jmethodID method_reportGeofenceRemoveStatus;
65static jmethodID method_reportGeofencePauseStatus;
66static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070067static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070068static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080069static jmethodID method_reportLocationBatch;
Yu-Han Yang52057622018-04-25 00:51:22 -070070static jmethodID method_reportGnssServiceDied;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080072/*
73 * Save a pointer to JavaVm to attach/detach threads executing
74 * callback methods that need to make JNI calls.
75 */
76static JavaVM* sJvm;
77
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070078using android::OK;
79using android::sp;
gomo25208882017-04-15 02:05:25 -070080using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070081using android::status_t;
82using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070084using android::hardware::Return;
85using android::hardware::Void;
86using android::hardware::hidl_vec;
gomo25208882017-04-15 02:05:25 -070087using android::hardware::hidl_death_recipient;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070088using android::hardware::gnss::V1_0::GnssConstellationType;
Wyatt Rileyfb840922017-11-08 15:07:58 -080089using android::hardware::gnss::V1_0::GnssLocation;
90using android::hardware::gnss::V1_0::GnssLocationFlags;
Wyatt Riley46ac9562018-03-02 20:16:58 -080091
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070092using android::hardware::gnss::V1_0::IAGnss;
93using android::hardware::gnss::V1_0::IAGnssCallback;
94using android::hardware::gnss::V1_0::IAGnssCallback;
95using android::hardware::gnss::V1_0::IAGnssRil;
96using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -080097using android::hardware::gnss::V1_0::IGnssBatching;
98using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070099using android::hardware::gnss::V1_0::IGnssDebug;
100using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
101using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700102using android::hardware::gnss::V1_0::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 Rileybb9bc842018-02-14 08:46:00 -0800108
Wyatt Rileyfb840922017-11-08 15:07:58 -0800109using android::hardware::gnss::V1_1::IGnssCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800110
111using android::hidl::base::V1_0::IBase;
112
113using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
114using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800115using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700116using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
117using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800118using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
119using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800120using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800121using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
122using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800123using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800124
gomo25208882017-04-15 02:05:25 -0700125struct GnssDeathRecipient : virtual public hidl_death_recipient
126{
127 // hidl_death_recipient interface
128 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700129 ALOGE("IGNSS hidl service failed, trying to recover...");
130
131 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
132 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700133 }
134};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700135
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800136// Must match the value from GnssMeasurement.java
137static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
138
gomo25208882017-04-15 02:05:25 -0700139sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800140sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800141sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800142sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700143sp<IGnssXtra> gnssXtraIface = nullptr;
144sp<IAGnssRil> agnssRilIface = nullptr;
145sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
146sp<IAGnss> agnssIface = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800147sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700148sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700149sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
150sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700151sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800152sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
153sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800154sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700155sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400157#define WAKE_LOCK_NAME "GPS"
158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159namespace android {
160
Lifu Tang120480f2016-02-07 18:08:19 -0800161template<class T>
162class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700163 public:
164 // Helper function to call setter on a Java object.
165 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800166 JNIEnv* env,
167 jclass clazz,
168 jobject object,
169 const char* method_name,
170 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700171
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700172 private:
Lifu Tang120480f2016-02-07 18:08:19 -0800173 static const char *const signature_;
174};
Lifu Tange5a0e212016-01-25 18:02:17 -0800175
Lifu Tang120480f2016-02-07 18:08:19 -0800176template<class T>
177void JavaMethodHelper<T>::callJavaMethod(
178 JNIEnv* env,
179 jclass clazz,
180 jobject object,
181 const char* method_name,
182 T value) {
183 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
184 env->CallVoidMethod(object, method, value);
185}
destradaaea8a8a62014-06-23 18:19:03 -0700186
Lifu Tang120480f2016-02-07 18:08:19 -0800187class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700188 public:
189 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800190 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700191 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800192
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700193 template<class T>
194 void callSetter(const char* method_name, T value);
195 template<class T>
196 void callSetter(const char* method_name, T* value, size_t size);
197 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800198
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700199 private:
200 JNIEnv* env_;
201 jclass clazz_;
202 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800203};
204
205JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
206 clazz_ = env_->FindClass(class_name);
207 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
208 object_ = env_->NewObject(clazz_, ctor);
209}
210
Wyatt Rileycf879db2017-01-12 13:57:38 -0800211JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
212 clazz_ = env_->FindClass(class_name);
213 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
214 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
215}
216
Lifu Tang120480f2016-02-07 18:08:19 -0800217JavaObject::~JavaObject() {
218 env_->DeleteLocalRef(clazz_);
219}
220
221template<class T>
222void JavaObject::callSetter(const char* method_name, T value) {
223 JavaMethodHelper<T>::callJavaMethod(
224 env_, clazz_, object_, method_name, value);
225}
226
227template<>
228void JavaObject::callSetter(
229 const char* method_name, uint8_t* value, size_t size) {
230 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700231 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800232 jmethodID method = env_->GetMethodID(
233 clazz_,
234 method_name,
235 "([B)V");
236 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700237 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800238}
239
240jobject JavaObject::get() {
241 return object_;
242}
243
244// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800245template<>
246const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
247template<>
248const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
249template<>
250const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
251template<>
252const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
253template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800254const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
255template<>
256const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800257template<>
258const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
259template<>
260const char *const JavaMethodHelper<float>::signature_ = "(F)V";
261template<>
262const char *const JavaMethodHelper<double>::signature_ = "(D)V";
263template<>
264const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
265
266#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800267
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700268static inline jboolean boolToJbool(bool value) {
269 return value ? JNI_TRUE : JNI_FALSE;
270}
Lifu Tang120480f2016-02-07 18:08:19 -0800271
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700272static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
273 if (env->ExceptionCheck()) {
274 ALOGE("An exception was thrown by callback '%s'.", methodName);
275 LOGE_EX(env);
276 env->ExceptionClear();
277 }
278}
destradaaea8a8a62014-06-23 18:19:03 -0700279
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800280class ScopedJniThreadAttach {
281public:
282 ScopedJniThreadAttach() {
283 /*
284 * attachResult will also be JNI_OK if the thead was already attached to
285 * JNI before the call to AttachCurrentThread().
286 */
287 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
288 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
289 attachResult);
290 }
291
292 ~ScopedJniThreadAttach() {
293 jint detachResult = sJvm->DetachCurrentThread();
294 /*
295 * Return if the thread was already detached. Log error for any other
296 * failure.
297 */
298 if (detachResult == JNI_EDETACHED) {
299 return;
300 }
301
302 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
303 detachResult);
304 }
305
306 JNIEnv* getEnv() {
307 /*
308 * Checking validity of mEnv in case the thread was detached elsewhere.
309 */
310 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
311 return mEnv;
312 }
313
314private:
315 JNIEnv* mEnv = nullptr;
316};
317
318thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
319
320static JNIEnv* getJniEnv() {
321 JNIEnv* env = AndroidRuntime::getJNIEnv();
322
323 /*
324 * If env is nullptr, the thread is not already attached to
325 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
326 * will detach it on thread exit.
327 */
328 if (env == nullptr) {
329 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
330 env = tJniThreadAttacher->getEnv();
331 }
332
333 return env;
334}
335
Wyatt Rileyfb840922017-11-08 15:07:58 -0800336static jobject translateLocation(JNIEnv* env, const GnssLocation& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800337 JavaObject object(env, "android/location/Location", "gps");
338
339 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800340 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800341 SET(Latitude, location.latitudeDegrees);
342 SET(Longitude, location.longitudeDegrees);
343 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800344 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800345 SET(Altitude, location.altitudeMeters);
346 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800347 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800348 SET(Speed, location.speedMetersPerSec);
349 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800350 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800351 SET(Bearing, location.bearingDegrees);
352 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800353 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800354 SET(Accuracy, location.horizontalAccuracyMeters);
355 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800356 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800357 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
358 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800359 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800360 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
361 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800362 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800363 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
364 }
365 SET(Time, location.timestamp);
366
367 return object.get();
368}
369
Yu-Han Yange7baef32018-02-09 13:58:17 -0800370static GnssLocation createGnssLocation(
371 jint gnssLocationFlags,
372 jdouble latitudeDegrees,
373 jdouble longitudeDegrees,
374 jdouble altitudeMeters,
375 jfloat speedMetersPerSec,
376 jfloat bearingDegrees,
377 jfloat horizontalAccuracyMeters,
378 jfloat verticalAccuracyMeters,
379 jfloat speedAccuracyMetersPerSecond,
380 jfloat bearingAccuracyDegrees,
381 jlong timestamp) {
382 GnssLocation location;
383 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
384 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
385 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
386 location.altitudeMeters = static_cast<double>(altitudeMeters);
387 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
388 location.bearingDegrees = static_cast<float>(bearingDegrees);
389 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
390 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
391 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
392 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
393 location.timestamp = static_cast<uint64_t>(timestamp);
394
395 return location;
396}
397
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700398/*
399 * GnssCallback class implements the callback methods for IGnss interface.
400 */
401struct GnssCallback : public IGnssCallback {
Wyatt Rileyfb840922017-11-08 15:07:58 -0800402 Return<void> gnssLocationCb(const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
404 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
405 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
406 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
407 Return<void> gnssAcquireWakelockCb() override;
408 Return<void> gnssReleaseWakelockCb() override;
409 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800410 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700411 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800412
Wyatt Rileyfb840922017-11-08 15:07:58 -0800413 // New in 1.1
414 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
415
Wyatt Riley26465d22018-02-12 13:44:24 -0800416 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700417 static const char* sNmeaString;
418 static size_t sNmeaStringLength;
419};
420
Wyatt Rileyfb840922017-11-08 15:07:58 -0800421Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
422 ALOGD("%s: name=%s\n", __func__, name.c_str());
423
Wyatt Rileyfb840922017-11-08 15:07:58 -0800424 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800425 jstring jstringName = env->NewStringUTF(name.c_str());
426 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800427 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800428
Wyatt Rileyfb840922017-11-08 15:07:58 -0800429 return Void();
430}
431
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700432const char* GnssCallback::sNmeaString = nullptr;
433size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700434
Wyatt Rileyfb840922017-11-08 15:07:58 -0800435Return<void> GnssCallback::gnssLocationCb(const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800436 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800437
438 jobject jLocation = translateLocation(env, location);
439 bool hasLatLong = (static_cast<uint32_t>(location.gnssLocationFlags) &
Wyatt Rileyfb840922017-11-08 15:07:58 -0800440 GnssLocationFlags::HAS_LAT_LONG) != 0;
Wyatt Riley5d229832017-02-10 17:06:00 -0800441
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700442 env->CallVoidMethod(mCallbacksObj,
443 method_reportLocation,
Wyatt Riley5d229832017-02-10 17:06:00 -0800444 boolToJbool(hasLatLong),
445 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700446 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800447 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700448 return Void();
449}
450
451Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800452 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700453 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
454 checkAndClearExceptionFromCallback(env, __FUNCTION__);
455 return Void();
456}
457
458Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800459 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700460
Wyatt Riley26465d22018-02-12 13:44:24 -0800461 uint32_t listSize = svStatus.numSvs;
462 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700463 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800464 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700465 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800466 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800467 }
468
Wyatt Riley26465d22018-02-12 13:44:24 -0800469 jintArray svidWithFlagArray = env->NewIntArray(listSize);
470 jfloatArray cn0Array = env->NewFloatArray(listSize);
471 jfloatArray elevArray = env->NewFloatArray(listSize);
472 jfloatArray azimArray = env->NewFloatArray(listSize);
473 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
474
475 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
476 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
477 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
478 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
479 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
480
481 /*
482 * Read GNSS SV info.
483 */
484 for (size_t i = 0; i < listSize; ++i) {
485 enum ShiftWidth: uint8_t {
486 SVID_SHIFT_WIDTH = 8,
487 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
488 };
489
490 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
491 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
492 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
493 static_cast<uint32_t>(info.svFlag);
494 cn0s[i] = info.cN0Dbhz;
495 elev[i] = info.elevationDegrees;
496 azim[i] = info.azimuthDegrees;
497 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800498 }
destradaaea8a8a62014-06-23 18:19:03 -0700499
Wyatt Riley26465d22018-02-12 13:44:24 -0800500 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
501 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
502 env->ReleaseFloatArrayElements(elevArray, elev, 0);
503 env->ReleaseFloatArrayElements(azimArray, azim, 0);
504 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
505
506 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
507 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
508 carrierFreqArray);
509
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700510 checkAndClearExceptionFromCallback(env, __FUNCTION__);
511 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700512}
513
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700514Return<void> GnssCallback::gnssNmeaCb(
515 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800516 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700517 /*
518 * The Java code will call back to read these values.
519 * We do this to avoid creating unnecessary String objects.
520 */
521 sNmeaString = nmea.c_str();
522 sNmeaStringLength = nmea.size();
523
524 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
525 checkAndClearExceptionFromCallback(env, __FUNCTION__);
526 return Void();
527}
528
529Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
530 ALOGD("%s: %du\n", __func__, capabilities);
531
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800532 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700533 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
534 checkAndClearExceptionFromCallback(env, __FUNCTION__);
535 return Void();
536}
537
538Return<void> GnssCallback::gnssAcquireWakelockCb() {
539 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
540 return Void();
541}
542
543Return<void> GnssCallback::gnssReleaseWakelockCb() {
544 release_wake_lock(WAKE_LOCK_NAME);
545 return Void();
546}
547
548Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800549 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700550 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
551 checkAndClearExceptionFromCallback(env, __FUNCTION__);
552 return Void();
553}
554
Yu-Han Yang21988932018-01-23 15:07:37 -0800555Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800556 JNIEnv* env = getJniEnv();
557 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
558 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800559 return Void();
560}
561
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700562Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
563 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
564
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800565 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700566 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
567 info.yearOfHw);
568 checkAndClearExceptionFromCallback(env, __FUNCTION__);
569 return Void();
570}
571
572class GnssXtraCallback : public IGnssXtraCallback {
573 Return<void> downloadRequestCb() override;
574};
575
576/*
577 * GnssXtraCallback class implements the callback methods for the IGnssXtra
578 * interface.
579 */
580Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800581 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700582 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
583 checkAndClearExceptionFromCallback(env, __FUNCTION__);
584 return Void();
585}
586
587/*
588 * GnssGeofenceCallback class implements the callback methods for the
589 * IGnssGeofence interface.
590 */
591struct GnssGeofenceCallback : public IGnssGeofenceCallback {
592 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
593 Return<void> gnssGeofenceTransitionCb(
594 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800595 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700596 GeofenceTransition transition,
597 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
598 Return<void> gnssGeofenceStatusCb(
599 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800600 const GnssLocation& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700601 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
602 GeofenceStatus status) override;
603 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
604 GeofenceStatus status) override;
605 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
606 GeofenceStatus status) override;
607 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
608 GeofenceStatus status) override;
609};
610
611Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
612 int32_t geofenceId,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800613 const GnssLocation& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700614 GeofenceTransition transition,
615 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800616 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700617
Wyatt Riley5d229832017-02-10 17:06:00 -0800618 jobject jLocation = translateLocation(env, location);
619
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700620 env->CallVoidMethod(mCallbacksObj,
621 method_reportGeofenceTransition,
622 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800623 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700624 transition,
625 timestamp);
626
627 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800628 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700629 return Void();
630}
631
632Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
633 GeofenceAvailability status,
Wyatt Rileyfb840922017-11-08 15:07:58 -0800634 const GnssLocation& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800635 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800636
637 jobject jLocation = translateLocation(env, location);
638
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700639 env->CallVoidMethod(mCallbacksObj,
640 method_reportGeofenceStatus,
641 status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800642 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700643 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800644 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700645 return Void();
646}
647
648Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
649 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800650 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700651 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
652 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
653 }
654
655 env->CallVoidMethod(mCallbacksObj,
656 method_reportGeofenceAddStatus,
657 geofenceId,
658 status);
659 checkAndClearExceptionFromCallback(env, __FUNCTION__);
660 return Void();
661}
662
663Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
664 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800665 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700666 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
667 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
668 }
669
670 env->CallVoidMethod(mCallbacksObj,
671 method_reportGeofenceRemoveStatus,
672 geofenceId, status);
673 checkAndClearExceptionFromCallback(env, __FUNCTION__);
674 return Void();
675}
676
677Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
678 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800679 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700680 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
681 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
682 }
683
684 env->CallVoidMethod(mCallbacksObj,
685 method_reportGeofencePauseStatus,
686 geofenceId, status);
687 checkAndClearExceptionFromCallback(env, __FUNCTION__);
688 return Void();
689}
690
691Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
692 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800693 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700694 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
695 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
696 }
697
698 env->CallVoidMethod(mCallbacksObj,
699 method_reportGeofenceResumeStatus,
700 geofenceId, status);
701 checkAndClearExceptionFromCallback(env, __FUNCTION__);
702 return Void();
703}
704
705/*
706 * GnssNavigationMessageCallback interface implements the callback methods
707 * required by the IGnssNavigationMessage interface.
708 */
709struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
710 /*
711 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
712 * follow.
713 */
714 Return<void> gnssNavigationMessageCb(
715 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
716};
717
718Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
719 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800720 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700721
722 size_t dataLength = message.data.size();
723
724 std::vector<uint8_t> navigationData = message.data;
725 uint8_t* data = &(navigationData[0]);
WyattRiley840c0b22018-10-31 09:03:53 -0700726 if (dataLength == 0 || data == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700727 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
728 dataLength);
729 return Void();
730 }
731
732 JavaObject object(env, "android/location/GnssNavigationMessage");
733 SET(Type, static_cast<int32_t>(message.type));
734 SET(Svid, static_cast<int32_t>(message.svid));
735 SET(MessageId, static_cast<int32_t>(message.messageId));
736 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
737 object.callSetter("setData", data, dataLength);
738 SET(Status, static_cast<int32_t>(message.status));
739
740 jobject navigationMessage = object.get();
741 env->CallVoidMethod(mCallbacksObj,
742 method_reportNavigationMessages,
743 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800744 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700745 env->DeleteLocalRef(navigationMessage);
746 return Void();
747}
748
749/*
750 * GnssMeasurementCallback implements the callback methods required for the
751 * GnssMeasurement interface.
752 */
Yu-Han Yang88d79102018-11-14 14:20:57 -0800753struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 {
754 Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData& data)
755 override;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800756 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800757 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700758 private:
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800759 void translateGnssMeasurement_V1_0(
WyattRiley840c0b22018-10-31 09:03:53 -0700760 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800761 JavaObject& object);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700762 jobjectArray translateGnssMeasurements(
763 JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800764 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800765 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700766 size_t count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800767 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800768 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700769 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
770};
771
Yu-Han Yang88d79102018-11-14 14:20:57 -0800772Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_0(
773 const IGnssMeasurementCallback_V2_0::GnssData& data) {
774 // TODO(b/119571122): implement gnssMeasurementCb_2_0
775 return Void();
776}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700777
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800778Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800779 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800780 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700781
782 jobject clock;
783 jobjectArray measurementArray;
784
785 clock = translateGnssClock(env, &data.clock);
Wyatt Riley46ac9562018-03-02 20:16:58 -0800786
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700787 measurementArray = translateGnssMeasurements(
WyattRiley840c0b22018-10-31 09:03:53 -0700788 env, data.measurements.data(), nullptr, data.measurements.size());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700789 setMeasurementData(env, clock, measurementArray);
790
791 env->DeleteLocalRef(clock);
792 env->DeleteLocalRef(measurementArray);
793 return Void();
794}
795
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800796Return<void> GnssMeasurementCallback::GnssMeasurementCb(
797 const IGnssMeasurementCallback_V1_0::GnssData& data) {
798 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800799
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800800 jobject clock;
801 jobjectArray measurementArray;
802
803 clock = translateGnssClock(env, &data.clock);
804 measurementArray = translateGnssMeasurements(
WyattRiley840c0b22018-10-31 09:03:53 -0700805 env, nullptr, data.measurements.data(), data.measurementCount);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800806 setMeasurementData(env, clock, measurementArray);
807
808 env->DeleteLocalRef(clock);
809 env->DeleteLocalRef(measurementArray);
810 return Void();
811}
812
813// preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
814void GnssMeasurementCallback::translateGnssMeasurement_V1_0(
WyattRiley840c0b22018-10-31 09:03:53 -0700815 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800816 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700817 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700818
819 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800820 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700821 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800822 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700823 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800824 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700825 measurement->receivedSvTimeUncertaintyInNs);
826 SET(Cn0DbHz, measurement->cN0DbHz);
827 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800828 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700829 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800830 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800831 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
WyattRiley948dd6d2018-10-31 06:56:09 -0700832 ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700833 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -0800834 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700835 measurement->accumulatedDeltaRangeUncertaintyM);
836
837 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
838 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
839 }
840
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800841 // Intentionally not copying deprecated fields of carrierCycles,
842 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700843
844 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
845
846 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
847 SET(SnrInDb, measurement->snrDb);
848 }
Lifu Tang120480f2016-02-07 18:08:19 -0800849
gomo4402af62017-01-11 13:20:13 -0800850 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -0800851 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -0800852 }
Lifu Tang120480f2016-02-07 18:08:19 -0800853}
854
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700855jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800856 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700857 JavaObject object(env, "android/location/GnssClock");
858
859 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
860 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
861 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
862 }
863
864 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
865 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
866 }
867
868 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
869 SET(FullBiasNanos, clock->fullBiasNs);
870 }
871
872 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
873 SET(BiasNanos, clock->biasNs);
874 }
875
876 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
877 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
878 }
879
880 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
881 SET(DriftNanosPerSecond, clock->driftNsps);
882 }
883
884 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
885 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
886 }
887
888 SET(TimeNanos, clock->timeNs);
889 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
890
891 return object.get();
892}
893
894jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800895 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurements_v1_1,
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800896 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurements_v1_0,
897 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -0800898 if (count == 0) {
WyattRiley840c0b22018-10-31 09:03:53 -0700899 return nullptr;
destradaaea8a8a62014-06-23 18:19:03 -0700900 }
901
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700902 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -0800903 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -0800904 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -0800905 gnssMeasurementClass,
WyattRiley840c0b22018-10-31 09:03:53 -0700906 nullptr /* initialElement */);
destradaaea8a8a62014-06-23 18:19:03 -0700907
Lifu Tang120480f2016-02-07 18:08:19 -0800908 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800909 JavaObject object(env, "android/location/GnssMeasurement");
WyattRiley840c0b22018-10-31 09:03:53 -0700910 if (measurements_v1_1 != nullptr) {
911 translateGnssMeasurement_V1_0(&(measurements_v1_1[i].v1_0), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800912
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800913 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800914 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800915 (static_cast<int32_t>(measurements_v1_1[i].accumulatedDeltaRangeState) |
916 ADR_STATE_HALF_CYCLE_REPORTED));
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800917 } else {
WyattRiley840c0b22018-10-31 09:03:53 -0700918 translateGnssMeasurement_V1_0(&(measurements_v1_0[i]), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800919 }
920
921 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -0700922 }
923
Lifu Tang818aa2c2016-02-01 01:52:00 -0800924 env->DeleteLocalRef(gnssMeasurementClass);
925 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -0700926}
927
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700928void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
929 jobjectArray measurementArray) {
930 jclass gnssMeasurementsEventClass =
931 env->FindClass("android/location/GnssMeasurementsEvent");
932 jmethodID gnssMeasurementsEventCtor =
933 env->GetMethodID(
934 gnssMeasurementsEventClass,
935 "<init>",
936 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -0800937
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700938 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
939 gnssMeasurementsEventCtor,
940 clock,
941 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -0800942
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
944 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -0800945 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -0800946 env->DeleteLocalRef(gnssMeasurementsEventClass);
947 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -0700948}
949
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700950/*
951 * GnssNiCallback implements callback methods required by the IGnssNi interface.
952 */
953struct GnssNiCallback : public IGnssNiCallback {
954 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
955 override;
destradaaea8a8a62014-06-23 18:19:03 -0700956};
957
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700958Return<void> GnssNiCallback::niNotifyCb(
959 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800960 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700961 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
962 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
963
964 if (requestorId && text) {
965 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
966 notification.notificationId, notification.niType,
967 notification.notifyFlags, notification.timeoutSec,
968 notification.defaultResponse, requestorId, text,
969 notification.requestorIdEncoding,
970 notification.notificationIdEncoding);
971 } else {
972 ALOGE("%s: OOM Error\n", __func__);
973 }
974
975 if (requestorId) {
976 env->DeleteLocalRef(requestorId);
977 }
978
979 if (text) {
980 env->DeleteLocalRef(text);
981 }
982 checkAndClearExceptionFromCallback(env, __FUNCTION__);
983 return Void();
984}
985
986/*
987 * AGnssCallback implements callback methods required by the IAGnss interface.
988 */
989struct AGnssCallback : public IAGnssCallback {
990 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
991 Return<void> agnssStatusIpV6Cb(
992 const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
993
994 Return<void> agnssStatusIpV4Cb(
995 const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
996 private:
997 jbyteArray convertToIpV4(uint32_t ip);
998};
999
1000Return<void> AGnssCallback::agnssStatusIpV6Cb(
1001 const IAGnssCallback::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001002 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001003 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001004
1005 byteArray = env->NewByteArray(16);
WyattRiley840c0b22018-10-31 09:03:53 -07001006 if (byteArray != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001007 env->SetByteArrayRegion(byteArray, 0, 16,
1008 (const jbyte*)(agps_status.ipV6Addr.data()));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001009 } else {
1010 ALOGE("Unable to allocate byte array for IPv6 address.");
1011 }
1012
1013 IF_ALOGD() {
1014 // log the IP for reference in case there is a bogus value pushed by HAL
1015 char str[INET6_ADDRSTRLEN];
1016 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1017 ALOGD("AGPS IP is v6: %s", str);
1018 }
1019
WyattRiley840c0b22018-10-31 09:03:53 -07001020 jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001021 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1022 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1023 agps_status.type, agps_status.status, byteArray);
1024
1025 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1026
1027 if (byteArray) {
1028 env->DeleteLocalRef(byteArray);
1029 }
1030
1031 return Void();
1032}
1033
1034Return<void> AGnssCallback::agnssStatusIpV4Cb(
1035 const IAGnssCallback::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001036 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001037 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001038
1039 uint32_t ipAddr = agps_status.ipV4Addr;
1040 byteArray = convertToIpV4(ipAddr);
1041
1042 IF_ALOGD() {
1043 /*
1044 * log the IP for reference in case there is a bogus value pushed by
1045 * HAL.
1046 */
1047 char str[INET_ADDRSTRLEN];
1048 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1049 ALOGD("AGPS IP is v4: %s", str);
1050 }
1051
1052 jsize byteArrayLength =
WyattRiley840c0b22018-10-31 09:03:53 -07001053 byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001054 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1055 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1056 agps_status.type, agps_status.status, byteArray);
1057
1058 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1059
1060 if (byteArray) {
1061 env->DeleteLocalRef(byteArray);
1062 }
1063 return Void();
1064}
1065
1066jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
1067 if (INADDR_NONE == ip) {
WyattRiley840c0b22018-10-31 09:03:53 -07001068 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001069 }
1070
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001071 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001072 jbyteArray byteArray = env->NewByteArray(4);
WyattRiley840c0b22018-10-31 09:03:53 -07001073 if (byteArray == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 ALOGE("Unable to allocate byte array for IPv4 address");
WyattRiley840c0b22018-10-31 09:03:53 -07001075 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001076 }
1077
1078 jbyte ipv4[4];
1079 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1080 memcpy(ipv4, &ip, sizeof(ipv4));
1081 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1082 return byteArray;
1083}
1084
1085/*
1086 * AGnssRilCallback implements the callback methods required by the AGnssRil
1087 * interface.
1088 */
1089struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001090 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001091 Return<void> requestRefLocCb() override;
1092};
1093
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001094Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001095 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001096 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1097 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1098 return Void();
1099}
1100
1101Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001102 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001103 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1104 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1105 return Void();
1106}
1107
Wyatt Rileycf879db2017-01-12 13:57:38 -08001108/*
1109 * GnssBatchingCallback interface implements the callback methods
1110 * required by the IGnssBatching interface.
1111 */
1112struct GnssBatchingCallback : public IGnssBatchingCallback {
1113 /*
1114 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1115 * follow.
1116 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001117 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001118 override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001119};
1120
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07001121Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001122 JNIEnv* env = getJniEnv();
1123
1124 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1125 env->FindClass("android/location/Location"), nullptr);
1126
1127 for (uint16_t i = 0; i < locations.size(); ++i) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001128 jobject jLocation = translateLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001129 env->SetObjectArrayElement(jLocations, i, jLocation);
1130 env->DeleteLocalRef(jLocation);
1131 }
1132
1133 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1134 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1135
1136 env->DeleteLocalRef(jLocations);
1137
1138 return Void();
1139}
1140
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001141static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001142 gnssHal_V2_0 = IGnss_V2_0::getService();
1143 if (gnssHal_V2_0 != nullptr) {
1144 gnssHal = gnssHal_V2_0;
1145 gnssHal_V1_1 = gnssHal_V2_0;
1146 return;
Yu-Han Yang6d317352018-03-15 11:53:01 -07001147 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001148
1149 ALOGD("gnssHal 2.0 was null, trying 1.1");
1150 gnssHal_V1_1 = IGnss_V1_1::getService();
1151 if (gnssHal_V1_1 != nullptr) {
1152 gnssHal = gnssHal_V1_1;
1153 return;
1154 }
1155
1156 ALOGD("gnssHal 1.1 was null, trying 1.0");
1157 gnssHal = IGnss_V1_0::getService();
Yu-Han Yang6d317352018-03-15 11:53:01 -07001158}
1159
1160static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001161 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1162 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001163 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001164 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001165 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1166 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1167 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1168 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001169 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1170 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001171 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1172 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1173 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001174 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001175 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1176 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1177 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1178 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001179 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001180 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001181 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001182 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1183 "(II)V");
1184 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1185 "(II)V");
1186 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1187 "(II)V");
1188 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1189 "(II)V");
1190 method_reportMeasurementData = env->GetMethodID(
1191 clazz,
1192 "reportMeasurementData",
1193 "(Landroid/location/GnssMeasurementsEvent;)V");
1194 method_reportNavigationMessages = env->GetMethodID(
1195 clazz,
1196 "reportNavigationMessage",
1197 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001198 method_reportLocationBatch = env->GetMethodID(
1199 clazz,
1200 "reportLocationBatch",
1201 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001202 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001203
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001204 /*
1205 * Save a pointer to JVM.
1206 */
1207 jint jvmStatus = env->GetJavaVM(&sJvm);
1208 if (jvmStatus != JNI_OK) {
1209 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1210 }
1211
Yu-Han Yang88d79102018-11-14 14:20:57 -08001212 if (gnssHal == nullptr) {
1213 ALOGE("Unable to get GPS service\n");
1214 return;
1215 }
gomo25208882017-04-15 02:05:25 -07001216
Yu-Han Yang88d79102018-11-14 14:20:57 -08001217 gnssHalDeathRecipient = new GnssDeathRecipient();
1218 hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
1219 if (!linked.isOk()) {
1220 ALOGE("Transaction error in linking to GnssHAL death: %s",
1221 linked.description().c_str());
1222 } else if (!linked) {
1223 ALOGW("Unable to link to GnssHal death notifications");
1224 } else {
1225 ALOGD("Link to death notification successful");
1226 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001227
Yu-Han Yang88d79102018-11-14 14:20:57 -08001228 auto gnssXtra = gnssHal->getExtensionXtra();
1229 if (!gnssXtra.isOk()) {
1230 ALOGD("Unable to get a handle to Xtra");
1231 } else {
1232 gnssXtraIface = gnssXtra;
1233 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001234
Yu-Han Yang88d79102018-11-14 14:20:57 -08001235 auto gnssRil = gnssHal->getExtensionAGnssRil();
1236 if (!gnssRil.isOk()) {
1237 ALOGD("Unable to get a handle to AGnssRil");
1238 } else {
1239 agnssRilIface = gnssRil;
1240 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001241
Yu-Han Yang88d79102018-11-14 14:20:57 -08001242 auto gnssAgnss = gnssHal->getExtensionAGnss();
1243 if (!gnssAgnss.isOk()) {
1244 ALOGD("Unable to get a handle to AGnss");
1245 } else {
1246 agnssIface = gnssAgnss;
1247 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001248
Yu-Han Yang88d79102018-11-14 14:20:57 -08001249 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1250 if (!gnssNavigationMessage.isOk()) {
1251 ALOGD("Unable to get a handle to GnssNavigationMessage");
1252 } else {
1253 gnssNavigationMessageIface = gnssNavigationMessage;
1254 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001255
Yu-Han Yang88d79102018-11-14 14:20:57 -08001256 if (gnssHal_V2_0 != nullptr) {
1257 // TODO(b/119638366): getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
1258 auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
1259 if (!gnssMeasurement.isOk()) {
1260 ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001261 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001262 gnssMeasurementIface_V2_0 = gnssMeasurement;
1263 gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
1264 gnssMeasurementIface = gnssMeasurementIface_V2_0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001265 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001266 } else if (gnssHal_V1_1 != nullptr) {
1267 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1268 if (!gnssMeasurement.isOk()) {
1269 ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
1270 } else {
1271 gnssMeasurementIface_V1_1 = gnssMeasurement;
1272 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1273 }
1274 } else {
1275 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1276 if (!gnssMeasurement_V1_0.isOk()) {
1277 ALOGD("Unable to get a handle to GnssMeasurement");
1278 } else {
1279 gnssMeasurementIface = gnssMeasurement_V1_0;
1280 }
1281 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001282
Yu-Han Yang88d79102018-11-14 14:20:57 -08001283 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1284 if (!gnssDebug.isOk()) {
1285 ALOGD("Unable to get a handle to GnssDebug");
1286 } else {
1287 gnssDebugIface = gnssDebug;
1288 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001289
Yu-Han Yang88d79102018-11-14 14:20:57 -08001290 auto gnssNi = gnssHal->getExtensionGnssNi();
1291 if (!gnssNi.isOk()) {
1292 ALOGD("Unable to get a handle to GnssNi");
1293 } else {
1294 gnssNiIface = gnssNi;
1295 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001296
Yu-Han Yang88d79102018-11-14 14:20:57 -08001297 if (gnssHal_V1_1 != nullptr) {
1298 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1299 if (!gnssConfiguration.isOk()) {
1300 ALOGD("Unable to get a handle to GnssConfiguration");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001301 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001302 gnssConfigurationIface_V1_1 = gnssConfiguration;
1303 gnssConfigurationIface = gnssConfigurationIface_V1_1;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001304 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001305 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001306 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1307 if (!gnssConfiguration_V1_0.isOk()) {
1308 ALOGD("Unable to get a handle to GnssConfiguration");
1309 } else {
1310 gnssConfigurationIface = gnssConfiguration_V1_0;
1311 }
1312 }
1313
1314 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1315 if (!gnssGeofencing.isOk()) {
1316 ALOGD("Unable to get a handle to GnssGeofencing");
1317 } else {
1318 gnssGeofencingIface = gnssGeofencing;
1319 }
1320
1321 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1322 if (!gnssBatching.isOk()) {
1323 ALOGD("Unable to get a handle to gnssBatching");
1324 } else {
1325 gnssBatchingIface = gnssBatching;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001326 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001327}
1328
1329static jboolean android_location_GnssLocationProvider_is_supported(
1330 JNIEnv* /* env */, jclass /* clazz */) {
1331 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1332}
1333
Anil Admal50ba15e2018-11-01 16:42:42 -07001334static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001335 JNIEnv* /* env */, jclass /* clazz */) {
1336 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1337}
1338
1339static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
1340 JNIEnv* /* env */, jclass /* jclazz */) {
1341 return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1342}
1343
1344static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1345 /*
1346 * This must be set before calling into the HAL library.
1347 */
1348 if (!mCallbacksObj)
1349 mCallbacksObj = env->NewGlobalRef(obj);
1350
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001351 /*
1352 * Fail if the main interface fails to initialize
1353 */
1354 if (gnssHal == nullptr) {
1355 ALOGE("Unable to Initialize GNSS HAL\n");
1356 return JNI_FALSE;
1357 }
1358
Wyatt Rileyfb840922017-11-08 15:07:58 -08001359 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1360
1361 Return<bool> result = false;
gomo48f1a642017-11-10 20:35:46 -08001362 if (gnssHal_V1_1 != nullptr) {
1363 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001364 } else {
1365 result = gnssHal->setCallback(gnssCbIface);
1366 }
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001367 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001368 ALOGE("SetCallback for Gnss Interface fails\n");
1369 return JNI_FALSE;
1370 }
1371
1372 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1373 if (gnssXtraIface == nullptr) {
WyattRileybc5a8b02018-10-31 13:06:34 -07001374 ALOGI("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001375 } else {
1376 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001377 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001378 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001379 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001380 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001381 }
1382
1383 sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
1384 if (agnssIface != nullptr) {
1385 agnssIface->setCallback(aGnssCbIface);
1386 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001387 ALOGI("Unable to Initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001388 }
1389
1390 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1391 if (gnssGeofencingIface != nullptr) {
1392 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1393 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001394 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001395 }
1396
1397 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001398 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001399 gnssNiIface->setCallback(gnssNiCbIface);
1400 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001401 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001402 }
1403
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001404 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1405 if (agnssRilIface != nullptr) {
1406 agnssRilIface->setCallback(aGnssRilCbIface);
1407 } else {
1408 ALOGI("Unable to Initialize AGnss Ril interface\n");
1409 }
1410
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001411 return JNI_TRUE;
1412}
1413
1414static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1415 if (gnssHal != nullptr) {
1416 gnssHal->cleanup();
1417 }
1418}
1419
1420static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1421 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001422 jint preferred_time, jboolean low_power_mode) {
1423 Return<bool> result = false;
1424 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001425 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1426 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1427 min_interval,
1428 preferred_accuracy,
1429 preferred_time,
1430 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001431 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001432 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1433 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1434 min_interval,
1435 preferred_accuracy,
1436 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001437 }
1438 if (!result.isOk()) {
1439 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1440 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001441 } else {
gomo48f1a642017-11-10 20:35:46 -08001442 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001443 }
1444}
1445
1446static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1447 if (gnssHal != nullptr) {
1448 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001449 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001450 return JNI_FALSE;
1451 } else {
1452 return result;
1453 }
1454 } else {
1455 return JNI_FALSE;
1456 }
1457}
1458
1459static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1460 if (gnssHal != nullptr) {
1461 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001462 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001463 return JNI_FALSE;
1464 } else {
1465 return result;
1466 }
1467 } else {
1468 return JNI_FALSE;
1469 }
1470}
1471static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1472 jobject /* obj */,
1473 jint flags) {
1474 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001475 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001476 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001477 ALOGE("Error in deleting aiding data");
1478 }
1479 }
1480}
1481
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001482static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1483 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
1484 IAGnssRil::AGnssRefLocation location;
1485
1486 if (agnssRilIface == nullptr) {
1487 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1488 return;
1489 }
1490
1491 switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
1492 case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
1493 case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
1494 location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
1495 location.cellID.mcc = mcc;
1496 location.cellID.mnc = mnc;
1497 location.cellID.lac = lac;
1498 location.cellID.cid = cid;
1499 break;
1500 default:
1501 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1502 return;
1503 break;
1504 }
1505
1506 agnssRilIface->setRefLocation(location);
1507}
1508
1509static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
1510 jint type, jstring setid_string) {
1511 if (agnssRilIface == nullptr) {
1512 ALOGE("no AGPS RIL interface in agps_set_id");
1513 return;
1514 }
1515
WyattRiley840c0b22018-10-31 09:03:53 -07001516 const char *setid = env->GetStringUTFChars(setid_string, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001517 agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
1518 env->ReleaseStringUTFChars(setid_string, setid);
1519}
1520
1521static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1522 jbyteArray nmeaArray, jint buffer_size) {
1523 // this should only be called from within a call to reportNmea
1524 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1525 int length = GnssCallback::sNmeaStringLength;
1526 if (length > buffer_size)
1527 length = buffer_size;
1528 memcpy(nmea, GnssCallback::sNmeaString, length);
1529 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1530 return (jint) length;
1531}
1532
1533static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1534 jlong time, jlong timeReference, jint uncertainty) {
1535 if (gnssHal != nullptr) {
1536 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001537 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001538 ALOGE("%s: Gnss injectTime() failed", __func__);
1539 }
1540 }
1541}
1542
Yu-Han Yange7baef32018-02-09 13:58:17 -08001543static void android_location_GnssLocationProvider_inject_best_location(
1544 JNIEnv*,
1545 jobject,
1546 jint gnssLocationFlags,
1547 jdouble latitudeDegrees,
1548 jdouble longitudeDegrees,
1549 jdouble altitudeMeters,
1550 jfloat speedMetersPerSec,
1551 jfloat bearingDegrees,
1552 jfloat horizontalAccuracyMeters,
1553 jfloat verticalAccuracyMeters,
1554 jfloat speedAccuracyMetersPerSecond,
1555 jfloat bearingAccuracyDegrees,
1556 jlong timestamp) {
1557 if (gnssHal_V1_1 != nullptr) {
1558 GnssLocation location = createGnssLocation(
1559 gnssLocationFlags,
1560 latitudeDegrees,
1561 longitudeDegrees,
1562 altitudeMeters,
1563 speedMetersPerSec,
1564 bearingDegrees,
1565 horizontalAccuracyMeters,
1566 verticalAccuracyMeters,
1567 speedAccuracyMetersPerSecond,
1568 bearingAccuracyDegrees,
1569 timestamp);
1570 auto result = gnssHal_V1_1->injectBestLocation(location);
1571 if (!result.isOk() || !result) {
1572 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1573 }
1574 } else {
1575 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
1576 }
1577}
1578
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001579static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1580 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1581 if (gnssHal != nullptr) {
1582 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001583 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001584 ALOGE("%s: Gnss injectLocation() failed", __func__);
1585 }
1586 }
1587}
1588
1589static jboolean android_location_GnssLocationProvider_supports_xtra(
1590 JNIEnv* /* env */, jobject /* obj */) {
1591 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1592}
1593
1594static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1595 jbyteArray data, jint length) {
1596 if (gnssXtraIface == nullptr) {
1597 ALOGE("XTRA Interface not supported");
1598 return;
1599 }
1600
1601 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1602 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1603 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1604}
1605
Anil Admal50ba15e2018-11-01 16:42:42 -07001606static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001607 JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
1608 if (agnssIface == nullptr) {
1609 ALOGE("no AGPS interface in agps_data_conn_open");
1610 return;
1611 }
WyattRiley840c0b22018-10-31 09:03:53 -07001612 if (apn == nullptr) {
1613 jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614 return;
1615 }
1616
WyattRiley840c0b22018-10-31 09:03:53 -07001617 const char *apnStr = env->GetStringUTFChars(apn, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001618
1619 auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001620 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001621 ALOGE("%s: Failed to set APN and its IP type", __func__);
1622 }
1623 env->ReleaseStringUTFChars(apn, apnStr);
1624}
1625
Anil Admal50ba15e2018-11-01 16:42:42 -07001626static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001627 jobject /* obj */) {
1628 if (agnssIface == nullptr) {
1629 ALOGE("%s: AGPS interface not supported", __func__);
1630 return;
1631 }
1632
1633 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001634 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001635 ALOGE("%s: Failed to close AGnss data connection", __func__);
1636 }
1637}
1638
Anil Admal50ba15e2018-11-01 16:42:42 -07001639static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001640 jobject /* obj */) {
1641 if (agnssIface == nullptr) {
1642 ALOGE("%s: AGPS interface not supported", __func__);
1643 return;
1644 }
1645
1646 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001647 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001648 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
1649 }
1650}
1651
1652static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
1653 jint type, jstring hostname, jint port) {
1654 if (agnssIface == nullptr) {
1655 ALOGE("no AGPS interface in set_agps_server");
1656 return;
1657 }
1658
WyattRiley840c0b22018-10-31 09:03:53 -07001659 const char *c_hostname = env->GetStringUTFChars(hostname, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001660 auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
1661 c_hostname,
1662 port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001663 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001664 ALOGE("%s: Failed to set AGnss host name and port", __func__);
1665 }
1666
1667 env->ReleaseStringUTFChars(hostname, c_hostname);
1668}
1669
1670static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
1671 jobject /* obj */, jint notifId, jint response) {
1672 if (gnssNiIface == nullptr) {
1673 ALOGE("no NI interface in send_ni_response");
1674 return;
1675 }
1676
1677 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
1678}
1679
1680static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
1681 jobject /* obj */) {
WyattRiley840c0b22018-10-31 09:03:53 -07001682 jstring result = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001683 /*
1684 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
1685 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07001686
1687 std::stringstream internalState;
1688
1689 if (gnssDebugIface == nullptr) {
1690 internalState << "Gnss Debug Interface not available" << std::endl;
1691 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001692 IGnssDebug::DebugData data;
1693 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
1694 data = debugData;
1695 });
1696
Wyatt Riley268c6e02017-03-29 10:21:46 -07001697 internalState << "Gnss Location Data:: ";
1698 if (!data.position.valid) {
1699 internalState << "not valid";
1700 } else {
1701 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001702 << ", LongitudeDegrees: " << data.position.longitudeDegrees
1703 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08001704 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
1705 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001706 << ", horizontalAccuracyMeters: "
1707 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08001708 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07001709 << ", speedAccuracyMetersPerSecond: "
1710 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08001711 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07001712 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001713 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001714 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001715
Wyatt Riley268c6e02017-03-29 10:21:46 -07001716 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
1717 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
1718 << ", frequencyUncertaintyNsPerSec: "
1719 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001720
1721 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07001722 internalState << "Satellite Data for " << data.satelliteDataArray.size()
1723 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001724 }
1725
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001726 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
1727 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
1728 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
1729 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001730 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001731 internalState << "constell: "
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001732 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001733 << ", svid: " << std::setw(3) << data.satelliteDataArray[i].svid
1734 << ", serverPredAvail: "
Wyatt Riley268c6e02017-03-29 10:21:46 -07001735 << data.satelliteDataArray[i].serverPredictionIsAvailable
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001736 << ", serverPredAgeSec: " << std::setw(7)
Wyatt Riley268c6e02017-03-29 10:21:46 -07001737 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07001738 << ", ephType: "
1739 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
1740 << ", ephSource: "
1741 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
1742 << ", ephHealth: "
1743 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
1744 << ", ephAgeSec: " << std::setw(7)
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001745 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
1746 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001747 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07001748
1749 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 return result;
1751}
1752
Anil Admal50ba15e2018-11-01 16:42:42 -07001753static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001754 jobject /* obj */,
1755 jboolean connected,
1756 jint type,
1757 jboolean roaming,
1758 jboolean available,
1759 jstring extraInfo,
1760 jstring apn) {
1761 if (agnssRilIface != nullptr) {
1762 auto result = agnssRilIface->updateNetworkState(connected,
1763 static_cast<IAGnssRil::NetworkType>(type),
1764 roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001765 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 ALOGE("updateNetworkState failed");
1767 }
1768
WyattRiley840c0b22018-10-31 09:03:53 -07001769 const char *c_apn = env->GetStringUTFChars(apn, nullptr);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001770 result = agnssRilIface->updateNetworkAvailability(available, c_apn);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001771 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001772 ALOGE("updateNetworkAvailability failed");
1773 }
1774
1775 env->ReleaseStringUTFChars(apn, c_apn);
1776 } else {
1777 ALOGE("AGnssRilInterface does not exist");
1778 }
1779}
1780
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001781static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001782 JNIEnv* /* env */, jobject /* obj */) {
1783 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1784}
1785
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001786static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001787 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
1788 jint last_transition, jint monitor_transition, jint notification_responsiveness,
1789 jint unknown_timer) {
1790 if (gnssGeofencingIface != nullptr) {
1791 auto result = gnssGeofencingIface->addGeofence(
1792 geofenceId, latitude, longitude, radius,
1793 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
1794 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001795 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001796 } else {
1797 ALOGE("Geofence Interface not available");
1798 }
1799 return JNI_FALSE;
1800}
1801
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001802static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 jobject /* obj */, jint geofenceId) {
1804 if (gnssGeofencingIface != nullptr) {
1805 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001806 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001807 } else {
1808 ALOGE("Geofence interface not available");
1809 }
1810 return JNI_FALSE;
1811}
1812
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001813static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001814 jobject /* obj */, jint geofenceId) {
1815 if (gnssGeofencingIface != nullptr) {
1816 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001817 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001818 } else {
1819 ALOGE("Geofence interface not available");
1820 }
1821 return JNI_FALSE;
1822}
1823
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001824static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001825 jobject /* obj */, jint geofenceId, jint monitor_transition) {
1826 if (gnssGeofencingIface != nullptr) {
1827 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001828 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001829 } else {
1830 ALOGE("Geofence interface not available");
1831 }
1832 return JNI_FALSE;
1833}
1834
Yu-Han Yang8de21502018-04-23 01:40:25 -07001835static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001836 JNIEnv* env, jclass clazz) {
1837 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001838 return JNI_TRUE;
1839 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001840
destradaaea8a8a62014-06-23 18:19:03 -07001841 return JNI_FALSE;
1842}
1843
Yu-Han Yang8de21502018-04-23 01:40:25 -07001844static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08001845 JNIEnv* /* env */,
1846 jobject /* obj */,
1847 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001848 if (gnssMeasurementIface == nullptr) {
1849 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07001850 return JNI_FALSE;
1851 }
1852
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001853 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08001854 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
Yu-Han Yang88d79102018-11-14 14:20:57 -08001855 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
1856 if (gnssMeasurementIface_V2_0 != nullptr) {
1857 result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
1858 } else if (gnssMeasurementIface_V1_1 != nullptr) {
1859 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
gomo48f1a642017-11-10 20:35:46 -08001860 } else {
1861 if (enableFullTracking == JNI_TRUE) {
1862 // full tracking mode not supported in 1.0 HAL
1863 return JNI_FALSE;
1864 }
1865 result = gnssMeasurementIface->setCallback(cbIface);
1866 }
1867
1868 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001869 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
1870 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07001871 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001872 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001873 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07001874 }
1875
1876 return JNI_TRUE;
1877}
1878
Yu-Han Yang8de21502018-04-23 01:40:25 -07001879static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07001880 JNIEnv* env,
1881 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001882 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07001883 ALOGE("Measurement interface not available");
1884 return JNI_FALSE;
1885 }
1886
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001887 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001888 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07001889}
1890
Yu-Han Yang23d92162018-04-19 06:03:00 -07001891static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07001892 JNIEnv* env,
1893 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001894 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001895 return JNI_TRUE;
1896 }
1897 return JNI_FALSE;
1898}
1899
Yu-Han Yang23d92162018-04-19 06:03:00 -07001900static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001901 JNIEnv* env,
1902 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001903 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001904 ALOGE("Navigation Message interface is not available.");
1905 return JNI_FALSE;
1906 }
1907
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001908 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
1909 new GnssNavigationMessageCallback();
1910 IGnssNavigationMessage::GnssNavigationMessageStatus result =
1911 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
1912
1913 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
1914 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07001915 return JNI_FALSE;
1916 }
1917
1918 return JNI_TRUE;
1919}
1920
Yu-Han Yang23d92162018-04-19 06:03:00 -07001921static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07001922 JNIEnv* env,
1923 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001924 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07001925 ALOGE("Navigation Message interface is not available.");
1926 return JNI_FALSE;
1927 }
1928
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001929 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001930 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07001931}
1932
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001933static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
1934 jobject,
1935 jint emergencySuplPdn) {
1936 if (gnssConfigurationIface == nullptr) {
1937 ALOGE("no GNSS configuration interface available");
1938 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001939 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001940
1941 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001942 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001943 return result;
1944 } else {
1945 return JNI_FALSE;
1946 }
1947}
1948
1949static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
1950 jobject,
1951 jint version) {
1952 if (gnssConfigurationIface == nullptr) {
1953 ALOGE("no GNSS configuration interface available");
1954 return JNI_FALSE;
1955 }
1956 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001957 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001958 return result;
1959 } else {
1960 return JNI_FALSE;
1961 }
1962}
1963
1964static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
1965 jobject,
1966 jint suplEs) {
1967 if (gnssConfigurationIface == nullptr) {
1968 ALOGE("no GNSS configuration interface available");
1969 return JNI_FALSE;
1970 }
1971
1972 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001973 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001974 return result;
1975 } else {
1976 return JNI_FALSE;
1977 }
1978}
1979
1980static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
1981 jobject,
1982 jint mode) {
1983 if (gnssConfigurationIface == nullptr) {
1984 ALOGE("no GNSS configuration interface available");
1985 return JNI_FALSE;
1986 }
1987
1988 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08001989 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001990 return result;
1991 } else {
1992 return JNI_FALSE;
1993 }
1994}
1995
1996static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
1997 jobject,
1998 jint gpsLock) {
1999 if (gnssConfigurationIface == nullptr) {
2000 ALOGE("no GNSS configuration interface available");
2001 return JNI_FALSE;
2002 }
2003
2004 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002005 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002006 return result;
2007 } else {
2008 return JNI_FALSE;
2009 }
2010}
2011
2012static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
2013 jobject,
2014 jint lppProfile) {
2015 if (gnssConfigurationIface == nullptr) {
2016 ALOGE("no GNSS configuration interface available");
2017 return JNI_FALSE;
2018 }
2019
2020 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
2021
Steven Morelandd002a8b2017-01-03 17:18:24 -08002022 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002023 return result;
2024 } else {
2025 return JNI_FALSE;
2026 }
2027}
2028
2029static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
2030 jobject,
2031 jint gnssPosProtocol) {
2032 if (gnssConfigurationIface == nullptr) {
2033 ALOGE("no GNSS configuration interface available");
2034 return JNI_FALSE;
2035 }
2036
2037 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002038 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002039 return result;
2040 } else {
2041 return JNI_FALSE;
2042 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002043}
2044
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002045static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
2046 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2047 if (gnssConfigurationIface_V1_1 == nullptr) {
2048 ALOGI("No GNSS Satellite Blacklist interface available");
2049 return JNI_FALSE;
2050 }
2051
2052 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002053 if (nullptr == constellation_array) {
2054 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002055 return JNI_FALSE;
2056 }
2057 jsize length = env->GetArrayLength(constellations);
2058
2059 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002060 if (nullptr == sv_id_array) {
2061 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002062 return JNI_FALSE;
2063 }
2064
2065 if (length != env->GetArrayLength(sv_ids)) {
2066 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2067 return JNI_FALSE;
2068 }
2069
2070 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2071 sources.resize(length);
2072
2073 for (int i = 0; i < length; i++) {
2074 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2075 sources[i].svid = sv_id_array[i];
2076 }
2077
2078 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2079 if (result.isOk()) {
2080 return result;
2081 } else {
2082 return JNI_FALSE;
2083 }
2084}
2085
2086
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002087static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002088 if (gnssBatchingIface == nullptr) {
2089 return 0; // batching not supported, size = 0
2090 }
2091 auto result = gnssBatchingIface->getBatchSize();
2092 if (result.isOk()) {
2093 return static_cast<jint>(result);
2094 } else {
2095 return 0; // failure in binder, don't support batching
2096 }
2097}
2098
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002099static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002100 if (gnssBatchingIface == nullptr) {
2101 return JNI_FALSE; // batching not supported
2102 }
2103 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2104
2105 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2106}
2107
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002108static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002109 if (gnssBatchingIface == nullptr) {
2110 return; // batching not supported
2111 }
2112 gnssBatchingIface->cleanup();
2113}
2114
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002115static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002116 jlong periodNanos, jboolean wakeOnFifoFull) {
2117 if (gnssBatchingIface == nullptr) {
2118 return JNI_FALSE; // batching not supported
2119 }
2120
2121 IGnssBatching::Options options;
2122 options.periodNanos = periodNanos;
2123 if (wakeOnFifoFull) {
2124 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2125 } else {
2126 options.flags = 0;
2127 }
2128
2129 return static_cast<jboolean>(gnssBatchingIface->start(options));
2130}
2131
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002132static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002133 if (gnssBatchingIface == nullptr) {
2134 return; // batching not supported
2135 }
2136
2137 gnssBatchingIface->flush();
2138}
2139
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002140static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002141 if (gnssBatchingIface == nullptr) {
2142 return JNI_FALSE; // batching not supported
2143 }
2144
2145 return gnssBatchingIface->stop();
2146}
2147
Daniel Micay76f6a862015-09-19 17:31:01 -04002148static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002150 {"class_init_native", "()V", reinterpret_cast<void *>(
2151 android_location_GnssLocationProvider_class_init_native)},
2152 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2153 android_location_GnssLocationProvider_is_supported)},
destradaaef752b62015-04-17 13:10:47 -07002154 {"native_is_gnss_configuration_supported", "()Z",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002155 reinterpret_cast<void *>(
2156 android_location_gpsLocationProvider_is_gnss_configuration_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002157 {"native_init_once", "()V", reinterpret_cast<void *>(
2158 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002159 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2160 {"native_cleanup", "()V", reinterpret_cast<void *>(
2161 android_location_GnssLocationProvider_cleanup)},
destradaaea8a8a62014-06-23 18:19:03 -07002162 {"native_set_position_mode",
gomo48f1a642017-11-10 20:35:46 -08002163 "(IIIIIZ)Z",
2164 reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002165 {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
2166 {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
destradaaea8a8a62014-06-23 18:19:03 -07002167 {"native_delete_aiding_data",
2168 "(I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002169 reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002170 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2171 android_location_GnssLocationProvider_read_nmea)},
2172 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2173 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yange7baef32018-02-09 13:58:17 -08002174 {"native_inject_best_location",
2175 "(IDDDFFFFFFJ)V",
2176 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)},
destradaaea8a8a62014-06-23 18:19:03 -07002177 {"native_inject_location",
2178 "(DDF)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002179 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
2180 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2181 android_location_GnssLocationProvider_supports_xtra)},
destradaaea8a8a62014-06-23 18:19:03 -07002182 {"native_inject_xtra_data",
2183 "([BI)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002184 reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
destradaaea8a8a62014-06-23 18:19:03 -07002185 {"native_agps_set_id",
2186 "(ILjava/lang/String;)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002187 reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
destradaaea8a8a62014-06-23 18:19:03 -07002188 {"native_agps_set_ref_location_cellid",
2189 "(IIIII)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002190 reinterpret_cast<void *>(
2191 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
destradaaea8a8a62014-06-23 18:19:03 -07002192 {"native_set_agps_server",
2193 "(ILjava/lang/String;I)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002194 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
destradaaea8a8a62014-06-23 18:19:03 -07002195 {"native_send_ni_response",
2196 "(II)V",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002197 reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
destradaaea8a8a62014-06-23 18:19:03 -07002198 {"native_get_internal_state",
2199 "()Ljava/lang/String;",
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002200 reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002201 {"native_set_supl_es",
2202 "(I)Z",
2203 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
2204 {"native_set_supl_version",
2205 "(I)Z",
2206 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
2207 {"native_set_supl_mode",
2208 "(I)Z",
2209 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
2210 {"native_set_lpp_profile",
2211 "(I)Z",
2212 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
2213 {"native_set_gnss_pos_protocol_select",
2214 "(I)Z",
2215 reinterpret_cast<void *>(
2216 android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
2217 {"native_set_gps_lock",
2218 "(I)Z",
2219 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
2220 {"native_set_emergency_supl_pdn",
2221 "(I)Z",
2222 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002223 {"native_set_satellite_blacklist",
2224 "([I[I)Z",
2225 reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002226};
2227
2228static const JNINativeMethod sMethodsBatching[] = {
2229 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002230 {"native_get_batch_size",
2231 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002232 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002233 {"native_start_batch",
2234 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002235 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002236 {"native_flush_batch",
2237 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002238 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002239 {"native_stop_batch",
2240 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002241 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002242 {"native_init_batching",
2243 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002244 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002245 {"native_cleanup_batching",
2246 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002247 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248};
2249
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002250static const JNINativeMethod sGeofenceMethods[] = {
2251 /* name, signature, funcPtr */
2252 {"native_is_geofence_supported",
2253 "()Z",
2254 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2255 {"native_add_geofence",
2256 "(IDDDIIII)Z",
2257 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2258 {"native_remove_geofence",
2259 "(I)Z",
2260 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2261 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2262 android_location_GnssGeofenceProvider_pause_geofence)},
2263 {"native_resume_geofence",
2264 "(II)Z",
2265 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2266};
2267
Yu-Han Yang8de21502018-04-23 01:40:25 -07002268static const JNINativeMethod sMeasurementMethods[] = {
2269 /* name, signature, funcPtr */
2270 {"native_is_measurement_supported",
2271 "()Z",
2272 reinterpret_cast<void *>(
2273 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2274 {"native_start_measurement_collection",
2275 "(Z)Z",
2276 reinterpret_cast<void *>(
2277 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2278 {"native_stop_measurement_collection",
2279 "()Z",
2280 reinterpret_cast<void *>(
2281 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2282};
2283
Yu-Han Yang23d92162018-04-19 06:03:00 -07002284static const JNINativeMethod sNavigationMessageMethods[] = {
2285 /* name, signature, funcPtr */
2286 {"native_is_navigation_message_supported",
2287 "()Z",
2288 reinterpret_cast<void *>(
2289 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2290 {"native_start_navigation_message_collection",
2291 "()Z",
2292 reinterpret_cast<void *>(
2293 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2294 {"native_stop_navigation_message_collection",
2295 "()Z",
2296 reinterpret_cast<void *>(
2297 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2298};
2299
Anil Admal50ba15e2018-11-01 16:42:42 -07002300static const JNINativeMethod sNetworkConnectivityMethods[] = {
2301 /* name, signature, funcPtr */
2302 {"native_is_agps_ril_supported", "()Z",
2303 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
2304 {"native_update_network_state",
2305 "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
2306 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
2307 {"native_agps_data_conn_open",
2308 "(Ljava/lang/String;I)V",
2309 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
2310 {"native_agps_data_conn_closed",
2311 "()V",
2312 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
2313 {"native_agps_data_conn_failed",
2314 "()V",
2315 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
2316};
2317
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002318int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002319 jniRegisterNativeMethods(
2320 env,
2321 "com/android/server/location/GnssBatchingProvider",
2322 sMethodsBatching,
2323 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002324 jniRegisterNativeMethods(
2325 env,
2326 "com/android/server/location/GnssGeofenceProvider",
2327 sGeofenceMethods,
2328 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002329 jniRegisterNativeMethods(
2330 env,
2331 "com/android/server/location/GnssMeasurementsProvider",
2332 sMeasurementMethods,
2333 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002334 jniRegisterNativeMethods(
2335 env,
2336 "com/android/server/location/GnssNavigationMessageProvider",
2337 sNavigationMessageMethods,
2338 NELEM(sNavigationMessageMethods));
Anil Admal50ba15e2018-11-01 16:42:42 -07002339 jniRegisterNativeMethods(
2340 env,
2341 "com/android/server/location/GnssNetworkConnectivityHandler",
2342 sNetworkConnectivityMethods,
2343 NELEM(sNetworkConnectivityMethods));
destradaaea8a8a62014-06-23 18:19:03 -07002344 return jniRegisterNativeMethods(
2345 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08002346 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07002347 sMethods,
2348 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349}
2350
2351} /* namespace android */