blob: 03240c076ede1689197666dce76e21cefecd0946 [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>
gomo226b7b72018-12-12 16:49:39 -080028#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
Anil Admal94ec76a2019-01-15 09:42:01 -080029#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070030#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031#include "jni.h"
Mike Lockwood8f5a8002010-04-07 09:05:26 -040032#include "hardware_legacy/power.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033#include "utils/Log.h"
34#include "utils/misc.h"
Mike Lockwoodf602d362010-06-20 14:28:16 -070035#include "android_runtime/AndroidRuntime.h"
Ruben Brunk87eac992013-09-09 17:44:59 -070036#include "android_runtime/Log.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
destradaa931a37f2014-08-12 16:36:59 -070038#include <arpa/inet.h>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -080039#include <cinttypes>
40#include <iomanip>
Lifu Tang38bce792016-02-24 17:17:38 -080041#include <limits>
destradaa96a14702014-06-05 11:36:30 -070042#include <linux/in.h>
43#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080044#include <pthread.h>
45#include <string.h>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -080046#include <utils/SystemClock.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
WyattRiley840c0b22018-10-31 09:03:53 -070048static jobject mCallbacksObj = nullptr;
Mike Lockwoodf602d362010-06-20 14:28:16 -070049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050static jmethodID method_reportLocation;
51static jmethodID method_reportStatus;
52static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040053static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040054static jmethodID method_reportNmea;
Mike Lockwood04598b62010-04-14 17:17:24 -040055static jmethodID method_setEngineCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080056static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080057static jmethodID method_setGnssHardwareModelName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058static jmethodID method_xtraDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040059static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020061static jmethodID method_requestRefLocation;
62static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040063static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070064static jmethodID method_reportGeofenceTransition;
65static jmethodID method_reportGeofenceStatus;
66static jmethodID method_reportGeofenceAddStatus;
67static jmethodID method_reportGeofenceRemoveStatus;
68static jmethodID method_reportGeofencePauseStatus;
69static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070070static jmethodID method_reportMeasurementData;
destradaa4b3e3932014-07-21 18:01:47 -070071static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080072static jmethodID method_reportLocationBatch;
Yu-Han Yang52057622018-04-25 00:51:22 -070073static jmethodID method_reportGnssServiceDied;
gomo226b7b72018-12-12 16:49:39 -080074static jmethodID method_correctionsGetLatitudeDegrees;
75static jmethodID method_correctionsGetLongitudeDegrees;
76static jmethodID method_correctionsGetAltitudeMeters;
gomo6ec95382019-01-26 03:08:18 -080077static jmethodID method_correctionsGetHorPosUncMeters;
78static jmethodID method_correctionsGetVerPosUncMeters;
gomo226b7b72018-12-12 16:49:39 -080079static jmethodID method_correctionsGetToaGpsNanosecondsOfWeek;
80static jmethodID method_correctionsGetSingleSatCorrectionList;
81static jmethodID method_listSize;
82static jmethodID method_correctionListGet;
83static jmethodID method_correctionSatFlags;
84static jmethodID method_correctionSatConstType;
85static jmethodID method_correctionSatId;
86static jmethodID method_correctionSatCarrierFreq;
gomob4635ba2019-01-17 04:02:53 -080087static jmethodID method_correctionSatIsLosProb;
gomo226b7b72018-12-12 16:49:39 -080088static jmethodID method_correctionSatEpl;
89static jmethodID method_correctionSatEplUnc;
90static jmethodID method_correctionSatRefPlane;
91static jmethodID method_correctionPlaneLatDeg;
92static jmethodID method_correctionPlaneLngDeg;
93static jmethodID method_correctionPlaneAltDeg;
94static jmethodID method_correctionPlaneAzimDeg;
Anil Admal94ec76a2019-01-15 09:42:01 -080095static jmethodID method_reportNfwNotification;
96static jmethodID method_isInEmergencySession;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -080098/*
99 * Save a pointer to JavaVm to attach/detach threads executing
100 * callback methods that need to make JNI calls.
101 */
102static JavaVM* sJvm;
103
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700104using android::OK;
105using android::sp;
gomo25208882017-04-15 02:05:25 -0700106using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700107using android::status_t;
108using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700110using android::hardware::Return;
111using android::hardware::Void;
112using android::hardware::hidl_vec;
Anil Admalc70344b2018-11-16 14:22:38 -0800113using android::hardware::hidl_string;
gomo25208882017-04-15 02:05:25 -0700114using android::hardware::hidl_death_recipient;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800115
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800116using android::hardware::gnss::V1_0::GnssConstellationType;
117using android::hardware::gnss::V1_0::GnssLocationFlags;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700118using android::hardware::gnss::V1_0::IAGnssRilCallback;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800119using android::hardware::gnss::V1_0::IGnssBatching;
120using android::hardware::gnss::V1_0::IGnssBatchingCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700121using android::hardware::gnss::V1_0::IGnssDebug;
122using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
123using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700124using android::hardware::gnss::V1_0::IGnssNavigationMessage;
125using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
126using android::hardware::gnss::V1_0::IGnssNi;
127using android::hardware::gnss::V1_0::IGnssNiCallback;
128using android::hardware::gnss::V1_0::IGnssXtra;
129using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800130
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800131using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
gomo226b7b72018-12-12 16:49:39 -0800132using android::hardware::gnss::V2_0::IGnssCallback;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800133
gomo226b7b72018-12-12 16:49:39 -0800134using android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
135using android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
136using android::hardware::gnss::measurement_corrections::V1_0::ReflectingPlane;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800137
138using android::hidl::base::V1_0::IBase;
139
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800140using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
141using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800142using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
143using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800144using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700145using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
146using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Anil Admald71cf142018-12-21 14:59:36 -0800147using IGnssConfiguration_V2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800148using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
149using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800150using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800151using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
152using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800153using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
Anil Admalb4995e22018-11-16 17:36:21 -0800154using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil;
155using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil;
Anil Admalc70344b2018-11-16 14:22:38 -0800156using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss;
157using IAGnss_V2_0 = android::hardware::gnss::V2_0::IAGnss;
158using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
159using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800160
gomo226b7b72018-12-12 16:49:39 -0800161using IMeasurementCorrections =
162 android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
163
Anil Admal94ec76a2019-01-15 09:42:01 -0800164using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
165using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
166
gomo25208882017-04-15 02:05:25 -0700167struct GnssDeathRecipient : virtual public hidl_death_recipient
168{
169 // hidl_death_recipient interface
170 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700171 ALOGE("IGNSS hidl service failed, trying to recover...");
172
173 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
174 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700175 }
176};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700177
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800178// Must match the value from GnssMeasurement.java
179static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
180
gomo25208882017-04-15 02:05:25 -0700181sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800182sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800183sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800184sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700185sp<IGnssXtra> gnssXtraIface = nullptr;
Anil Admalb4995e22018-11-16 17:36:21 -0800186sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
187sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700188sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
Anil Admalc70344b2018-11-16 14:22:38 -0800189sp<IAGnss_V1_0> agnssIface = nullptr;
190sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800191sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700192sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700193sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
194sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Anil Admald71cf142018-12-21 14:59:36 -0800195sp<IGnssConfiguration_V2_0> gnssConfigurationIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700196sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800197sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
198sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800199sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700200sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
gomo226b7b72018-12-12 16:49:39 -0800201sp<IMeasurementCorrections> gnssCorrectionsIface = nullptr;
202// This boolean is needed to ensure that Gnsss Measurement Corrections related method are only
203// initalized when needed which will be few devices initially
204bool firstGnssMeasurementCorrectionInjected = false;
Anil Admal94ec76a2019-01-15 09:42:01 -0800205sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400207#define WAKE_LOCK_NAME "GPS"
208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209namespace android {
210
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800211namespace {
212
213// Returns true if location has lat/long information.
214bool hasLatLong(const GnssLocation_V1_0& location) {
215 return (static_cast<uint32_t>(location.gnssLocationFlags) &
216 GnssLocationFlags::HAS_LAT_LONG) != 0;
217}
218
219// Returns true if location has lat/long information.
220bool hasLatLong(const GnssLocation_V2_0& location) {
221 return hasLatLong(location.v1_0);
222}
223
224} // namespace
Lifu Tang120480f2016-02-07 18:08:19 -0800225template<class T>
226class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700227 public:
228 // Helper function to call setter on a Java object.
229 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800230 JNIEnv* env,
231 jclass clazz,
232 jobject object,
233 const char* method_name,
234 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700235
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700236 private:
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800237 static const char* const signature_;
Lifu Tang120480f2016-02-07 18:08:19 -0800238};
Lifu Tange5a0e212016-01-25 18:02:17 -0800239
Lifu Tang120480f2016-02-07 18:08:19 -0800240template<class T>
241void JavaMethodHelper<T>::callJavaMethod(
242 JNIEnv* env,
243 jclass clazz,
244 jobject object,
245 const char* method_name,
246 T value) {
247 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
248 env->CallVoidMethod(object, method, value);
249}
destradaaea8a8a62014-06-23 18:19:03 -0700250
Lifu Tang120480f2016-02-07 18:08:19 -0800251class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700252 public:
253 JavaObject(JNIEnv* env, const char* class_name);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800254 JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800255 JavaObject(JNIEnv* env, const char* class_name, jobject object);
256
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700257 virtual ~JavaObject();
Lifu Tang120480f2016-02-07 18:08:19 -0800258
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700259 template<class T>
260 void callSetter(const char* method_name, T value);
261 template<class T>
262 void callSetter(const char* method_name, T* value, size_t size);
263 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800264
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700265 private:
266 JNIEnv* env_;
267 jclass clazz_;
268 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800269};
270
271JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
272 clazz_ = env_->FindClass(class_name);
273 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
274 object_ = env_->NewObject(clazz_, ctor);
275}
276
Wyatt Rileycf879db2017-01-12 13:57:38 -0800277JavaObject::JavaObject(JNIEnv* env, const char* class_name, const char * sz_arg_1) : env_(env) {
278 clazz_ = env_->FindClass(class_name);
279 jmethodID ctor = env->GetMethodID(clazz_, "<init>", "(Ljava/lang/String;)V");
280 object_ = env_->NewObject(clazz_, ctor, env->NewStringUTF(sz_arg_1));
281}
282
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800283JavaObject::JavaObject(JNIEnv* env, const char* class_name, jobject object)
284 : env_(env), object_(object) {
285 clazz_ = env_->FindClass(class_name);
286}
287
Lifu Tang120480f2016-02-07 18:08:19 -0800288JavaObject::~JavaObject() {
289 env_->DeleteLocalRef(clazz_);
290}
291
292template<class T>
293void JavaObject::callSetter(const char* method_name, T value) {
294 JavaMethodHelper<T>::callJavaMethod(
295 env_, clazz_, object_, method_name, value);
296}
297
298template<>
299void JavaObject::callSetter(
300 const char* method_name, uint8_t* value, size_t size) {
301 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700302 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800303 jmethodID method = env_->GetMethodID(
304 clazz_,
305 method_name,
306 "([B)V");
307 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700308 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800309}
310
311jobject JavaObject::get() {
312 return object_;
313}
314
315// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800316template<>
317const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
318template<>
319const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
320template<>
321const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
322template<>
323const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
324template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800325const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
326template<>
327const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800328template<>
329const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
330template<>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800331const char *const JavaMethodHelper<uint64_t>::signature_ = "(J)V";
332template<>
Lifu Tang120480f2016-02-07 18:08:19 -0800333const char *const JavaMethodHelper<float>::signature_ = "(F)V";
334template<>
335const char *const JavaMethodHelper<double>::signature_ = "(D)V";
336template<>
337const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
338
339#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800340
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700341static inline jboolean boolToJbool(bool value) {
342 return value ? JNI_TRUE : JNI_FALSE;
343}
Lifu Tang120480f2016-02-07 18:08:19 -0800344
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700345static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
346 if (env->ExceptionCheck()) {
347 ALOGE("An exception was thrown by callback '%s'.", methodName);
348 LOGE_EX(env);
349 env->ExceptionClear();
350 }
351}
destradaaea8a8a62014-06-23 18:19:03 -0700352
Anil Admald71cf142018-12-21 14:59:36 -0800353static jobject createHalInterfaceVersionJavaObject(JNIEnv* env, jint major, jint minor) {
354 jclass versionClass =
355 env->FindClass("com/android/server/location/GnssConfiguration$HalInterfaceVersion");
356 jmethodID versionCtor = env->GetMethodID(versionClass, "<init>", "(II)V");
357 jobject version = env->NewObject(versionClass, versionCtor, major, minor);
358 env->DeleteLocalRef(versionClass);
359 return version;
360}
361
Anil Admalc70344b2018-11-16 14:22:38 -0800362struct ScopedJniString {
363 ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
364 mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
365 }
366
367 ~ScopedJniString() {
368 if (mNativeString != nullptr) {
369 mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
370 }
371 }
372
373 const char* c_str() const {
374 return mNativeString;
375 }
376
377 operator hidl_string() const {
378 return hidl_string(mNativeString);
379 }
380
381private:
382 ScopedJniString(const ScopedJniString&) = delete;
383 ScopedJniString& operator=(const ScopedJniString&) = delete;
384
385 JNIEnv* mEnv;
386 jstring mJavaString;
387 const char* mNativeString;
388};
389
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800390class ScopedJniThreadAttach {
391public:
392 ScopedJniThreadAttach() {
393 /*
394 * attachResult will also be JNI_OK if the thead was already attached to
395 * JNI before the call to AttachCurrentThread().
396 */
397 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
398 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
399 attachResult);
400 }
401
402 ~ScopedJniThreadAttach() {
403 jint detachResult = sJvm->DetachCurrentThread();
404 /*
405 * Return if the thread was already detached. Log error for any other
406 * failure.
407 */
408 if (detachResult == JNI_EDETACHED) {
409 return;
410 }
411
412 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
413 detachResult);
414 }
415
416 JNIEnv* getEnv() {
417 /*
418 * Checking validity of mEnv in case the thread was detached elsewhere.
419 */
420 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
421 return mEnv;
422 }
423
424private:
425 JNIEnv* mEnv = nullptr;
426};
427
428thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
429
430static JNIEnv* getJniEnv() {
431 JNIEnv* env = AndroidRuntime::getJNIEnv();
432
433 /*
434 * If env is nullptr, the thread is not already attached to
435 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
436 * will detach it on thread exit.
437 */
438 if (env == nullptr) {
439 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
440 env = tJniThreadAttacher->getEnv();
441 }
442
443 return env;
444}
445
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800446static jobject translateGnssLocation(JNIEnv* env,
447 const GnssLocation_V1_0& location) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800448 JavaObject object(env, "android/location/Location", "gps");
449
450 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800451 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800452 SET(Latitude, location.latitudeDegrees);
453 SET(Longitude, location.longitudeDegrees);
454 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800455 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800456 SET(Altitude, location.altitudeMeters);
457 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800458 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800459 SET(Speed, location.speedMetersPerSec);
460 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800461 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800462 SET(Bearing, location.bearingDegrees);
463 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800464 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800465 SET(Accuracy, location.horizontalAccuracyMeters);
466 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800467 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800468 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
469 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800470 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800471 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
472 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800473 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800474 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
475 }
476 SET(Time, location.timestamp);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800477 SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
Wyatt Riley5d229832017-02-10 17:06:00 -0800478
479 return object.get();
480}
481
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800482static jobject translateGnssLocation(JNIEnv* env,
483 const GnssLocation_V2_0& location) {
484 JavaObject object(env, "android/location/Location",
485 translateGnssLocation(env, location.v1_0));
486
487 const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);
488
489 // Overwrite ElapsedRealtimeNanos when available from HAL.
490 if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
491 SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
492 }
493
494 return object.get();
495}
496
497static GnssLocation_V1_0 createGnssLocation_V1_0(
498 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
499 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
500 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
501 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
Yu-Han Yange7baef32018-02-09 13:58:17 -0800502 jlong timestamp) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800503 GnssLocation_V1_0 location;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800504 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
505 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
506 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
507 location.altitudeMeters = static_cast<double>(altitudeMeters);
508 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
509 location.bearingDegrees = static_cast<float>(bearingDegrees);
510 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
511 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
512 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
513 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
514 location.timestamp = static_cast<uint64_t>(timestamp);
515
516 return location;
517}
518
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800519static GnssLocation_V2_0 createGnssLocation_V2_0(
520 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
521 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
522 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
523 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
524 jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos) {
525 GnssLocation_V2_0 location;
526 location.v1_0 = createGnssLocation_V1_0(
527 gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
528 speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
529 verticalAccuracyMeters, speedAccuracyMetersPerSecond,
530 bearingAccuracyDegrees, timestamp);
531
532 location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
533 location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
534
535 return location;
536}
537
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700538/*
539 * GnssCallback class implements the callback methods for IGnss interface.
540 */
541struct GnssCallback : public IGnssCallback {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800542 Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700543 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
544 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
545 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
546 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
547 Return<void> gnssAcquireWakelockCb() override;
548 Return<void> gnssReleaseWakelockCb() override;
549 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800550 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700551 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800552
Wyatt Rileyfb840922017-11-08 15:07:58 -0800553 // New in 1.1
554 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
555
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800556 // New in 2.0
gomo226b7b72018-12-12 16:49:39 -0800557 Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800558 Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;
559
560 // Templated implementation for gnnsLocationCb and gnnsLocationCb_2_0.
561 template <class T>
562 Return<void> gnssLocationCbImpl(const T& location);
gomo226b7b72018-12-12 16:49:39 -0800563
Wyatt Riley26465d22018-02-12 13:44:24 -0800564 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700565 static const char* sNmeaString;
566 static size_t sNmeaStringLength;
567};
568
Wyatt Rileyfb840922017-11-08 15:07:58 -0800569Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
570 ALOGD("%s: name=%s\n", __func__, name.c_str());
571
Wyatt Rileyfb840922017-11-08 15:07:58 -0800572 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800573 jstring jstringName = env->NewStringUTF(name.c_str());
574 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800575 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800576
Wyatt Rileyfb840922017-11-08 15:07:58 -0800577 return Void();
578}
579
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700580const char* GnssCallback::sNmeaString = nullptr;
581size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700582
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800583template<class T>
584Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800585 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800586
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800587 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800588
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700589 env->CallVoidMethod(mCallbacksObj,
590 method_reportLocation,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800591 boolToJbool(hasLatLong(location)),
Wyatt Riley5d229832017-02-10 17:06:00 -0800592 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700593 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800594 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700595 return Void();
596}
597
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800598Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
599 return gnssLocationCbImpl<GnssLocation_V1_0>(location);
600}
601
602Return<void>
603GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
604 return gnssLocationCbImpl<GnssLocation_V2_0>(location);
605}
606
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700607Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800608 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700609 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
610 checkAndClearExceptionFromCallback(env, __FUNCTION__);
611 return Void();
612}
613
614Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800615 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700616
Wyatt Riley26465d22018-02-12 13:44:24 -0800617 uint32_t listSize = svStatus.numSvs;
618 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700619 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800620 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700621 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800622 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800623 }
624
Wyatt Riley26465d22018-02-12 13:44:24 -0800625 jintArray svidWithFlagArray = env->NewIntArray(listSize);
626 jfloatArray cn0Array = env->NewFloatArray(listSize);
627 jfloatArray elevArray = env->NewFloatArray(listSize);
628 jfloatArray azimArray = env->NewFloatArray(listSize);
629 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
630
631 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
632 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
633 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
634 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
635 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
636
637 /*
638 * Read GNSS SV info.
639 */
640 for (size_t i = 0; i < listSize; ++i) {
641 enum ShiftWidth: uint8_t {
642 SVID_SHIFT_WIDTH = 8,
643 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
644 };
645
646 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
647 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
648 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
649 static_cast<uint32_t>(info.svFlag);
650 cn0s[i] = info.cN0Dbhz;
651 elev[i] = info.elevationDegrees;
652 azim[i] = info.azimuthDegrees;
653 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800654 }
destradaaea8a8a62014-06-23 18:19:03 -0700655
Wyatt Riley26465d22018-02-12 13:44:24 -0800656 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
657 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
658 env->ReleaseFloatArrayElements(elevArray, elev, 0);
659 env->ReleaseFloatArrayElements(azimArray, azim, 0);
660 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
661
662 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
663 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
664 carrierFreqArray);
665
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700666 checkAndClearExceptionFromCallback(env, __FUNCTION__);
667 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700668}
669
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700670Return<void> GnssCallback::gnssNmeaCb(
671 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800672 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700673 /*
674 * The Java code will call back to read these values.
675 * We do this to avoid creating unnecessary String objects.
676 */
677 sNmeaString = nmea.c_str();
678 sNmeaStringLength = nmea.size();
679
680 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
681 checkAndClearExceptionFromCallback(env, __FUNCTION__);
682 return Void();
683}
684
685Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
686 ALOGD("%s: %du\n", __func__, capabilities);
687
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800688 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700689 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
690 checkAndClearExceptionFromCallback(env, __FUNCTION__);
691 return Void();
692}
693
gomo226b7b72018-12-12 16:49:39 -0800694Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
695 return GnssCallback::gnssSetCapabilitesCb(capabilities);
696}
697
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698Return<void> GnssCallback::gnssAcquireWakelockCb() {
699 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
700 return Void();
701}
702
703Return<void> GnssCallback::gnssReleaseWakelockCb() {
704 release_wake_lock(WAKE_LOCK_NAME);
705 return Void();
706}
707
708Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800709 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700710 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
711 checkAndClearExceptionFromCallback(env, __FUNCTION__);
712 return Void();
713}
714
Yu-Han Yang21988932018-01-23 15:07:37 -0800715Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800716 JNIEnv* env = getJniEnv();
717 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss));
718 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800719 return Void();
720}
721
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700722Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
723 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
724
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800725 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700726 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
727 info.yearOfHw);
728 checkAndClearExceptionFromCallback(env, __FUNCTION__);
729 return Void();
730}
731
732class GnssXtraCallback : public IGnssXtraCallback {
733 Return<void> downloadRequestCb() override;
734};
735
736/*
737 * GnssXtraCallback class implements the callback methods for the IGnssXtra
738 * interface.
739 */
740Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800741 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700742 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
743 checkAndClearExceptionFromCallback(env, __FUNCTION__);
744 return Void();
745}
746
747/*
748 * GnssGeofenceCallback class implements the callback methods for the
749 * IGnssGeofence interface.
750 */
751struct GnssGeofenceCallback : public IGnssGeofenceCallback {
752 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
753 Return<void> gnssGeofenceTransitionCb(
754 int32_t geofenceId,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800755 const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700756 GeofenceTransition transition,
757 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800758 Return<void>
759 gnssGeofenceStatusCb(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700760 GeofenceAvailability status,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800761 const GnssLocation_V1_0& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700762 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
763 GeofenceStatus status) override;
764 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
765 GeofenceStatus status) override;
766 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
767 GeofenceStatus status) override;
768 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
769 GeofenceStatus status) override;
770};
771
772Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800773 int32_t geofenceId, const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700774 GeofenceTransition transition,
775 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800776 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700777
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800778 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800779
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700780 env->CallVoidMethod(mCallbacksObj,
781 method_reportGeofenceTransition,
782 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800783 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700784 transition,
785 timestamp);
786
787 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800788 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700789 return Void();
790}
791
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800792Return<void>
793GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability status,
794 const GnssLocation_V1_0& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800795 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800796
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800797 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800798
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800799 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800800 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700801 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800802 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700803 return Void();
804}
805
806Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
807 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800808 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700809 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
810 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
811 }
812
813 env->CallVoidMethod(mCallbacksObj,
814 method_reportGeofenceAddStatus,
815 geofenceId,
816 status);
817 checkAndClearExceptionFromCallback(env, __FUNCTION__);
818 return Void();
819}
820
821Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
822 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800823 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700824 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
825 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
826 }
827
828 env->CallVoidMethod(mCallbacksObj,
829 method_reportGeofenceRemoveStatus,
830 geofenceId, status);
831 checkAndClearExceptionFromCallback(env, __FUNCTION__);
832 return Void();
833}
834
835Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
836 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800837 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700838 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
839 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
840 }
841
842 env->CallVoidMethod(mCallbacksObj,
843 method_reportGeofencePauseStatus,
844 geofenceId, status);
845 checkAndClearExceptionFromCallback(env, __FUNCTION__);
846 return Void();
847}
848
849Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
850 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800851 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700852 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
853 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
854 }
855
856 env->CallVoidMethod(mCallbacksObj,
857 method_reportGeofenceResumeStatus,
858 geofenceId, status);
859 checkAndClearExceptionFromCallback(env, __FUNCTION__);
860 return Void();
861}
862
863/*
864 * GnssNavigationMessageCallback interface implements the callback methods
865 * required by the IGnssNavigationMessage interface.
866 */
867struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
868 /*
869 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
870 * follow.
871 */
872 Return<void> gnssNavigationMessageCb(
873 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
874};
875
876Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
877 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800878 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700879
880 size_t dataLength = message.data.size();
881
882 std::vector<uint8_t> navigationData = message.data;
883 uint8_t* data = &(navigationData[0]);
WyattRiley840c0b22018-10-31 09:03:53 -0700884 if (dataLength == 0 || data == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700885 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
886 dataLength);
887 return Void();
888 }
889
890 JavaObject object(env, "android/location/GnssNavigationMessage");
891 SET(Type, static_cast<int32_t>(message.type));
892 SET(Svid, static_cast<int32_t>(message.svid));
893 SET(MessageId, static_cast<int32_t>(message.messageId));
894 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
895 object.callSetter("setData", data, dataLength);
896 SET(Status, static_cast<int32_t>(message.status));
897
898 jobject navigationMessage = object.get();
899 env->CallVoidMethod(mCallbacksObj,
900 method_reportNavigationMessages,
901 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800902 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700903 env->DeleteLocalRef(navigationMessage);
904 return Void();
905}
906
907/*
908 * GnssMeasurementCallback implements the callback methods required for the
909 * GnssMeasurement interface.
910 */
Yu-Han Yang88d79102018-11-14 14:20:57 -0800911struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 {
912 Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData& data)
913 override;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800914 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800915 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700916 private:
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800917 template<class T>
918 void translateSingleGnssMeasurement(const T* measurement, JavaObject& object);
919
920 template<class T>
921 jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
922
923 template<class T>
924 void translateAndSetGnssData(const T& data);
925
926 template<class T>
927 size_t getMeasurementCount(const T& data);
928
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800929 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800930 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700931 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
932};
933
Yu-Han Yang88d79102018-11-14 14:20:57 -0800934Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_0(
935 const IGnssMeasurementCallback_V2_0::GnssData& data) {
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -0800936 translateAndSetGnssData(data);
Yu-Han Yang88d79102018-11-14 14:20:57 -0800937 return Void();
938}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700939
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800940Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800941 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800942 translateAndSetGnssData(data);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700943 return Void();
944}
945
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800946Return<void> GnssMeasurementCallback::GnssMeasurementCb(
947 const IGnssMeasurementCallback_V1_0::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800948 translateAndSetGnssData(data);
949 return Void();
950}
951
952template<class T>
953void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800954 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800955
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800956 jobject clock;
957 jobjectArray measurementArray;
958
959 clock = translateGnssClock(env, &data.clock);
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800960 size_t count = getMeasurementCount(data);
961 measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800962 setMeasurementData(env, clock, measurementArray);
963
964 env->DeleteLocalRef(clock);
965 env->DeleteLocalRef(measurementArray);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800966}
967
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800968template<>
969size_t GnssMeasurementCallback::getMeasurementCount<IGnssMeasurementCallback_V1_0::GnssData>
970 (const IGnssMeasurementCallback_V1_0::GnssData& data) {
971 return data.measurementCount;
972}
973
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -0800974template<class T>
975size_t GnssMeasurementCallback::getMeasurementCount(const T& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800976 return data.measurements.size();
977}
978
979// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
980template<>
981void GnssMeasurementCallback::translateSingleGnssMeasurement
982 <IGnssMeasurementCallback_V1_0::GnssMeasurement>(
WyattRiley840c0b22018-10-31 09:03:53 -0700983 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -0800984 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700985 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -0700986
987 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -0800988 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700989 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800990 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700991 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -0800992 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700993 measurement->receivedSvTimeUncertaintyInNs);
994 SET(Cn0DbHz, measurement->cN0DbHz);
995 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800996 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700997 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -0800998 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800999 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
WyattRiley948dd6d2018-10-31 06:56:09 -07001000 ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001001 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -08001002 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001003 measurement->accumulatedDeltaRangeUncertaintyM);
1004
1005 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
1006 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
1007 }
1008
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001009 // Intentionally not copying deprecated fields of carrierCycles,
1010 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001011
1012 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
1013
1014 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
1015 SET(SnrInDb, measurement->snrDb);
1016 }
Lifu Tang120480f2016-02-07 18:08:19 -08001017
gomo4402af62017-01-11 13:20:13 -08001018 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -08001019 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -08001020 }
Lifu Tang120480f2016-02-07 18:08:19 -08001021}
1022
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001023// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1024template<>
1025void GnssMeasurementCallback::translateSingleGnssMeasurement
1026 <IGnssMeasurementCallback_V1_1::GnssMeasurement>(
1027 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurement_V1_1,
1028 JavaObject& object) {
1029 translateSingleGnssMeasurement(&(measurement_V1_1->v1_0), object);
1030
1031 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
1032 SET(AccumulatedDeltaRangeState,
1033 (static_cast<int32_t>(measurement_V1_1->accumulatedDeltaRangeState) |
1034 ADR_STATE_HALF_CYCLE_REPORTED));
1035}
1036
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001037// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1038template<>
1039void GnssMeasurementCallback::translateSingleGnssMeasurement
1040 <IGnssMeasurementCallback_V2_0::GnssMeasurement>(
1041 const IGnssMeasurementCallback_V2_0::GnssMeasurement* measurement_V2_0,
1042 JavaObject& object) {
1043 translateSingleGnssMeasurement(&(measurement_V2_0->v1_1), object);
1044
Yu-Han Yang786a2bd2019-02-01 19:52:28 -08001045 SET(CodeType, static_cast<int32_t>(measurement_V2_0->codeType));
1046
1047 // Overwrite with v2_0.state since v2_0->v1_1->v1_0.state is deprecated.
1048 SET(State, static_cast<int32_t>(measurement_V2_0->state));
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001049}
1050
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001051jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -08001052 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001053 JavaObject object(env, "android/location/GnssClock");
1054
1055 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
1056 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
1057 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
1058 }
1059
1060 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
1061 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
1062 }
1063
1064 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
1065 SET(FullBiasNanos, clock->fullBiasNs);
1066 }
1067
1068 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
1069 SET(BiasNanos, clock->biasNs);
1070 }
1071
1072 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
1073 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
1074 }
1075
1076 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
1077 SET(DriftNanosPerSecond, clock->driftNsps);
1078 }
1079
1080 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
1081 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
1082 }
1083
1084 SET(TimeNanos, clock->timeNs);
1085 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
1086
1087 return object.get();
1088}
1089
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001090template<class T>
1091jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
1092 const T* measurements,
1093 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -08001094 if (count == 0) {
WyattRiley840c0b22018-10-31 09:03:53 -07001095 return nullptr;
destradaaea8a8a62014-06-23 18:19:03 -07001096 }
1097
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001098 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -08001099 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -08001100 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -08001101 gnssMeasurementClass,
WyattRiley840c0b22018-10-31 09:03:53 -07001102 nullptr /* initialElement */);
destradaaea8a8a62014-06-23 18:19:03 -07001103
Lifu Tang120480f2016-02-07 18:08:19 -08001104 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001105 JavaObject object(env, "android/location/GnssMeasurement");
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001106 translateSingleGnssMeasurement(&(measurements[i]), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001107 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -07001108 }
1109
Lifu Tang818aa2c2016-02-01 01:52:00 -08001110 env->DeleteLocalRef(gnssMeasurementClass);
1111 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -07001112}
1113
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
1115 jobjectArray measurementArray) {
1116 jclass gnssMeasurementsEventClass =
1117 env->FindClass("android/location/GnssMeasurementsEvent");
1118 jmethodID gnssMeasurementsEventCtor =
1119 env->GetMethodID(
1120 gnssMeasurementsEventClass,
1121 "<init>",
1122 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -08001123
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001124 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
1125 gnssMeasurementsEventCtor,
1126 clock,
1127 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -08001128
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001129 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
1130 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -08001131 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -08001132 env->DeleteLocalRef(gnssMeasurementsEventClass);
1133 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -07001134}
1135
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001136/*
1137 * GnssNiCallback implements callback methods required by the IGnssNi interface.
1138 */
1139struct GnssNiCallback : public IGnssNiCallback {
1140 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
1141 override;
destradaaea8a8a62014-06-23 18:19:03 -07001142};
1143
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001144Return<void> GnssNiCallback::niNotifyCb(
1145 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001146 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001147 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1148 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
1149
1150 if (requestorId && text) {
1151 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
1152 notification.notificationId, notification.niType,
1153 notification.notifyFlags, notification.timeoutSec,
1154 notification.defaultResponse, requestorId, text,
1155 notification.requestorIdEncoding,
1156 notification.notificationIdEncoding);
1157 } else {
1158 ALOGE("%s: OOM Error\n", __func__);
1159 }
1160
1161 if (requestorId) {
1162 env->DeleteLocalRef(requestorId);
1163 }
1164
1165 if (text) {
1166 env->DeleteLocalRef(text);
1167 }
1168 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1169 return Void();
1170}
1171
1172/*
Anil Admal94ec76a2019-01-15 09:42:01 -08001173 * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
1174 */
1175struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
1176 Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
1177 override;
1178 Return<bool> isInEmergencySession() override;
1179};
1180
1181Return<void> GnssVisibilityControlCallback::nfwNotifyCb(
1182 const IGnssVisibilityControlCallback::NfwNotification& notification) {
1183 JNIEnv* env = getJniEnv();
1184 jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str());
1185 jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str());
1186 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1187
1188 if (proxyAppPackageName && otherProtocolStackName && requestorId) {
1189 env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
1190 notification.protocolStack, otherProtocolStackName,
1191 notification.requestor, requestorId,
1192 notification.inEmergencyMode, notification.isCachedLocation);
1193 } else {
1194 ALOGE("%s: OOM Error\n", __func__);
1195 }
1196
1197 if (requestorId) {
1198 env->DeleteLocalRef(requestorId);
1199 }
1200
1201 if (otherProtocolStackName) {
1202 env->DeleteLocalRef(otherProtocolStackName);
1203 }
1204
1205 if (proxyAppPackageName) {
1206 env->DeleteLocalRef(proxyAppPackageName);
1207 }
1208
1209 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1210 return Void();
1211}
1212
1213Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
1214 JNIEnv* env = getJniEnv();
1215 auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
1216 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1217 return result;
1218}
1219
1220/*
Anil Admalc70344b2018-11-16 14:22:38 -08001221 * AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001222 */
Anil Admalc70344b2018-11-16 14:22:38 -08001223struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001224 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
1225 Return<void> agnssStatusIpV6Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001226 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001227
1228 Return<void> agnssStatusIpV4Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001229 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001230 private:
1231 jbyteArray convertToIpV4(uint32_t ip);
1232};
1233
Anil Admalc70344b2018-11-16 14:22:38 -08001234Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
1235 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001236 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001237 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238
1239 byteArray = env->NewByteArray(16);
WyattRiley840c0b22018-10-31 09:03:53 -07001240 if (byteArray != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001241 env->SetByteArrayRegion(byteArray, 0, 16,
1242 (const jbyte*)(agps_status.ipV6Addr.data()));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001243 } else {
1244 ALOGE("Unable to allocate byte array for IPv6 address.");
1245 }
1246
1247 IF_ALOGD() {
1248 // log the IP for reference in case there is a bogus value pushed by HAL
1249 char str[INET6_ADDRSTRLEN];
1250 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1251 ALOGD("AGPS IP is v6: %s", str);
1252 }
1253
WyattRiley840c0b22018-10-31 09:03:53 -07001254 jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001255 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1256 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1257 agps_status.type, agps_status.status, byteArray);
1258
1259 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1260
1261 if (byteArray) {
1262 env->DeleteLocalRef(byteArray);
1263 }
1264
1265 return Void();
1266}
1267
Anil Admalc70344b2018-11-16 14:22:38 -08001268Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
1269 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001270 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001271 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001272
1273 uint32_t ipAddr = agps_status.ipV4Addr;
1274 byteArray = convertToIpV4(ipAddr);
1275
1276 IF_ALOGD() {
1277 /*
1278 * log the IP for reference in case there is a bogus value pushed by
1279 * HAL.
1280 */
1281 char str[INET_ADDRSTRLEN];
1282 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1283 ALOGD("AGPS IP is v4: %s", str);
1284 }
1285
1286 jsize byteArrayLength =
WyattRiley840c0b22018-10-31 09:03:53 -07001287 byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001288 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1289 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1290 agps_status.type, agps_status.status, byteArray);
1291
1292 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1293
1294 if (byteArray) {
1295 env->DeleteLocalRef(byteArray);
1296 }
1297 return Void();
1298}
1299
Anil Admalc70344b2018-11-16 14:22:38 -08001300jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001301 if (INADDR_NONE == ip) {
WyattRiley840c0b22018-10-31 09:03:53 -07001302 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001303 }
1304
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001305 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001306 jbyteArray byteArray = env->NewByteArray(4);
WyattRiley840c0b22018-10-31 09:03:53 -07001307 if (byteArray == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001308 ALOGE("Unable to allocate byte array for IPv4 address");
WyattRiley840c0b22018-10-31 09:03:53 -07001309 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001310 }
1311
1312 jbyte ipv4[4];
1313 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1314 memcpy(ipv4, &ip, sizeof(ipv4));
1315 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1316 return byteArray;
1317}
1318
1319/*
Anil Admalc70344b2018-11-16 14:22:38 -08001320 * AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
1321 */
1322struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 {
1323 // Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
1324 Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1325 IAGnssCallback_V2_0::AGnssStatusValue status) override;
1326};
1327
1328Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1329 IAGnssCallback_V2_0::AGnssStatusValue status) {
1330 JNIEnv* env = getJniEnv();
1331 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
1332 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1333 return Void();
1334}
1335
1336/*
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001337 * AGnssRilCallback implements the callback methods required by the AGnssRil
1338 * interface.
1339 */
1340struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001341 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001342 Return<void> requestRefLocCb() override;
1343};
1344
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001345Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001346 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001347 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1348 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1349 return Void();
1350}
1351
1352Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001353 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001354 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1355 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1356 return Void();
1357}
1358
Wyatt Rileycf879db2017-01-12 13:57:38 -08001359/*
1360 * GnssBatchingCallback interface implements the callback methods
1361 * required by the IGnssBatching interface.
1362 */
1363struct GnssBatchingCallback : public IGnssBatchingCallback {
1364 /*
1365 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1366 * follow.
1367 */
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001368 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001369};
1370
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001371Return<void> GnssBatchingCallback::gnssLocationBatchCb(
1372 const hidl_vec<GnssLocation_V1_0>& locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001373 JNIEnv* env = getJniEnv();
1374
1375 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1376 env->FindClass("android/location/Location"), nullptr);
1377
1378 for (uint16_t i = 0; i < locations.size(); ++i) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001379 jobject jLocation = translateGnssLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001380 env->SetObjectArrayElement(jLocations, i, jLocation);
1381 env->DeleteLocalRef(jLocation);
1382 }
1383
1384 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1385 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1386
1387 env->DeleteLocalRef(jLocations);
1388
1389 return Void();
1390}
1391
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001392static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001393 gnssHal_V2_0 = IGnss_V2_0::getService();
1394 if (gnssHal_V2_0 != nullptr) {
1395 gnssHal = gnssHal_V2_0;
1396 gnssHal_V1_1 = gnssHal_V2_0;
1397 return;
Yu-Han Yang6d317352018-03-15 11:53:01 -07001398 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001399
1400 ALOGD("gnssHal 2.0 was null, trying 1.1");
1401 gnssHal_V1_1 = IGnss_V1_1::getService();
1402 if (gnssHal_V1_1 != nullptr) {
1403 gnssHal = gnssHal_V1_1;
1404 return;
1405 }
1406
1407 ALOGD("gnssHal 1.1 was null, trying 1.0");
1408 gnssHal = IGnss_V1_0::getService();
Yu-Han Yang6d317352018-03-15 11:53:01 -07001409}
1410
1411static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001412 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1413 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001414 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001415 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001416 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1417 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1418 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1419 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001420 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1421 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001422 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1423 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1424 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yange7baef32018-02-09 13:58:17 -08001425 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001426 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1427 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1428 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1429 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001430 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001431 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001432 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001433 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1434 "(II)V");
1435 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1436 "(II)V");
1437 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1438 "(II)V");
1439 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1440 "(II)V");
1441 method_reportMeasurementData = env->GetMethodID(
1442 clazz,
1443 "reportMeasurementData",
1444 "(Landroid/location/GnssMeasurementsEvent;)V");
1445 method_reportNavigationMessages = env->GetMethodID(
1446 clazz,
1447 "reportNavigationMessage",
1448 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001449 method_reportLocationBatch = env->GetMethodID(
1450 clazz,
1451 "reportLocationBatch",
1452 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001453 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Anil Admal94ec76a2019-01-15 09:42:01 -08001454 method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
1455 "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
1456 method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001457
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001458 /*
1459 * Save a pointer to JVM.
1460 */
1461 jint jvmStatus = env->GetJavaVM(&sJvm);
1462 if (jvmStatus != JNI_OK) {
1463 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1464 }
1465
Yu-Han Yang88d79102018-11-14 14:20:57 -08001466 if (gnssHal == nullptr) {
1467 ALOGE("Unable to get GPS service\n");
1468 return;
1469 }
gomo25208882017-04-15 02:05:25 -07001470
Yu-Han Yang88d79102018-11-14 14:20:57 -08001471 gnssHalDeathRecipient = new GnssDeathRecipient();
1472 hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
1473 if (!linked.isOk()) {
1474 ALOGE("Transaction error in linking to GnssHAL death: %s",
1475 linked.description().c_str());
1476 } else if (!linked) {
1477 ALOGW("Unable to link to GnssHal death notifications");
1478 } else {
1479 ALOGD("Link to death notification successful");
1480 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001481
Yu-Han Yang88d79102018-11-14 14:20:57 -08001482 auto gnssXtra = gnssHal->getExtensionXtra();
1483 if (!gnssXtra.isOk()) {
1484 ALOGD("Unable to get a handle to Xtra");
1485 } else {
1486 gnssXtraIface = gnssXtra;
1487 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001488
Anil Admalb4995e22018-11-16 17:36:21 -08001489 if (gnssHal_V2_0 != nullptr) {
1490 auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
1491 if (!agnssRil_V2_0.isOk()) {
1492 ALOGD("Unable to get a handle to AGnssRil_V2_0");
1493 } else {
1494 agnssRilIface_V2_0 = agnssRil_V2_0;
1495 agnssRilIface = agnssRilIface_V2_0;
1496 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001497 } else {
Anil Admalb4995e22018-11-16 17:36:21 -08001498 auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
1499 if (!agnssRil_V1_0.isOk()) {
1500 ALOGD("Unable to get a handle to AGnssRil");
1501 } else {
1502 agnssRilIface = agnssRil_V1_0;
1503 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001504 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001505
Anil Admalc70344b2018-11-16 14:22:38 -08001506 if (gnssHal_V2_0 != nullptr) {
1507 auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
1508 if (!agnss_V2_0.isOk()) {
1509 ALOGD("Unable to get a handle to AGnss_V2_0");
1510 } else {
1511 agnssIface_V2_0 = agnss_V2_0;
1512 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001513 } else {
Anil Admalc70344b2018-11-16 14:22:38 -08001514 auto agnss_V1_0 = gnssHal->getExtensionAGnss();
1515 if (!agnss_V1_0.isOk()) {
1516 ALOGD("Unable to get a handle to AGnss");
1517 } else {
1518 agnssIface = agnss_V1_0;
1519 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001520 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001521
Yu-Han Yang88d79102018-11-14 14:20:57 -08001522 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1523 if (!gnssNavigationMessage.isOk()) {
1524 ALOGD("Unable to get a handle to GnssNavigationMessage");
1525 } else {
1526 gnssNavigationMessageIface = gnssNavigationMessage;
1527 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001528
Yu-Han Yang88d79102018-11-14 14:20:57 -08001529 if (gnssHal_V2_0 != nullptr) {
1530 // TODO(b/119638366): getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
1531 auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
1532 if (!gnssMeasurement.isOk()) {
1533 ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001534 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001535 gnssMeasurementIface_V2_0 = gnssMeasurement;
1536 gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
1537 gnssMeasurementIface = gnssMeasurementIface_V2_0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001538 }
Anil Admal94ec76a2019-01-15 09:42:01 -08001539 auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
1540 if (!gnssCorrections.isOk()) {
1541 ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
1542 } else {
1543 gnssCorrectionsIface = gnssCorrections;
1544 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001545 } else if (gnssHal_V1_1 != nullptr) {
1546 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1547 if (!gnssMeasurement.isOk()) {
1548 ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
1549 } else {
1550 gnssMeasurementIface_V1_1 = gnssMeasurement;
1551 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1552 }
1553 } else {
1554 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1555 if (!gnssMeasurement_V1_0.isOk()) {
1556 ALOGD("Unable to get a handle to GnssMeasurement");
1557 } else {
1558 gnssMeasurementIface = gnssMeasurement_V1_0;
1559 }
1560 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001561
Yu-Han Yang88d79102018-11-14 14:20:57 -08001562 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1563 if (!gnssDebug.isOk()) {
1564 ALOGD("Unable to get a handle to GnssDebug");
1565 } else {
1566 gnssDebugIface = gnssDebug;
1567 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001568
Yu-Han Yang88d79102018-11-14 14:20:57 -08001569 auto gnssNi = gnssHal->getExtensionGnssNi();
1570 if (!gnssNi.isOk()) {
1571 ALOGD("Unable to get a handle to GnssNi");
1572 } else {
1573 gnssNiIface = gnssNi;
1574 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001575
Anil Admald71cf142018-12-21 14:59:36 -08001576 if (gnssHal_V2_0 != nullptr) {
1577 auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
1578 if (!gnssConfiguration.isOk()) {
1579 ALOGD("Unable to get a handle to GnssConfiguration_V2_0");
1580 } else {
1581 gnssConfigurationIface_V2_0 = gnssConfiguration;
1582 gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_0;
1583 gnssConfigurationIface = gnssConfigurationIface_V2_0;
1584 }
1585 } else if (gnssHal_V1_1 != nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001586 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1587 if (!gnssConfiguration.isOk()) {
Anil Admald71cf142018-12-21 14:59:36 -08001588 ALOGD("Unable to get a handle to GnssConfiguration_V1_1");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001589 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001590 gnssConfigurationIface_V1_1 = gnssConfiguration;
1591 gnssConfigurationIface = gnssConfigurationIface_V1_1;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001592 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001593 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001594 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1595 if (!gnssConfiguration_V1_0.isOk()) {
1596 ALOGD("Unable to get a handle to GnssConfiguration");
1597 } else {
1598 gnssConfigurationIface = gnssConfiguration_V1_0;
1599 }
1600 }
1601
1602 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1603 if (!gnssGeofencing.isOk()) {
1604 ALOGD("Unable to get a handle to GnssGeofencing");
1605 } else {
1606 gnssGeofencingIface = gnssGeofencing;
1607 }
1608
1609 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1610 if (!gnssBatching.isOk()) {
1611 ALOGD("Unable to get a handle to gnssBatching");
1612 } else {
1613 gnssBatchingIface = gnssBatching;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614 }
Anil Admal94ec76a2019-01-15 09:42:01 -08001615
1616 if (gnssHal_V2_0 != nullptr) {
1617 auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl();
1618 if (!gnssVisibilityControl.isOk()) {
1619 ALOGD("Unable to get a handle to GnssVisibilityControl interface");
1620 } else {
1621 gnssVisibilityControlIface = gnssVisibilityControl;
1622 }
1623 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001624}
1625
1626static jboolean android_location_GnssLocationProvider_is_supported(
1627 JNIEnv* /* env */, jclass /* clazz */) {
1628 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1629}
1630
Anil Admal50ba15e2018-11-01 16:42:42 -07001631static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 JNIEnv* /* env */, jclass /* clazz */) {
1633 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1634}
1635
Anil Admald71cf142018-12-21 14:59:36 -08001636static jobject android_location_GnssConfiguration_get_gnss_configuration_version(
1637 JNIEnv* env, jclass /* jclazz */) {
1638 jint major, minor;
1639 if (gnssConfigurationIface_V2_0 != nullptr) {
1640 major = 2;
1641 minor = 0;
1642 } else if (gnssConfigurationIface_V1_1 != nullptr) {
1643 major = 1;
1644 minor = 1;
1645 } else if (gnssConfigurationIface != nullptr) {
1646 major = 1;
1647 minor = 0;
1648 } else {
1649 return nullptr;
1650 }
1651
1652 return createHalInterfaceVersionJavaObject(env, major, minor);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001653}
1654
1655static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1656 /*
1657 * This must be set before calling into the HAL library.
1658 */
1659 if (!mCallbacksObj)
1660 mCallbacksObj = env->NewGlobalRef(obj);
1661
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001662 /*
1663 * Fail if the main interface fails to initialize
1664 */
1665 if (gnssHal == nullptr) {
1666 ALOGE("Unable to Initialize GNSS HAL\n");
1667 return JNI_FALSE;
1668 }
1669
Wyatt Rileyfb840922017-11-08 15:07:58 -08001670 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1671
1672 Return<bool> result = false;
gomo226b7b72018-12-12 16:49:39 -08001673 if (gnssHal_V2_0 != nullptr) {
1674 result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
1675 } else if (gnssHal_V1_1 != nullptr) {
gomo48f1a642017-11-10 20:35:46 -08001676 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001677 } else {
1678 result = gnssHal->setCallback(gnssCbIface);
1679 }
gomo226b7b72018-12-12 16:49:39 -08001680
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001681 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001682 ALOGE("SetCallback for Gnss Interface fails\n");
1683 return JNI_FALSE;
1684 }
1685
1686 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1687 if (gnssXtraIface == nullptr) {
WyattRileybc5a8b02018-10-31 13:06:34 -07001688 ALOGI("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001689 } else {
1690 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001691 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001692 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001693 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001694 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001695 }
1696
Anil Admalc70344b2018-11-16 14:22:38 -08001697 if (agnssIface_V2_0 != nullptr) {
1698 sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
1699 agnssIface_V2_0->setCallback(aGnssCbIface);
1700 } else if (agnssIface != nullptr) {
1701 sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001702 agnssIface->setCallback(aGnssCbIface);
1703 } else {
Anil Admalc70344b2018-11-16 14:22:38 -08001704 ALOGI("Unable to initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001705 }
1706
1707 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1708 if (gnssGeofencingIface != nullptr) {
1709 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1710 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001711 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001712 }
1713
1714 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001715 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001716 gnssNiIface->setCallback(gnssNiCbIface);
1717 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001718 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001719 }
1720
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001721 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1722 if (agnssRilIface != nullptr) {
1723 agnssRilIface->setCallback(aGnssRilCbIface);
1724 } else {
Anil Admal94ec76a2019-01-15 09:42:01 -08001725 ALOGI("Unable to initialize AGnss Ril interface\n");
1726 }
1727
1728 if (gnssVisibilityControlIface != nullptr) {
1729 sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
1730 new GnssVisibilityControlCallback();
1731 gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001732 }
1733
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001734 return JNI_TRUE;
1735}
1736
1737static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1738 if (gnssHal != nullptr) {
1739 gnssHal->cleanup();
1740 }
1741}
1742
1743static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1744 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001745 jint preferred_time, jboolean low_power_mode) {
1746 Return<bool> result = false;
1747 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001748 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1749 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1750 min_interval,
1751 preferred_accuracy,
1752 preferred_time,
1753 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001754 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001755 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1756 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1757 min_interval,
1758 preferred_accuracy,
1759 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001760 }
1761 if (!result.isOk()) {
1762 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1763 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001764 } else {
gomo48f1a642017-11-10 20:35:46 -08001765 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 }
1767}
1768
1769static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1770 if (gnssHal != nullptr) {
1771 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001772 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001773 return JNI_FALSE;
1774 } else {
1775 return result;
1776 }
1777 } else {
1778 return JNI_FALSE;
1779 }
1780}
1781
1782static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1783 if (gnssHal != nullptr) {
1784 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001785 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001786 return JNI_FALSE;
1787 } else {
1788 return result;
1789 }
1790 } else {
1791 return JNI_FALSE;
1792 }
1793}
1794static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1795 jobject /* obj */,
1796 jint flags) {
1797 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001798 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001799 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001800 ALOGE("Error in deleting aiding data");
1801 }
1802 }
1803}
1804
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001805static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1806 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
Anil Admalb4995e22018-11-16 17:36:21 -08001807 IAGnssRil_V1_0::AGnssRefLocation location;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001808
1809 if (agnssRilIface == nullptr) {
1810 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1811 return;
1812 }
1813
Anil Admalb4995e22018-11-16 17:36:21 -08001814 switch (static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type)) {
1815 case IAGnssRil_V1_0::AGnssRefLocationType::GSM_CELLID:
1816 case IAGnssRil_V1_0::AGnssRefLocationType::UMTS_CELLID:
1817 location.type = static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001818 location.cellID.mcc = mcc;
1819 location.cellID.mnc = mnc;
1820 location.cellID.lac = lac;
1821 location.cellID.cid = cid;
1822 break;
1823 default:
1824 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1825 return;
1826 break;
1827 }
1828
1829 agnssRilIface->setRefLocation(location);
1830}
1831
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001832static void android_location_GnssLocationProvider_agps_set_id(JNIEnv* env, jobject /* obj */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001833 jint type, jstring setid_string) {
1834 if (agnssRilIface == nullptr) {
1835 ALOGE("no AGPS RIL interface in agps_set_id");
1836 return;
1837 }
1838
Anil Admalc70344b2018-11-16 14:22:38 -08001839 ScopedJniString jniSetId{env, setid_string};
1840 agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001841}
1842
1843static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1844 jbyteArray nmeaArray, jint buffer_size) {
1845 // this should only be called from within a call to reportNmea
1846 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1847 int length = GnssCallback::sNmeaStringLength;
1848 if (length > buffer_size)
1849 length = buffer_size;
1850 memcpy(nmea, GnssCallback::sNmeaString, length);
1851 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1852 return (jint) length;
1853}
1854
1855static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1856 jlong time, jlong timeReference, jint uncertainty) {
1857 if (gnssHal != nullptr) {
1858 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001859 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001860 ALOGE("%s: Gnss injectTime() failed", __func__);
1861 }
1862 }
1863}
1864
Yu-Han Yange7baef32018-02-09 13:58:17 -08001865static void android_location_GnssLocationProvider_inject_best_location(
1866 JNIEnv*,
1867 jobject,
1868 jint gnssLocationFlags,
1869 jdouble latitudeDegrees,
1870 jdouble longitudeDegrees,
1871 jdouble altitudeMeters,
1872 jfloat speedMetersPerSec,
1873 jfloat bearingDegrees,
1874 jfloat horizontalAccuracyMeters,
1875 jfloat verticalAccuracyMeters,
1876 jfloat speedAccuracyMetersPerSecond,
1877 jfloat bearingAccuracyDegrees,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001878 jlong timestamp,
1879 jint elapsedRealtimeFlags,
1880 jlong elapsedRealtimeNanos) {
1881 if (gnssHal_V2_0 != nullptr) {
1882 GnssLocation_V2_0 location = createGnssLocation_V2_0(
1883 gnssLocationFlags,
1884 latitudeDegrees,
1885 longitudeDegrees,
1886 altitudeMeters,
1887 speedMetersPerSec,
1888 bearingDegrees,
1889 horizontalAccuracyMeters,
1890 verticalAccuracyMeters,
1891 speedAccuracyMetersPerSecond,
1892 bearingAccuracyDegrees,
1893 timestamp,
1894 elapsedRealtimeFlags,
1895 elapsedRealtimeNanos);
1896 auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
1897
1898 if (!result.isOk() || !result) {
1899 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1900 }
1901 return;
1902 }
1903
Yu-Han Yange7baef32018-02-09 13:58:17 -08001904 if (gnssHal_V1_1 != nullptr) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001905 GnssLocation_V1_0 location = createGnssLocation_V1_0(
Yu-Han Yange7baef32018-02-09 13:58:17 -08001906 gnssLocationFlags,
1907 latitudeDegrees,
1908 longitudeDegrees,
1909 altitudeMeters,
1910 speedMetersPerSec,
1911 bearingDegrees,
1912 horizontalAccuracyMeters,
1913 verticalAccuracyMeters,
1914 speedAccuracyMetersPerSecond,
1915 bearingAccuracyDegrees,
1916 timestamp);
1917 auto result = gnssHal_V1_1->injectBestLocation(location);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001918
Yu-Han Yange7baef32018-02-09 13:58:17 -08001919 if (!result.isOk() || !result) {
1920 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1921 }
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001922 return;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001923 }
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001924
1925 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001926}
1927
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001928static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1929 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1930 if (gnssHal != nullptr) {
1931 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001932 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001933 ALOGE("%s: Gnss injectLocation() failed", __func__);
1934 }
1935 }
1936}
1937
1938static jboolean android_location_GnssLocationProvider_supports_xtra(
1939 JNIEnv* /* env */, jobject /* obj */) {
1940 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1941}
1942
1943static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
1944 jbyteArray data, jint length) {
1945 if (gnssXtraIface == nullptr) {
1946 ALOGE("XTRA Interface not supported");
1947 return;
1948 }
1949
1950 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
1951 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
1952 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
1953}
1954
Anil Admalc70344b2018-11-16 14:22:38 -08001955struct AGnssDispatcher {
1956 static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType);
1957 static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle,
1958 jstring apn, jint apnIpType);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001959
Anil Admalc70344b2018-11-16 14:22:38 -08001960 template <class T>
1961 static void dataConnClosed(sp<T> agnssIface);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001962
Anil Admalc70344b2018-11-16 14:22:38 -08001963 template <class T>
1964 static void dataConnFailed(sp<T> agnssIface);
1965
1966 template <class T, class U>
1967 static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port);
1968
1969private:
1970 AGnssDispatcher() = delete;
1971 AGnssDispatcher(const AGnssDispatcher&) = delete;
1972 AGnssDispatcher& operator=(const AGnssDispatcher&) = delete;
1973};
1974
1975void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn,
1976 jint apnIpType) {
1977 ScopedJniString jniApn{env, apn};
1978 auto result = agnssIface->dataConnOpen(jniApn,
1979 static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001980 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001981 ALOGE("%s: Failed to set APN and its IP type", __func__);
1982 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001983}
1984
Anil Admalc70344b2018-11-16 14:22:38 -08001985void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
1986 jlong networkHandle, jstring apn, jint apnIpType) {
1987 ScopedJniString jniApn{env, apn};
1988 auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
1989 static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
1990 if (!result.isOk() || !result){
1991 ALOGE("%s: Failed to set APN and its IP type", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001992 }
Anil Admalc70344b2018-11-16 14:22:38 -08001993}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001994
Anil Admalc70344b2018-11-16 14:22:38 -08001995template<class T>
1996void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001997 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001998 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001999 ALOGE("%s: Failed to close AGnss data connection", __func__);
2000 }
2001}
2002
Anil Admalc70344b2018-11-16 14:22:38 -08002003template<class T>
2004void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002005 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002006 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002007 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
2008 }
2009}
2010
Anil Admalc70344b2018-11-16 14:22:38 -08002011template <class T, class U>
2012void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname,
2013 jint port) {
2014 ScopedJniString jniHostName{env, hostname};
2015 auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
2016 jniHostName, port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002017 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002018 ALOGE("%s: Failed to set AGnss host name and port", __func__);
2019 }
Anil Admalc70344b2018-11-16 14:22:38 -08002020}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002021
Anil Admalc70344b2018-11-16 14:22:38 -08002022static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
2023 JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
2024 if (apn == nullptr) {
2025 jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
2026 return;
2027 }
2028
2029 if (agnssIface_V2_0 != nullptr) {
2030 AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType);
2031 } else if (agnssIface != nullptr) {
2032 AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
2033 } else {
2034 ALOGE("%s: AGPS interface not supported", __func__);
2035 return;
2036 }
2037}
2038
2039static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
2040 jobject /* obj */) {
2041 if (agnssIface_V2_0 != nullptr) {
2042 AGnssDispatcher::dataConnClosed(agnssIface_V2_0);
2043 } else if (agnssIface != nullptr) {
2044 AGnssDispatcher::dataConnClosed(agnssIface);
2045 } else {
2046 ALOGE("%s: AGPS interface not supported", __func__);
2047 return;
2048 }
2049}
2050
2051static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
2052 jobject /* obj */) {
2053 if (agnssIface_V2_0 != nullptr) {
2054 AGnssDispatcher::dataConnFailed(agnssIface_V2_0);
2055 } else if (agnssIface != nullptr) {
2056 AGnssDispatcher::dataConnFailed(agnssIface);
2057 } else {
2058 ALOGE("%s: AGPS interface not supported", __func__);
2059 return;
2060 }
2061}
2062
2063static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
2064 jint type, jstring hostname, jint port) {
2065 if (agnssIface_V2_0 != nullptr) {
2066 AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type,
2067 hostname, port);
2068 } else if (agnssIface != nullptr) {
2069 AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
2070 hostname, port);
2071 } else {
2072 ALOGE("%s: AGPS interface not supported", __func__);
2073 return;
2074 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002075}
2076
2077static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
2078 jobject /* obj */, jint notifId, jint response) {
2079 if (gnssNiIface == nullptr) {
2080 ALOGE("no NI interface in send_ni_response");
2081 return;
2082 }
2083
2084 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
2085}
2086
2087static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
2088 jobject /* obj */) {
WyattRiley840c0b22018-10-31 09:03:53 -07002089 jstring result = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002090 /*
2091 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
2092 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07002093
2094 std::stringstream internalState;
2095
2096 if (gnssDebugIface == nullptr) {
2097 internalState << "Gnss Debug Interface not available" << std::endl;
2098 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002099 IGnssDebug::DebugData data;
2100 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
2101 data = debugData;
2102 });
2103
Wyatt Riley268c6e02017-03-29 10:21:46 -07002104 internalState << "Gnss Location Data:: ";
2105 if (!data.position.valid) {
2106 internalState << "not valid";
2107 } else {
2108 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002109 << ", LongitudeDegrees: " << data.position.longitudeDegrees
2110 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08002111 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
2112 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07002113 << ", horizontalAccuracyMeters: "
2114 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08002115 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07002116 << ", speedAccuracyMetersPerSecond: "
2117 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08002118 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07002119 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002120 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07002121 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002122
Wyatt Riley268c6e02017-03-29 10:21:46 -07002123 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
2124 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
2125 << ", frequencyUncertaintyNsPerSec: "
2126 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002127
2128 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07002129 internalState << "Satellite Data for " << data.satelliteDataArray.size()
2130 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002131 }
2132
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002133 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
2134 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
2135 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
2136 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002137 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002138 internalState << "constell: "
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002139 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002140 << ", svid: " << std::setw(3) << data.satelliteDataArray[i].svid
2141 << ", serverPredAvail: "
Wyatt Riley268c6e02017-03-29 10:21:46 -07002142 << data.satelliteDataArray[i].serverPredictionIsAvailable
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002143 << ", serverPredAgeSec: " << std::setw(7)
Wyatt Riley268c6e02017-03-29 10:21:46 -07002144 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002145 << ", ephType: "
2146 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
2147 << ", ephSource: "
2148 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
2149 << ", ephHealth: "
2150 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
2151 << ", ephAgeSec: " << std::setw(7)
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002152 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
2153 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002154 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07002155
2156 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002157 return result;
2158}
2159
Anil Admal94ec76a2019-01-15 09:42:01 -08002160static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported(
2161 JNIEnv* /* env */, jclass /* clazz */) {
2162 return (gnssVisibilityControlIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2163}
2164
Anil Admal50ba15e2018-11-01 16:42:42 -07002165static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002166 jobject /* obj */,
2167 jboolean connected,
2168 jint type,
2169 jboolean roaming,
2170 jboolean available,
Anil Admalb4995e22018-11-16 17:36:21 -08002171 jstring apn,
2172 jlong networkHandle,
2173 jshort capabilities) {
Anil Admalb4995e22018-11-16 17:36:21 -08002174 if (agnssRilIface_V2_0 != nullptr) {
Anil Admalc70344b2018-11-16 14:22:38 -08002175 ScopedJniString jniApn{env, apn};
Anil Admalb4995e22018-11-16 17:36:21 -08002176 IAGnssRil_V2_0::NetworkAttributes networkAttributes = {
2177 .networkHandle = static_cast<uint64_t>(networkHandle),
2178 .isConnected = static_cast<bool>(connected),
2179 .capabilities = static_cast<uint16_t>(capabilities),
Anil Admalc70344b2018-11-16 14:22:38 -08002180 .apn = jniApn
Anil Admalb4995e22018-11-16 17:36:21 -08002181 };
2182
2183 auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
2184 if (!result.isOk() || !result) {
2185 ALOGE("updateNetworkState_2_0 failed");
2186 }
Anil Admalc70344b2018-11-16 14:22:38 -08002187 } else if (agnssRilIface != nullptr) {
2188 ScopedJniString jniApn{env, apn};
2189 hidl_string hidlApn{jniApn};
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002190 auto result = agnssRilIface->updateNetworkState(connected,
Anil Admalb4995e22018-11-16 17:36:21 -08002191 static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002192 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002193 ALOGE("updateNetworkState failed");
2194 }
2195
Anil Admalc70344b2018-11-16 14:22:38 -08002196 if (!hidlApn.empty()) {
2197 result = agnssRilIface->updateNetworkAvailability(available, hidlApn);
Anil Admalb4995e22018-11-16 17:36:21 -08002198 if (!result.isOk() || !result) {
2199 ALOGE("updateNetworkAvailability failed");
2200 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002201 }
Anil Admalc70344b2018-11-16 14:22:38 -08002202 } else {
2203 ALOGE("AGnssRilInterface does not exist");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002204 }
2205}
2206
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002207static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002208 JNIEnv* /* env */, jobject /* obj */) {
2209 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2210}
2211
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002212static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002213 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
2214 jint last_transition, jint monitor_transition, jint notification_responsiveness,
2215 jint unknown_timer) {
2216 if (gnssGeofencingIface != nullptr) {
2217 auto result = gnssGeofencingIface->addGeofence(
2218 geofenceId, latitude, longitude, radius,
2219 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
2220 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002221 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002222 } else {
2223 ALOGE("Geofence Interface not available");
2224 }
2225 return JNI_FALSE;
2226}
2227
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002228static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002229 jobject /* obj */, jint geofenceId) {
2230 if (gnssGeofencingIface != nullptr) {
2231 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002232 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002233 } else {
2234 ALOGE("Geofence interface not available");
2235 }
2236 return JNI_FALSE;
2237}
2238
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002239static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002240 jobject /* obj */, jint geofenceId) {
2241 if (gnssGeofencingIface != nullptr) {
2242 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002243 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002244 } else {
2245 ALOGE("Geofence interface not available");
2246 }
2247 return JNI_FALSE;
2248}
2249
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002250static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002251 jobject /* obj */, jint geofenceId, jint monitor_transition) {
2252 if (gnssGeofencingIface != nullptr) {
2253 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002254 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002255 } else {
2256 ALOGE("Geofence interface not available");
2257 }
2258 return JNI_FALSE;
2259}
2260
Yu-Han Yang8de21502018-04-23 01:40:25 -07002261static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002262 JNIEnv* env, jclass clazz) {
2263 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07002264 return JNI_TRUE;
2265 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002266
destradaaea8a8a62014-06-23 18:19:03 -07002267 return JNI_FALSE;
2268}
2269
Yu-Han Yang8de21502018-04-23 01:40:25 -07002270static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08002271 JNIEnv* /* env */,
2272 jobject /* obj */,
2273 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002274 if (gnssMeasurementIface == nullptr) {
2275 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07002276 return JNI_FALSE;
2277 }
2278
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002279 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08002280 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
Yu-Han Yang88d79102018-11-14 14:20:57 -08002281 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
2282 if (gnssMeasurementIface_V2_0 != nullptr) {
2283 result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
2284 } else if (gnssMeasurementIface_V1_1 != nullptr) {
2285 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
gomo48f1a642017-11-10 20:35:46 -08002286 } else {
2287 if (enableFullTracking == JNI_TRUE) {
2288 // full tracking mode not supported in 1.0 HAL
2289 return JNI_FALSE;
2290 }
2291 result = gnssMeasurementIface->setCallback(cbIface);
2292 }
2293
2294 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002295 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
2296 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07002297 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002298 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002299 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07002300 }
2301
2302 return JNI_TRUE;
2303}
2304
Yu-Han Yang8de21502018-04-23 01:40:25 -07002305static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07002306 JNIEnv* env,
2307 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002308 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07002309 ALOGE("Measurement interface not available");
2310 return JNI_FALSE;
2311 }
2312
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002313 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08002314 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07002315}
2316
gomo226b7b72018-12-12 16:49:39 -08002317static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections(
2318 JNIEnv* env,
2319 jobject obj /* clazz*/,
2320 jobject correctionsObj) {
2321
2322 if (gnssCorrectionsIface == nullptr) {
2323 ALOGW("Trying to inject GNSS corrections on a chipset that does not support them.");
2324 return JNI_FALSE;
2325 }
2326 if (firstGnssMeasurementCorrectionInjected == false) {
2327 jclass measCorrClass = env->GetObjectClass(correctionsObj);
2328 method_correctionsGetLatitudeDegrees = env->GetMethodID(
2329 measCorrClass,"getLatitudeDegrees", "()D");
2330
2331 method_correctionsGetLongitudeDegrees = env->GetMethodID(
2332 measCorrClass, "getLongitudeDegrees", "()D");
2333
2334 method_correctionsGetAltitudeMeters = env->GetMethodID(
2335 measCorrClass, "getAltitudeMeters", "()D");
2336
gomo6ec95382019-01-26 03:08:18 -08002337 method_correctionsGetHorPosUncMeters = env->GetMethodID(
2338 measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
2339
2340 method_correctionsGetVerPosUncMeters = env->GetMethodID(
2341 measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
2342
gomo226b7b72018-12-12 16:49:39 -08002343 method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
2344 measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
2345
2346 method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
gomo3796ab12019-02-20 23:21:11 -08002347 measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava.util.List;");
gomo226b7b72018-12-12 16:49:39 -08002348 }
2349
2350 jdouble latitudeDegreesCorr = env->CallDoubleMethod(
2351 correctionsObj, method_correctionsGetLatitudeDegrees);
2352 jdouble longitudeDegreesCorr = env->CallDoubleMethod(
2353 correctionsObj, method_correctionsGetLongitudeDegrees);
2354 jdouble altitudeDegreesCorr = env->CallDoubleMethod(
2355 correctionsObj, method_correctionsGetAltitudeMeters);
gomo6ec95382019-01-26 03:08:18 -08002356 jdouble horizontalPositionUncertaintyMeters = env->CallDoubleMethod(
2357 correctionsObj, method_correctionsGetHorPosUncMeters);
2358 jdouble verticalPositionUncertaintyMeters = env->CallDoubleMethod(
2359 correctionsObj, method_correctionsGetVerPosUncMeters);
gomo226b7b72018-12-12 16:49:39 -08002360 jlong toaGpsNanosOfWeek = env->CallLongMethod(
2361 correctionsObj, method_correctionsGetToaGpsNanosecondsOfWeek);
2362 jobject singleSatCorrectionList = env->CallObjectMethod(correctionsObj,
2363 method_correctionsGetSingleSatCorrectionList);
2364
2365 if (firstGnssMeasurementCorrectionInjected == false) {
2366 jclass corrListClass = env->GetObjectClass(singleSatCorrectionList);
2367 method_listSize = env->GetMethodID(corrListClass, "size", "()I");
2368 method_correctionListGet = env->GetMethodID(
2369 corrListClass, "get", "(I)Landroid/location/GnssSingleSatCorrection;");
2370 }
2371
2372 auto len = (singleSatCorrectionList == nullptr)
2373 ? 0
2374 : env->CallIntMethod(singleSatCorrectionList, method_listSize);
2375 hidl_vec<SingleSatCorrection> list(len);
2376
2377 for (uint16_t i = 0; i < len; ++i) {
2378 jobject singleSatCorrectionObj = env->CallObjectMethod(
2379 singleSatCorrectionList, method_correctionListGet, i);
2380
2381 if (firstGnssMeasurementCorrectionInjected == false) {
2382 jclass singleSatCorrClass = env->GetObjectClass(singleSatCorrectionObj);
2383 method_correctionSatFlags = env->GetMethodID(
gomo3796ab12019-02-20 23:21:11 -08002384 singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
gomo226b7b72018-12-12 16:49:39 -08002385 method_correctionSatConstType = env->GetMethodID(
2386 singleSatCorrClass, "getConstellationType", "()I");
2387 method_correctionSatId= env->GetMethodID(
gomo3796ab12019-02-20 23:21:11 -08002388 singleSatCorrClass, "getSatelliteId", "()I");
gomo226b7b72018-12-12 16:49:39 -08002389 method_correctionSatCarrierFreq = env->GetMethodID(
2390 singleSatCorrClass, "getCarrierFrequencyHz", "()F");
gomob4635ba2019-01-17 04:02:53 -08002391 method_correctionSatIsLosProb = env->GetMethodID(
gomo3796ab12019-02-20 23:21:11 -08002392 singleSatCorrClass,"getProbabilityLineOfSight", "()F");
gomo226b7b72018-12-12 16:49:39 -08002393 method_correctionSatEpl = env->GetMethodID(
2394 singleSatCorrClass, "getExcessPathLengthMeters", "()F");
2395 method_correctionSatEplUnc = env->GetMethodID(
2396 singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
2397 method_correctionSatRefPlane = env->GetMethodID(
2398 singleSatCorrClass, "getReflectingPlane",
2399 "()Landroid/location/GnssReflectingPlane;");
2400 }
2401
2402 jint correctionFlags =
2403 env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags);
2404 jint constType = env->CallIntMethod(singleSatCorrectionObj,
2405 method_correctionSatConstType);
2406 jint satId =
2407 env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId);
2408 jfloat carrierFreqHz = env->CallFloatMethod(
2409 singleSatCorrectionObj, method_correctionSatCarrierFreq);
gomob4635ba2019-01-17 04:02:53 -08002410 jfloat probSatIsLos = env->CallFloatMethod(singleSatCorrectionObj,
2411 method_correctionSatIsLosProb);
gomo226b7b72018-12-12 16:49:39 -08002412 jfloat eplMeters =
2413 env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl);
2414 jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj,
2415 method_correctionSatEplUnc);
2416 jobject reflectingPlaneObj = env->CallObjectMethod(
2417 singleSatCorrectionObj, method_correctionSatRefPlane);
2418
2419 if (firstGnssMeasurementCorrectionInjected == false) {
2420 jclass refPlaneClass = env->GetObjectClass(reflectingPlaneObj);
2421 method_correctionPlaneLatDeg = env->GetMethodID(
2422 refPlaneClass, "getLatitudeDegrees", "()D");
2423 method_correctionPlaneLngDeg = env->GetMethodID(
2424 refPlaneClass, "getLongitudeDegrees", "()D");
2425 method_correctionPlaneAltDeg = env->GetMethodID(
2426 refPlaneClass, "getAltitudeMeters", "()D");
2427 method_correctionPlaneAzimDeg = env->GetMethodID(
2428 refPlaneClass, "getAzimuthDegrees", "()D");
2429 }
2430
2431 jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(
2432 reflectingPlaneObj, method_correctionPlaneLatDeg);
2433 jdouble longitudeDegreesRefPlane = env->CallDoubleMethod(
2434 reflectingPlaneObj, method_correctionPlaneLngDeg);
2435 jdouble altitudeDegreesRefPlane = env->CallDoubleMethod(
2436 reflectingPlaneObj, method_correctionPlaneAltDeg);
2437 jdouble azimuthDegreeRefPlane = env->CallDoubleMethod(
2438 reflectingPlaneObj, method_correctionPlaneAzimDeg);
2439 ReflectingPlane reflectingPlane = {
2440 .latitudeDegrees = latitudeDegreesRefPlane,
2441 .longitudeDegrees = longitudeDegreesRefPlane,
2442 .altitudeMeters = altitudeDegreesRefPlane,
2443 .azimuthDegrees = azimuthDegreeRefPlane,
2444 };
2445
2446 SingleSatCorrection singleSatCorrection = {
2447 .singleSatCorrectionFlags = static_cast<uint16_t>(correctionFlags),
2448 .constellation = static_cast<GnssConstellationType>(constType),
2449 .svid = static_cast<uint16_t>(satId),
2450 .carrierFrequencyHz = carrierFreqHz,
gomob4635ba2019-01-17 04:02:53 -08002451 .probSatIsLos = probSatIsLos,
gomo226b7b72018-12-12 16:49:39 -08002452 .excessPathLengthMeters = eplMeters,
2453 .excessPathLengthUncertaintyMeters = eplUncMeters,
2454 .reflectingPlane = reflectingPlane,
2455 };
2456 list[i] = singleSatCorrection;
2457 }
2458 MeasurementCorrections measurementCorrections = {
2459 .latitudeDegrees = latitudeDegreesCorr,
2460 .longitudeDegrees = longitudeDegreesCorr,
2461 .altitudeMeters = altitudeDegreesCorr,
gomo6ec95382019-01-26 03:08:18 -08002462 .horizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters,
2463 .verticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters,
gomo226b7b72018-12-12 16:49:39 -08002464 .toaGpsNanosecondsOfWeek = static_cast<uint64_t>(toaGpsNanosOfWeek),
2465 .satCorrections = list,
2466 };
2467
2468 gnssCorrectionsIface->setCorrections(measurementCorrections);
2469 firstGnssMeasurementCorrectionInjected = true;
2470 return JNI_TRUE;
2471}
2472
Yu-Han Yang23d92162018-04-19 06:03:00 -07002473static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07002474 JNIEnv* env,
2475 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002476 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002477 return JNI_TRUE;
2478 }
2479 return JNI_FALSE;
2480}
2481
Yu-Han Yang23d92162018-04-19 06:03:00 -07002482static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07002483 JNIEnv* env,
2484 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002485 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002486 ALOGE("Navigation Message interface is not available.");
2487 return JNI_FALSE;
2488 }
2489
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002490 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
2491 new GnssNavigationMessageCallback();
2492 IGnssNavigationMessage::GnssNavigationMessageStatus result =
2493 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
2494
2495 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
2496 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07002497 return JNI_FALSE;
2498 }
2499
2500 return JNI_TRUE;
2501}
2502
Yu-Han Yang23d92162018-04-19 06:03:00 -07002503static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07002504 JNIEnv* env,
2505 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002506 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002507 ALOGE("Navigation Message interface is not available.");
2508 return JNI_FALSE;
2509 }
2510
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002511 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08002512 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07002513}
2514
Anil Admald71cf142018-12-21 14:59:36 -08002515static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,
2516 jobject,
2517 jint emergencySuplPdn) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002518 if (gnssConfigurationIface == nullptr) {
2519 ALOGE("no GNSS configuration interface available");
2520 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002521 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002522
2523 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002524 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002525 return result;
2526 } else {
2527 return JNI_FALSE;
2528 }
2529}
2530
Anil Admald71cf142018-12-21 14:59:36 -08002531static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002532 jobject,
2533 jint version) {
2534 if (gnssConfigurationIface == nullptr) {
2535 ALOGE("no GNSS configuration interface available");
2536 return JNI_FALSE;
2537 }
2538 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002539 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002540 return result;
2541 } else {
2542 return JNI_FALSE;
2543 }
2544}
2545
Anil Admald71cf142018-12-21 14:59:36 -08002546static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*,
2547 jobject,
2548 jint suplEs) {
2549 if (gnssConfigurationIface_V2_0 != nullptr) {
2550 ALOGI("Config parameter SUPL_ES is deprecated in IGnssConfiguration.hal version 2.0.");
2551 return JNI_FALSE;
2552 }
2553
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002554 if (gnssConfigurationIface == nullptr) {
2555 ALOGE("no GNSS configuration interface available");
2556 return JNI_FALSE;
2557 }
2558
2559 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002560 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002561 return result;
2562 } else {
2563 return JNI_FALSE;
2564 }
2565}
2566
Anil Admald71cf142018-12-21 14:59:36 -08002567static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*,
2568 jobject,
2569 jint mode) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002570 if (gnssConfigurationIface == nullptr) {
2571 ALOGE("no GNSS configuration interface available");
2572 return JNI_FALSE;
2573 }
2574
2575 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002576 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002577 return result;
2578 } else {
2579 return JNI_FALSE;
2580 }
2581}
2582
Anil Admald71cf142018-12-21 14:59:36 -08002583static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*,
2584 jobject,
2585 jint gpsLock) {
2586 if (gnssConfigurationIface_V2_0 != nullptr) {
2587 ALOGI("Config parameter GPS_LOCK is deprecated in IGnssConfiguration.hal version 2.0.");
2588 return JNI_FALSE;
2589 }
2590
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002591 if (gnssConfigurationIface == nullptr) {
2592 ALOGE("no GNSS configuration interface available");
2593 return JNI_FALSE;
2594 }
2595
2596 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002597 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002598 return result;
2599 } else {
2600 return JNI_FALSE;
2601 }
2602}
2603
Anil Admald71cf142018-12-21 14:59:36 -08002604static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002605 jobject,
2606 jint lppProfile) {
2607 if (gnssConfigurationIface == nullptr) {
2608 ALOGE("no GNSS configuration interface available");
2609 return JNI_FALSE;
2610 }
2611
2612 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
2613
Steven Morelandd002a8b2017-01-03 17:18:24 -08002614 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002615 return result;
2616 } else {
2617 return JNI_FALSE;
2618 }
2619}
2620
Anil Admald71cf142018-12-21 14:59:36 -08002621static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*,
2622 jobject,
2623 jint gnssPosProtocol) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002624 if (gnssConfigurationIface == nullptr) {
2625 ALOGE("no GNSS configuration interface available");
2626 return JNI_FALSE;
2627 }
2628
2629 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002630 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002631 return result;
2632 } else {
2633 return JNI_FALSE;
2634 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002635}
2636
Anil Admald71cf142018-12-21 14:59:36 -08002637static jboolean android_location_GnssConfiguration_set_satellite_blacklist(
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002638 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2639 if (gnssConfigurationIface_V1_1 == nullptr) {
2640 ALOGI("No GNSS Satellite Blacklist interface available");
2641 return JNI_FALSE;
2642 }
2643
2644 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002645 if (nullptr == constellation_array) {
2646 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002647 return JNI_FALSE;
2648 }
2649 jsize length = env->GetArrayLength(constellations);
2650
2651 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002652 if (nullptr == sv_id_array) {
2653 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002654 return JNI_FALSE;
2655 }
2656
2657 if (length != env->GetArrayLength(sv_ids)) {
2658 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2659 return JNI_FALSE;
2660 }
2661
2662 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2663 sources.resize(length);
2664
2665 for (int i = 0; i < length; i++) {
2666 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2667 sources[i].svid = sv_id_array[i];
2668 }
2669
2670 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2671 if (result.isOk()) {
2672 return result;
2673 } else {
2674 return JNI_FALSE;
2675 }
2676}
2677
Anil Admald71cf142018-12-21 14:59:36 -08002678static jboolean android_location_GnssConfiguration_set_es_extension_sec(
2679 JNIEnv*, jobject, jint emergencyExtensionSeconds) {
2680 if (gnssConfigurationIface == nullptr) {
2681 ALOGE("no GNSS configuration interface available");
2682 return JNI_FALSE;
2683 }
2684
2685 if (gnssConfigurationIface_V2_0 == nullptr) {
2686 ALOGI("Config parameter ES_EXTENSION_SEC is not supported in IGnssConfiguration.hal"
2687 " versions earlier than 2.0.");
2688 return JNI_FALSE;
2689 }
2690
2691 auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds);
2692 if (result.isOk()) {
2693 return result;
2694 } else {
2695 return JNI_FALSE;
2696 }
2697}
2698
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002699static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002700 if (gnssBatchingIface == nullptr) {
2701 return 0; // batching not supported, size = 0
2702 }
2703 auto result = gnssBatchingIface->getBatchSize();
2704 if (result.isOk()) {
2705 return static_cast<jint>(result);
2706 } else {
2707 return 0; // failure in binder, don't support batching
2708 }
2709}
2710
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002711static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002712 if (gnssBatchingIface == nullptr) {
2713 return JNI_FALSE; // batching not supported
2714 }
2715 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2716
2717 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2718}
2719
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002720static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002721 if (gnssBatchingIface == nullptr) {
2722 return; // batching not supported
2723 }
2724 gnssBatchingIface->cleanup();
2725}
2726
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002727static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002728 jlong periodNanos, jboolean wakeOnFifoFull) {
2729 if (gnssBatchingIface == nullptr) {
2730 return JNI_FALSE; // batching not supported
2731 }
2732
2733 IGnssBatching::Options options;
2734 options.periodNanos = periodNanos;
2735 if (wakeOnFifoFull) {
2736 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2737 } else {
2738 options.flags = 0;
2739 }
2740
2741 return static_cast<jboolean>(gnssBatchingIface->start(options));
2742}
2743
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002744static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002745 if (gnssBatchingIface == nullptr) {
2746 return; // batching not supported
2747 }
2748
2749 gnssBatchingIface->flush();
2750}
2751
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002752static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002753 if (gnssBatchingIface == nullptr) {
2754 return JNI_FALSE; // batching not supported
2755 }
2756
2757 return gnssBatchingIface->stop();
2758}
2759
Anil Admal94ec76a2019-01-15 09:42:01 -08002760static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
2761 JNIEnv* env, jobject, jobjectArray proxyApps) {
2762 if (gnssVisibilityControlIface == nullptr) {
2763 ALOGI("No GNSS Visibility Control interface available");
2764 return JNI_FALSE;
2765 }
2766
2767 const jsize length = env->GetArrayLength(proxyApps);
2768 hidl_vec<hidl_string> hidlProxyApps(length);
2769 for (int i = 0; i < length; ++i) {
2770 jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i));
2771 ScopedJniString jniProxyApp(env, proxyApp);
2772 hidlProxyApps[i] = jniProxyApp;
2773 }
2774
2775 auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
2776 if (result.isOk()) {
2777 return result;
2778 } else {
2779 return JNI_FALSE;
2780 }
2781}
2782
Daniel Micay76f6a862015-09-19 17:31:01 -04002783static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002785 {"class_init_native", "()V", reinterpret_cast<void *>(
2786 android_location_GnssLocationProvider_class_init_native)},
2787 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2788 android_location_GnssLocationProvider_is_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002789 {"native_init_once", "()V", reinterpret_cast<void *>(
2790 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002791 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2792 {"native_cleanup", "()V", reinterpret_cast<void *>(
2793 android_location_GnssLocationProvider_cleanup)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002794 {"native_set_position_mode", "(IIIIIZ)Z", reinterpret_cast<void *>(
2795 android_location_GnssLocationProvider_set_position_mode)},
2796 {"native_start", "()Z", reinterpret_cast<void *>(
2797 android_location_GnssLocationProvider_start)},
2798 {"native_stop", "()Z", reinterpret_cast<void *>(
2799 android_location_GnssLocationProvider_stop)},
2800 {"native_delete_aiding_data", "(I)V", reinterpret_cast<void *>(
2801 android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002802 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2803 android_location_GnssLocationProvider_read_nmea)},
2804 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2805 android_location_GnssLocationProvider_inject_time)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002806 {"native_inject_best_location", "(IDDDFFFFFFJIJ)V", reinterpret_cast<void *>(
2807 android_location_GnssLocationProvider_inject_best_location)},
2808 {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
2809 android_location_GnssLocationProvider_inject_location)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002810 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2811 android_location_GnssLocationProvider_supports_xtra)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002812 {"native_inject_xtra_data", "([BI)V", reinterpret_cast<void *>(
2813 android_location_GnssLocationProvider_inject_xtra_data)},
2814 {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void *>(
2815 android_location_GnssLocationProvider_agps_set_id)},
2816 {"native_agps_set_ref_location_cellid", "(IIIII)V", reinterpret_cast<void *>(
2817 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
2818 {"native_set_agps_server", "(ILjava/lang/String;I)V", reinterpret_cast<void *>(
2819 android_location_GnssLocationProvider_set_agps_server)},
2820 {"native_send_ni_response", "(II)V", reinterpret_cast<void *>(
2821 android_location_GnssLocationProvider_send_ni_response)},
2822 {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(
2823 android_location_GnssLocationProvider_get_internal_state)},
Anil Admal94ec76a2019-01-15 09:42:01 -08002824 {"native_is_gnss_visibility_control_supported", "()Z", reinterpret_cast<void *>(
2825 android_location_GnssLocationProvider_is_gnss_visibility_control_supported)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002826};
2827
2828static const JNINativeMethod sMethodsBatching[] = {
2829 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002830 {"native_get_batch_size",
2831 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002832 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002833 {"native_start_batch",
2834 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002835 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002836 {"native_flush_batch",
2837 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002838 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002839 {"native_stop_batch",
2840 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002841 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002842 {"native_init_batching",
2843 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002844 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002845 {"native_cleanup_batching",
2846 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002847 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002848};
2849
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002850static const JNINativeMethod sGeofenceMethods[] = {
2851 /* name, signature, funcPtr */
2852 {"native_is_geofence_supported",
2853 "()Z",
2854 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2855 {"native_add_geofence",
2856 "(IDDDIIII)Z",
2857 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2858 {"native_remove_geofence",
2859 "(I)Z",
2860 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2861 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2862 android_location_GnssGeofenceProvider_pause_geofence)},
2863 {"native_resume_geofence",
2864 "(II)Z",
2865 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2866};
2867
Yu-Han Yang8de21502018-04-23 01:40:25 -07002868static const JNINativeMethod sMeasurementMethods[] = {
gomo226b7b72018-12-12 16:49:39 -08002869 /* name, signature, funcPtr */
2870 {"native_is_measurement_supported", "()Z",
2871 reinterpret_cast<void*>(
2872 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2873 {"native_start_measurement_collection", "(Z)Z",
2874 reinterpret_cast<void*>(
2875 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2876 {"native_stop_measurement_collection", "()Z",
2877 reinterpret_cast<void*>(
2878 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2879 {"native_inject_gnss_measurement_corrections",
2880 "(Landroid/location/GnssMeasurementCorrections;)Z",
2881 reinterpret_cast<void*>(
2882 android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections)},
Yu-Han Yang8de21502018-04-23 01:40:25 -07002883};
2884
Yu-Han Yang23d92162018-04-19 06:03:00 -07002885static const JNINativeMethod sNavigationMessageMethods[] = {
2886 /* name, signature, funcPtr */
2887 {"native_is_navigation_message_supported",
2888 "()Z",
2889 reinterpret_cast<void *>(
2890 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2891 {"native_start_navigation_message_collection",
2892 "()Z",
2893 reinterpret_cast<void *>(
2894 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2895 {"native_stop_navigation_message_collection",
2896 "()Z",
2897 reinterpret_cast<void *>(
2898 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2899};
2900
Anil Admal50ba15e2018-11-01 16:42:42 -07002901static const JNINativeMethod sNetworkConnectivityMethods[] = {
2902 /* name, signature, funcPtr */
2903 {"native_is_agps_ril_supported", "()Z",
2904 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
2905 {"native_update_network_state",
Anil Admalb4995e22018-11-16 17:36:21 -08002906 "(ZIZZLjava/lang/String;JS)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07002907 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
2908 {"native_agps_data_conn_open",
Anil Admalc70344b2018-11-16 14:22:38 -08002909 "(JLjava/lang/String;I)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07002910 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
2911 {"native_agps_data_conn_closed",
2912 "()V",
2913 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
2914 {"native_agps_data_conn_failed",
2915 "()V",
2916 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
2917};
2918
Anil Admald71cf142018-12-21 14:59:36 -08002919static const JNINativeMethod sConfigurationMethods[] = {
2920 /* name, signature, funcPtr */
2921 {"native_get_gnss_configuration_version",
2922 "()Lcom/android/server/location/GnssConfiguration$HalInterfaceVersion;",
2923 reinterpret_cast<void *>(
2924 android_location_GnssConfiguration_get_gnss_configuration_version)},
2925 {"native_set_supl_es",
2926 "(I)Z",
2927 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_es)},
2928 {"native_set_supl_version",
2929 "(I)Z",
2930 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_version)},
2931 {"native_set_supl_mode",
2932 "(I)Z",
2933 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_mode)},
2934 {"native_set_lpp_profile",
2935 "(I)Z",
2936 reinterpret_cast<void *>(android_location_GnssConfiguration_set_lpp_profile)},
2937 {"native_set_gnss_pos_protocol_select",
2938 "(I)Z",
2939 reinterpret_cast<void *>(
2940 android_location_GnssConfiguration_set_gnss_pos_protocol_select)},
2941 {"native_set_gps_lock",
2942 "(I)Z",
2943 reinterpret_cast<void *>(android_location_GnssConfiguration_set_gps_lock)},
2944 {"native_set_emergency_supl_pdn",
2945 "(I)Z",
2946 reinterpret_cast<void *>(android_location_GnssConfiguration_set_emergency_supl_pdn)},
2947 {"native_set_satellite_blacklist",
2948 "([I[I)Z",
2949 reinterpret_cast<void *>(android_location_GnssConfiguration_set_satellite_blacklist)},
2950 {"native_set_es_extension_sec",
2951 "(I)Z",
2952 reinterpret_cast<void *>(android_location_GnssConfiguration_set_es_extension_sec)},
2953};
2954
Anil Admal94ec76a2019-01-15 09:42:01 -08002955static const JNINativeMethod sVisibilityControlMethods[] = {
2956 /* name, signature, funcPtr */
2957 {"native_enable_nfw_location_access",
2958 "([Ljava/lang/String;)Z",
2959 reinterpret_cast<void *>(
2960 android_location_GnssVisibilityControl_enable_nfw_location_access)},
2961};
2962
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002963int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002964 jniRegisterNativeMethods(
2965 env,
2966 "com/android/server/location/GnssBatchingProvider",
2967 sMethodsBatching,
2968 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002969 jniRegisterNativeMethods(
2970 env,
2971 "com/android/server/location/GnssGeofenceProvider",
2972 sGeofenceMethods,
2973 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002974 jniRegisterNativeMethods(
2975 env,
2976 "com/android/server/location/GnssMeasurementsProvider",
2977 sMeasurementMethods,
2978 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002979 jniRegisterNativeMethods(
2980 env,
2981 "com/android/server/location/GnssNavigationMessageProvider",
2982 sNavigationMessageMethods,
2983 NELEM(sNavigationMessageMethods));
Anil Admal50ba15e2018-11-01 16:42:42 -07002984 jniRegisterNativeMethods(
2985 env,
2986 "com/android/server/location/GnssNetworkConnectivityHandler",
2987 sNetworkConnectivityMethods,
2988 NELEM(sNetworkConnectivityMethods));
Anil Admald71cf142018-12-21 14:59:36 -08002989 jniRegisterNativeMethods(
2990 env,
2991 "com/android/server/location/GnssConfiguration",
2992 sConfigurationMethods,
2993 NELEM(sConfigurationMethods));
Anil Admal94ec76a2019-01-15 09:42:01 -08002994 jniRegisterNativeMethods(
2995 env,
2996 "com/android/server/location/GnssVisibilityControl",
2997 sVisibilityControlMethods,
2998 NELEM(sVisibilityControlMethods));
destradaaea8a8a62014-06-23 18:19:03 -07002999 return jniRegisterNativeMethods(
3000 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08003001 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07003002 sMethods,
3003 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004}
3005
3006} /* namespace android */