blob: bce3e98c7baa4b29a74ebc64046bc5e578a93bd2 [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;
gomo5716ab82019-02-27 22:57:56 -0800163using GnssSingleSatCorrectionFlags =
164 android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
gomo226b7b72018-12-12 16:49:39 -0800165
Anil Admal94ec76a2019-01-15 09:42:01 -0800166using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
167using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
168
gomo25208882017-04-15 02:05:25 -0700169struct GnssDeathRecipient : virtual public hidl_death_recipient
170{
171 // hidl_death_recipient interface
172 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700173 ALOGE("IGNSS hidl service failed, trying to recover...");
174
175 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
176 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700177 }
178};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700179
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800180// Must match the value from GnssMeasurement.java
181static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
182
gomo25208882017-04-15 02:05:25 -0700183sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800184sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800185sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800186sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700187sp<IGnssXtra> gnssXtraIface = nullptr;
Anil Admalb4995e22018-11-16 17:36:21 -0800188sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
189sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700190sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
Anil Admalc70344b2018-11-16 14:22:38 -0800191sp<IAGnss_V1_0> agnssIface = nullptr;
192sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800193sp<IGnssBatching> gnssBatchingIface = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700194sp<IGnssDebug> gnssDebugIface = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700195sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
196sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Anil Admald71cf142018-12-21 14:59:36 -0800197sp<IGnssConfiguration_V2_0> gnssConfigurationIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700198sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800199sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
200sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800201sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700202sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
gomo226b7b72018-12-12 16:49:39 -0800203sp<IMeasurementCorrections> gnssCorrectionsIface = nullptr;
gomo5716ab82019-02-27 22:57:56 -0800204
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
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000494 if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
495 SET(ElapsedRealtimeUncertaintyNanos, location.elapsedRealtime.timeUncertaintyNs);
496 }
497
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800498 return object.get();
499}
500
501static GnssLocation_V1_0 createGnssLocation_V1_0(
502 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
503 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
504 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
505 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
Yu-Han Yange7baef32018-02-09 13:58:17 -0800506 jlong timestamp) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800507 GnssLocation_V1_0 location;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800508 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
509 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
510 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
511 location.altitudeMeters = static_cast<double>(altitudeMeters);
512 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
513 location.bearingDegrees = static_cast<float>(bearingDegrees);
514 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
515 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
516 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
517 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
518 location.timestamp = static_cast<uint64_t>(timestamp);
519
520 return location;
521}
522
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800523static GnssLocation_V2_0 createGnssLocation_V2_0(
524 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
525 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
526 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
527 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000528 jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
529 jlong elapsedRealtimeUncertaintyNanos) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800530 GnssLocation_V2_0 location;
531 location.v1_0 = createGnssLocation_V1_0(
532 gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
533 speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
534 verticalAccuracyMeters, speedAccuracyMetersPerSecond,
535 bearingAccuracyDegrees, timestamp);
536
537 location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
538 location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000539 location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800540
541 return location;
542}
543
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700544/*
545 * GnssCallback class implements the callback methods for IGnss interface.
546 */
547struct GnssCallback : public IGnssCallback {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800548 Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700549 Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
550 Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
551 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
552 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
553 Return<void> gnssAcquireWakelockCb() override;
554 Return<void> gnssReleaseWakelockCb() override;
555 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800556 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800557
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700558 Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800559
Wyatt Rileyfb840922017-11-08 15:07:58 -0800560 // New in 1.1
561 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
562
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800563 // New in 2.0
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800564 Return<void> gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool isUserEmergency)
565 override;
gomo226b7b72018-12-12 16:49:39 -0800566 Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800567 Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;
568
569 // Templated implementation for gnnsLocationCb and gnnsLocationCb_2_0.
570 template <class T>
571 Return<void> gnssLocationCbImpl(const T& location);
gomo226b7b72018-12-12 16:49:39 -0800572
Wyatt Riley26465d22018-02-12 13:44:24 -0800573 // TODO(b/73306084): Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700574 static const char* sNmeaString;
575 static size_t sNmeaStringLength;
576};
577
Wyatt Rileyfb840922017-11-08 15:07:58 -0800578Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
579 ALOGD("%s: name=%s\n", __func__, name.c_str());
580
Wyatt Rileyfb840922017-11-08 15:07:58 -0800581 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800582 jstring jstringName = env->NewStringUTF(name.c_str());
583 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800584 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800585
Wyatt Rileyfb840922017-11-08 15:07:58 -0800586 return Void();
587}
588
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700589const char* GnssCallback::sNmeaString = nullptr;
590size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700591
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800592template<class T>
593Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800594 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800595
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800596 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800597
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700598 env->CallVoidMethod(mCallbacksObj,
599 method_reportLocation,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800600 boolToJbool(hasLatLong(location)),
Wyatt Riley5d229832017-02-10 17:06:00 -0800601 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700602 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800603 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700604 return Void();
605}
606
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800607Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
608 return gnssLocationCbImpl<GnssLocation_V1_0>(location);
609}
610
611Return<void>
612GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
613 return gnssLocationCbImpl<GnssLocation_V2_0>(location);
614}
615
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700616Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800617 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700618 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
619 checkAndClearExceptionFromCallback(env, __FUNCTION__);
620 return Void();
621}
622
623Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800624 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700625
Wyatt Riley26465d22018-02-12 13:44:24 -0800626 uint32_t listSize = svStatus.numSvs;
627 if (listSize > static_cast<uint32_t>(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700628 android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800629 ALOGD("Too many satellites %u. Clamps to %u.", listSize,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700630 static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
Wyatt Riley26465d22018-02-12 13:44:24 -0800631 listSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
Lifu Tang38bce792016-02-24 17:17:38 -0800632 }
633
Wyatt Riley26465d22018-02-12 13:44:24 -0800634 jintArray svidWithFlagArray = env->NewIntArray(listSize);
635 jfloatArray cn0Array = env->NewFloatArray(listSize);
636 jfloatArray elevArray = env->NewFloatArray(listSize);
637 jfloatArray azimArray = env->NewFloatArray(listSize);
638 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
639
640 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
641 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
642 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
643 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
644 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
645
646 /*
647 * Read GNSS SV info.
648 */
649 for (size_t i = 0; i < listSize; ++i) {
650 enum ShiftWidth: uint8_t {
651 SVID_SHIFT_WIDTH = 8,
652 CONSTELLATION_TYPE_SHIFT_WIDTH = 4
653 };
654
655 const IGnssCallback::GnssSvInfo& info = svStatus.gnssSvList.data()[i];
656 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
657 (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
658 static_cast<uint32_t>(info.svFlag);
659 cn0s[i] = info.cN0Dbhz;
660 elev[i] = info.elevationDegrees;
661 azim[i] = info.azimuthDegrees;
662 carrierFreq[i] = info.carrierFrequencyHz;
Lifu Tang9363b942016-02-16 18:07:00 -0800663 }
destradaaea8a8a62014-06-23 18:19:03 -0700664
Wyatt Riley26465d22018-02-12 13:44:24 -0800665 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
666 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
667 env->ReleaseFloatArrayElements(elevArray, elev, 0);
668 env->ReleaseFloatArrayElements(azimArray, azim, 0);
669 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
670
671 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
672 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
673 carrierFreqArray);
674
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700675 checkAndClearExceptionFromCallback(env, __FUNCTION__);
676 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700677}
678
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700679Return<void> GnssCallback::gnssNmeaCb(
680 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800681 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700682 /*
683 * The Java code will call back to read these values.
684 * We do this to avoid creating unnecessary String objects.
685 */
686 sNmeaString = nmea.c_str();
687 sNmeaStringLength = nmea.size();
688
689 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
690 checkAndClearExceptionFromCallback(env, __FUNCTION__);
691 return Void();
692}
693
694Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
695 ALOGD("%s: %du\n", __func__, capabilities);
696
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800697 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698 env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
699 checkAndClearExceptionFromCallback(env, __FUNCTION__);
700 return Void();
701}
702
gomo226b7b72018-12-12 16:49:39 -0800703Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
704 return GnssCallback::gnssSetCapabilitesCb(capabilities);
705}
706
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700707Return<void> GnssCallback::gnssAcquireWakelockCb() {
708 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
709 return Void();
710}
711
712Return<void> GnssCallback::gnssReleaseWakelockCb() {
713 release_wake_lock(WAKE_LOCK_NAME);
714 return Void();
715}
716
717Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800718 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700719 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
720 checkAndClearExceptionFromCallback(env, __FUNCTION__);
721 return Void();
722}
723
Yu-Han Yang21988932018-01-23 15:07:37 -0800724Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800725 return GnssCallback::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */
726 false);
727}
728
729Return<void> GnssCallback::gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool
730 isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800731 JNIEnv* env = getJniEnv();
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800732 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
733 boolToJbool(isUserEmergency));
Yu-Han Yange7baef32018-02-09 13:58:17 -0800734 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800735 return Void();
736}
737
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700738Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
739 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
740
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800741 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700742 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
743 info.yearOfHw);
744 checkAndClearExceptionFromCallback(env, __FUNCTION__);
745 return Void();
746}
747
748class GnssXtraCallback : public IGnssXtraCallback {
749 Return<void> downloadRequestCb() override;
750};
751
752/*
753 * GnssXtraCallback class implements the callback methods for the IGnssXtra
754 * interface.
755 */
756Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800757 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700758 env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
759 checkAndClearExceptionFromCallback(env, __FUNCTION__);
760 return Void();
761}
762
763/*
764 * GnssGeofenceCallback class implements the callback methods for the
765 * IGnssGeofence interface.
766 */
767struct GnssGeofenceCallback : public IGnssGeofenceCallback {
768 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
769 Return<void> gnssGeofenceTransitionCb(
770 int32_t geofenceId,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800771 const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700772 GeofenceTransition transition,
773 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800774 Return<void>
775 gnssGeofenceStatusCb(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700776 GeofenceAvailability status,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800777 const GnssLocation_V1_0& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700778 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
779 GeofenceStatus status) override;
780 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
781 GeofenceStatus status) override;
782 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
783 GeofenceStatus status) override;
784 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
785 GeofenceStatus status) override;
786};
787
788Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800789 int32_t geofenceId, const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700790 GeofenceTransition transition,
791 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800792 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700793
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800794 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800795
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700796 env->CallVoidMethod(mCallbacksObj,
797 method_reportGeofenceTransition,
798 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800799 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700800 transition,
801 timestamp);
802
803 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800804 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700805 return Void();
806}
807
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800808Return<void>
809GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability status,
810 const GnssLocation_V1_0& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800811 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800812
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800813 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800814
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800815 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800816 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700817 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800818 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700819 return Void();
820}
821
822Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
823 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800824 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700825 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
826 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
827 }
828
829 env->CallVoidMethod(mCallbacksObj,
830 method_reportGeofenceAddStatus,
831 geofenceId,
832 status);
833 checkAndClearExceptionFromCallback(env, __FUNCTION__);
834 return Void();
835}
836
837Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
838 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800839 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700840 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
841 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
842 }
843
844 env->CallVoidMethod(mCallbacksObj,
845 method_reportGeofenceRemoveStatus,
846 geofenceId, status);
847 checkAndClearExceptionFromCallback(env, __FUNCTION__);
848 return Void();
849}
850
851Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
852 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800853 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700854 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
855 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
856 }
857
858 env->CallVoidMethod(mCallbacksObj,
859 method_reportGeofencePauseStatus,
860 geofenceId, status);
861 checkAndClearExceptionFromCallback(env, __FUNCTION__);
862 return Void();
863}
864
865Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
866 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800867 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700868 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
869 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
870 }
871
872 env->CallVoidMethod(mCallbacksObj,
873 method_reportGeofenceResumeStatus,
874 geofenceId, status);
875 checkAndClearExceptionFromCallback(env, __FUNCTION__);
876 return Void();
877}
878
879/*
880 * GnssNavigationMessageCallback interface implements the callback methods
881 * required by the IGnssNavigationMessage interface.
882 */
883struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
884 /*
885 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
886 * follow.
887 */
888 Return<void> gnssNavigationMessageCb(
889 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
890};
891
892Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
893 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800894 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700895
896 size_t dataLength = message.data.size();
897
898 std::vector<uint8_t> navigationData = message.data;
899 uint8_t* data = &(navigationData[0]);
WyattRiley840c0b22018-10-31 09:03:53 -0700900 if (dataLength == 0 || data == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700901 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
902 dataLength);
903 return Void();
904 }
905
906 JavaObject object(env, "android/location/GnssNavigationMessage");
907 SET(Type, static_cast<int32_t>(message.type));
908 SET(Svid, static_cast<int32_t>(message.svid));
909 SET(MessageId, static_cast<int32_t>(message.messageId));
910 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
911 object.callSetter("setData", data, dataLength);
912 SET(Status, static_cast<int32_t>(message.status));
913
914 jobject navigationMessage = object.get();
915 env->CallVoidMethod(mCallbacksObj,
916 method_reportNavigationMessages,
917 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -0800918 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700919 env->DeleteLocalRef(navigationMessage);
920 return Void();
921}
922
923/*
924 * GnssMeasurementCallback implements the callback methods required for the
925 * GnssMeasurement interface.
926 */
Yu-Han Yang88d79102018-11-14 14:20:57 -0800927struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 {
928 Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData& data)
929 override;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800930 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800931 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700932 private:
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800933 template<class T>
934 void translateSingleGnssMeasurement(const T* measurement, JavaObject& object);
935
936 template<class T>
937 jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
938
939 template<class T>
940 void translateAndSetGnssData(const T& data);
941
942 template<class T>
943 size_t getMeasurementCount(const T& data);
944
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800945 jobject translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800946 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700947 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
948};
949
Yu-Han Yang88d79102018-11-14 14:20:57 -0800950Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_0(
951 const IGnssMeasurementCallback_V2_0::GnssData& data) {
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -0800952 translateAndSetGnssData(data);
Yu-Han Yang88d79102018-11-14 14:20:57 -0800953 return Void();
954}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700955
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800956Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -0800957 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800958 translateAndSetGnssData(data);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700959 return Void();
960}
961
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800962Return<void> GnssMeasurementCallback::GnssMeasurementCb(
963 const IGnssMeasurementCallback_V1_0::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800964 translateAndSetGnssData(data);
965 return Void();
966}
967
968template<class T>
969void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800970 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -0800971
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800972 jobject clock;
973 jobjectArray measurementArray;
974
975 clock = translateGnssClock(env, &data.clock);
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800976 size_t count = getMeasurementCount(data);
977 measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800978 setMeasurementData(env, clock, measurementArray);
979
980 env->DeleteLocalRef(clock);
981 env->DeleteLocalRef(measurementArray);
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800982}
983
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800984template<>
985size_t GnssMeasurementCallback::getMeasurementCount<IGnssMeasurementCallback_V1_0::GnssData>
986 (const IGnssMeasurementCallback_V1_0::GnssData& data) {
987 return data.measurementCount;
988}
989
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -0800990template<class T>
991size_t GnssMeasurementCallback::getMeasurementCount(const T& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -0800992 return data.measurements.size();
993}
994
995// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
996template<>
997void GnssMeasurementCallback::translateSingleGnssMeasurement
998 <IGnssMeasurementCallback_V1_0::GnssMeasurement>(
WyattRiley840c0b22018-10-31 09:03:53 -0700999 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -08001000 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001001 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -07001002
1003 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -08001004 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001005 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -08001006 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001007 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -08001008 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001009 measurement->receivedSvTimeUncertaintyInNs);
1010 SET(Cn0DbHz, measurement->cN0DbHz);
1011 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -08001012 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001013 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -08001014 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -08001015 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
WyattRiley948dd6d2018-10-31 06:56:09 -07001016 ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001017 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -08001018 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001019 measurement->accumulatedDeltaRangeUncertaintyM);
1020
1021 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
1022 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
1023 }
1024
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001025 // Intentionally not copying deprecated fields of carrierCycles,
1026 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001027
1028 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
1029
1030 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
1031 SET(SnrInDb, measurement->snrDb);
1032 }
Lifu Tang120480f2016-02-07 18:08:19 -08001033
gomo4402af62017-01-11 13:20:13 -08001034 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -08001035 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -08001036 }
Lifu Tang120480f2016-02-07 18:08:19 -08001037}
1038
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001039// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1040template<>
1041void GnssMeasurementCallback::translateSingleGnssMeasurement
1042 <IGnssMeasurementCallback_V1_1::GnssMeasurement>(
1043 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurement_V1_1,
1044 JavaObject& object) {
1045 translateSingleGnssMeasurement(&(measurement_V1_1->v1_0), object);
1046
1047 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
1048 SET(AccumulatedDeltaRangeState,
1049 (static_cast<int32_t>(measurement_V1_1->accumulatedDeltaRangeState) |
1050 ADR_STATE_HALF_CYCLE_REPORTED));
1051}
1052
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001053// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1054template<>
1055void GnssMeasurementCallback::translateSingleGnssMeasurement
1056 <IGnssMeasurementCallback_V2_0::GnssMeasurement>(
1057 const IGnssMeasurementCallback_V2_0::GnssMeasurement* measurement_V2_0,
1058 JavaObject& object) {
1059 translateSingleGnssMeasurement(&(measurement_V2_0->v1_1), object);
1060
Yu-Han Yang786a2bd2019-02-01 19:52:28 -08001061 SET(CodeType, static_cast<int32_t>(measurement_V2_0->codeType));
1062
1063 // Overwrite with v2_0.state since v2_0->v1_1->v1_0.state is deprecated.
1064 SET(State, static_cast<int32_t>(measurement_V2_0->state));
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001065}
1066
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001067jobject GnssMeasurementCallback::translateGnssClock(
Wyatt Riley46ac9562018-03-02 20:16:58 -08001068 JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001069 JavaObject object(env, "android/location/GnssClock");
1070
1071 uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
1072 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
1073 SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
1074 }
1075
1076 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
1077 SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
1078 }
1079
1080 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
1081 SET(FullBiasNanos, clock->fullBiasNs);
1082 }
1083
1084 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
1085 SET(BiasNanos, clock->biasNs);
1086 }
1087
1088 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
1089 SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
1090 }
1091
1092 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
1093 SET(DriftNanosPerSecond, clock->driftNsps);
1094 }
1095
1096 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
1097 SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
1098 }
1099
1100 SET(TimeNanos, clock->timeNs);
1101 SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
1102
1103 return object.get();
1104}
1105
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001106template<class T>
1107jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
1108 const T* measurements,
1109 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -08001110 if (count == 0) {
WyattRiley840c0b22018-10-31 09:03:53 -07001111 return nullptr;
destradaaea8a8a62014-06-23 18:19:03 -07001112 }
1113
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001114 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
Lifu Tang818aa2c2016-02-01 01:52:00 -08001115 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -08001116 count,
Lifu Tang818aa2c2016-02-01 01:52:00 -08001117 gnssMeasurementClass,
WyattRiley840c0b22018-10-31 09:03:53 -07001118 nullptr /* initialElement */);
destradaaea8a8a62014-06-23 18:19:03 -07001119
Lifu Tang120480f2016-02-07 18:08:19 -08001120 for (uint16_t i = 0; i < count; ++i) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001121 JavaObject object(env, "android/location/GnssMeasurement");
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001122 translateSingleGnssMeasurement(&(measurements[i]), object);
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001123 env->SetObjectArrayElement(gnssMeasurementArray, i, object.get());
destradaaea8a8a62014-06-23 18:19:03 -07001124 }
1125
Lifu Tang818aa2c2016-02-01 01:52:00 -08001126 env->DeleteLocalRef(gnssMeasurementClass);
1127 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -07001128}
1129
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001130void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
1131 jobjectArray measurementArray) {
1132 jclass gnssMeasurementsEventClass =
1133 env->FindClass("android/location/GnssMeasurementsEvent");
1134 jmethodID gnssMeasurementsEventCtor =
1135 env->GetMethodID(
1136 gnssMeasurementsEventClass,
1137 "<init>",
1138 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
Lifu Tange5a0e212016-01-25 18:02:17 -08001139
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001140 jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
1141 gnssMeasurementsEventCtor,
1142 clock,
1143 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -08001144
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001145 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
1146 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -08001147 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -08001148 env->DeleteLocalRef(gnssMeasurementsEventClass);
1149 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -07001150}
1151
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001152/*
1153 * GnssNiCallback implements callback methods required by the IGnssNi interface.
1154 */
1155struct GnssNiCallback : public IGnssNiCallback {
1156 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
1157 override;
destradaaea8a8a62014-06-23 18:19:03 -07001158};
1159
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001160Return<void> GnssNiCallback::niNotifyCb(
1161 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001162 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001163 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1164 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
1165
1166 if (requestorId && text) {
1167 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
1168 notification.notificationId, notification.niType,
1169 notification.notifyFlags, notification.timeoutSec,
1170 notification.defaultResponse, requestorId, text,
1171 notification.requestorIdEncoding,
1172 notification.notificationIdEncoding);
1173 } else {
1174 ALOGE("%s: OOM Error\n", __func__);
1175 }
1176
1177 if (requestorId) {
1178 env->DeleteLocalRef(requestorId);
1179 }
1180
1181 if (text) {
1182 env->DeleteLocalRef(text);
1183 }
1184 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1185 return Void();
1186}
1187
1188/*
Anil Admal94ec76a2019-01-15 09:42:01 -08001189 * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
1190 */
1191struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
1192 Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
1193 override;
1194 Return<bool> isInEmergencySession() override;
1195};
1196
1197Return<void> GnssVisibilityControlCallback::nfwNotifyCb(
1198 const IGnssVisibilityControlCallback::NfwNotification& notification) {
1199 JNIEnv* env = getJniEnv();
1200 jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str());
1201 jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str());
1202 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1203
1204 if (proxyAppPackageName && otherProtocolStackName && requestorId) {
1205 env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
1206 notification.protocolStack, otherProtocolStackName,
1207 notification.requestor, requestorId,
1208 notification.inEmergencyMode, notification.isCachedLocation);
1209 } else {
1210 ALOGE("%s: OOM Error\n", __func__);
1211 }
1212
1213 if (requestorId) {
1214 env->DeleteLocalRef(requestorId);
1215 }
1216
1217 if (otherProtocolStackName) {
1218 env->DeleteLocalRef(otherProtocolStackName);
1219 }
1220
1221 if (proxyAppPackageName) {
1222 env->DeleteLocalRef(proxyAppPackageName);
1223 }
1224
1225 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1226 return Void();
1227}
1228
1229Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
1230 JNIEnv* env = getJniEnv();
1231 auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
1232 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1233 return result;
1234}
1235
1236/*
Anil Admalc70344b2018-11-16 14:22:38 -08001237 * AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001238 */
Anil Admalc70344b2018-11-16 14:22:38 -08001239struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001240 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
1241 Return<void> agnssStatusIpV6Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001242 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001243
1244 Return<void> agnssStatusIpV4Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001245 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001246 private:
1247 jbyteArray convertToIpV4(uint32_t ip);
1248};
1249
Anil Admalc70344b2018-11-16 14:22:38 -08001250Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
1251 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001252 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001253 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001254
1255 byteArray = env->NewByteArray(16);
WyattRiley840c0b22018-10-31 09:03:53 -07001256 if (byteArray != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001257 env->SetByteArrayRegion(byteArray, 0, 16,
1258 (const jbyte*)(agps_status.ipV6Addr.data()));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001259 } else {
1260 ALOGE("Unable to allocate byte array for IPv6 address.");
1261 }
1262
1263 IF_ALOGD() {
1264 // log the IP for reference in case there is a bogus value pushed by HAL
1265 char str[INET6_ADDRSTRLEN];
1266 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1267 ALOGD("AGPS IP is v6: %s", str);
1268 }
1269
WyattRiley840c0b22018-10-31 09:03:53 -07001270 jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001271 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1272 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1273 agps_status.type, agps_status.status, byteArray);
1274
1275 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1276
1277 if (byteArray) {
1278 env->DeleteLocalRef(byteArray);
1279 }
1280
1281 return Void();
1282}
1283
Anil Admalc70344b2018-11-16 14:22:38 -08001284Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
1285 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001286 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001287 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001288
1289 uint32_t ipAddr = agps_status.ipV4Addr;
1290 byteArray = convertToIpV4(ipAddr);
1291
1292 IF_ALOGD() {
1293 /*
1294 * log the IP for reference in case there is a bogus value pushed by
1295 * HAL.
1296 */
1297 char str[INET_ADDRSTRLEN];
1298 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1299 ALOGD("AGPS IP is v4: %s", str);
1300 }
1301
1302 jsize byteArrayLength =
WyattRiley840c0b22018-10-31 09:03:53 -07001303 byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001304 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1305 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1306 agps_status.type, agps_status.status, byteArray);
1307
1308 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1309
1310 if (byteArray) {
1311 env->DeleteLocalRef(byteArray);
1312 }
1313 return Void();
1314}
1315
Anil Admalc70344b2018-11-16 14:22:38 -08001316jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001317 if (INADDR_NONE == ip) {
WyattRiley840c0b22018-10-31 09:03:53 -07001318 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001319 }
1320
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001321 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001322 jbyteArray byteArray = env->NewByteArray(4);
WyattRiley840c0b22018-10-31 09:03:53 -07001323 if (byteArray == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001324 ALOGE("Unable to allocate byte array for IPv4 address");
WyattRiley840c0b22018-10-31 09:03:53 -07001325 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001326 }
1327
1328 jbyte ipv4[4];
1329 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1330 memcpy(ipv4, &ip, sizeof(ipv4));
1331 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1332 return byteArray;
1333}
1334
1335/*
Anil Admalc70344b2018-11-16 14:22:38 -08001336 * AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
1337 */
1338struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 {
1339 // Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
1340 Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1341 IAGnssCallback_V2_0::AGnssStatusValue status) override;
1342};
1343
1344Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1345 IAGnssCallback_V2_0::AGnssStatusValue status) {
1346 JNIEnv* env = getJniEnv();
1347 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
1348 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1349 return Void();
1350}
1351
1352/*
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001353 * AGnssRilCallback implements the callback methods required by the AGnssRil
1354 * interface.
1355 */
1356struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001357 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001358 Return<void> requestRefLocCb() override;
1359};
1360
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001361Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001362 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001363 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1364 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1365 return Void();
1366}
1367
1368Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001369 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001370 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1371 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1372 return Void();
1373}
1374
Wyatt Rileycf879db2017-01-12 13:57:38 -08001375/*
1376 * GnssBatchingCallback interface implements the callback methods
1377 * required by the IGnssBatching interface.
1378 */
1379struct GnssBatchingCallback : public IGnssBatchingCallback {
1380 /*
1381 * Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
1382 * follow.
1383 */
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001384 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001385};
1386
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001387Return<void> GnssBatchingCallback::gnssLocationBatchCb(
1388 const hidl_vec<GnssLocation_V1_0>& locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001389 JNIEnv* env = getJniEnv();
1390
1391 jobjectArray jLocations = env->NewObjectArray(locations.size(),
1392 env->FindClass("android/location/Location"), nullptr);
1393
1394 for (uint16_t i = 0; i < locations.size(); ++i) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001395 jobject jLocation = translateGnssLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001396 env->SetObjectArrayElement(jLocations, i, jLocation);
1397 env->DeleteLocalRef(jLocation);
1398 }
1399
1400 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1401 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1402
1403 env->DeleteLocalRef(jLocations);
1404
1405 return Void();
1406}
1407
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001408static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001409 gnssHal_V2_0 = IGnss_V2_0::getService();
1410 if (gnssHal_V2_0 != nullptr) {
1411 gnssHal = gnssHal_V2_0;
1412 gnssHal_V1_1 = gnssHal_V2_0;
1413 return;
Yu-Han Yang6d317352018-03-15 11:53:01 -07001414 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001415
1416 ALOGD("gnssHal 2.0 was null, trying 1.1");
1417 gnssHal_V1_1 = IGnss_V1_1::getService();
1418 if (gnssHal_V1_1 != nullptr) {
1419 gnssHal = gnssHal_V1_1;
1420 return;
1421 }
1422
1423 ALOGD("gnssHal 1.1 was null, trying 1.0");
1424 gnssHal = IGnss_V1_0::getService();
Yu-Han Yang6d317352018-03-15 11:53:01 -07001425}
1426
1427static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001428 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1429 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001430 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Wyatt Riley26465d22018-02-12 13:44:24 -08001431 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001432 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1433 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
1434 method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
1435 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001436 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1437 "(Ljava/lang/String;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001438 method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
1439 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1440 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001441 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001442 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1443 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1444 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1445 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001446 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001447 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001448 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001449 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1450 "(II)V");
1451 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1452 "(II)V");
1453 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1454 "(II)V");
1455 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1456 "(II)V");
1457 method_reportMeasurementData = env->GetMethodID(
1458 clazz,
1459 "reportMeasurementData",
1460 "(Landroid/location/GnssMeasurementsEvent;)V");
1461 method_reportNavigationMessages = env->GetMethodID(
1462 clazz,
1463 "reportNavigationMessage",
1464 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001465 method_reportLocationBatch = env->GetMethodID(
1466 clazz,
1467 "reportLocationBatch",
1468 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001469 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Anil Admal94ec76a2019-01-15 09:42:01 -08001470 method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
1471 "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
1472 method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001473
gomo5716ab82019-02-27 22:57:56 -08001474 jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
1475 method_correctionsGetLatitudeDegrees = env->GetMethodID(
1476 measCorrClass,"getLatitudeDegrees", "()D");
1477 method_correctionsGetLongitudeDegrees = env->GetMethodID(
1478 measCorrClass, "getLongitudeDegrees", "()D");
1479 method_correctionsGetAltitudeMeters = env->GetMethodID(
1480 measCorrClass, "getAltitudeMeters", "()D");
1481 method_correctionsGetHorPosUncMeters = env->GetMethodID(
1482 measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
1483 method_correctionsGetVerPosUncMeters = env->GetMethodID(
1484 measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
1485 method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
1486 measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
1487
1488 method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
1489 measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava/util/List;");
1490
1491 jclass corrListClass = env->FindClass("java/util/List");
1492 method_listSize = env->GetMethodID(corrListClass, "size", "()I");
1493 method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;");
1494
1495 jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection");
1496 method_correctionSatFlags = env->GetMethodID(
1497 singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
1498 method_correctionSatConstType = env->GetMethodID(
1499 singleSatCorrClass, "getConstellationType", "()I");
1500 method_correctionSatId= env->GetMethodID(
1501 singleSatCorrClass, "getSatelliteId", "()I");
1502 method_correctionSatCarrierFreq = env->GetMethodID(
1503 singleSatCorrClass, "getCarrierFrequencyHz", "()F");
1504 method_correctionSatIsLosProb = env->GetMethodID(
1505 singleSatCorrClass,"getProbabilityLineOfSight", "()F");
1506 method_correctionSatEpl = env->GetMethodID(
1507 singleSatCorrClass, "getExcessPathLengthMeters", "()F");
1508 method_correctionSatEplUnc = env->GetMethodID(
1509 singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
1510 method_correctionSatRefPlane = env->GetMethodID(
1511 singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;");
1512
1513 jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane");
1514 method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D");
1515 method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D");
1516 method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D");
1517 method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D");
1518
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001519 /*
1520 * Save a pointer to JVM.
1521 */
1522 jint jvmStatus = env->GetJavaVM(&sJvm);
1523 if (jvmStatus != JNI_OK) {
1524 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
1525 }
1526
Yu-Han Yang88d79102018-11-14 14:20:57 -08001527 if (gnssHal == nullptr) {
1528 ALOGE("Unable to get GPS service\n");
1529 return;
1530 }
gomo25208882017-04-15 02:05:25 -07001531
Yu-Han Yang88d79102018-11-14 14:20:57 -08001532 gnssHalDeathRecipient = new GnssDeathRecipient();
1533 hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
1534 if (!linked.isOk()) {
1535 ALOGE("Transaction error in linking to GnssHAL death: %s",
1536 linked.description().c_str());
1537 } else if (!linked) {
1538 ALOGW("Unable to link to GnssHal death notifications");
1539 } else {
1540 ALOGD("Link to death notification successful");
1541 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001542
Yu-Han Yang88d79102018-11-14 14:20:57 -08001543 auto gnssXtra = gnssHal->getExtensionXtra();
1544 if (!gnssXtra.isOk()) {
1545 ALOGD("Unable to get a handle to Xtra");
1546 } else {
1547 gnssXtraIface = gnssXtra;
1548 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001549
Anil Admalb4995e22018-11-16 17:36:21 -08001550 if (gnssHal_V2_0 != nullptr) {
1551 auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
1552 if (!agnssRil_V2_0.isOk()) {
1553 ALOGD("Unable to get a handle to AGnssRil_V2_0");
1554 } else {
1555 agnssRilIface_V2_0 = agnssRil_V2_0;
1556 agnssRilIface = agnssRilIface_V2_0;
1557 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001558 } else {
Anil Admalb4995e22018-11-16 17:36:21 -08001559 auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
1560 if (!agnssRil_V1_0.isOk()) {
1561 ALOGD("Unable to get a handle to AGnssRil");
1562 } else {
1563 agnssRilIface = agnssRil_V1_0;
1564 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001565 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001566
Anil Admalc70344b2018-11-16 14:22:38 -08001567 if (gnssHal_V2_0 != nullptr) {
1568 auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
1569 if (!agnss_V2_0.isOk()) {
1570 ALOGD("Unable to get a handle to AGnss_V2_0");
1571 } else {
1572 agnssIface_V2_0 = agnss_V2_0;
1573 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001574 } else {
Anil Admalc70344b2018-11-16 14:22:38 -08001575 auto agnss_V1_0 = gnssHal->getExtensionAGnss();
1576 if (!agnss_V1_0.isOk()) {
1577 ALOGD("Unable to get a handle to AGnss");
1578 } else {
1579 agnssIface = agnss_V1_0;
1580 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001581 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001582
Yu-Han Yang88d79102018-11-14 14:20:57 -08001583 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
1584 if (!gnssNavigationMessage.isOk()) {
1585 ALOGD("Unable to get a handle to GnssNavigationMessage");
1586 } else {
1587 gnssNavigationMessageIface = gnssNavigationMessage;
1588 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001589
Yu-Han Yang88d79102018-11-14 14:20:57 -08001590 if (gnssHal_V2_0 != nullptr) {
1591 // TODO(b/119638366): getExtensionGnssMeasurement_1_1 from gnssHal_V2_0
1592 auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
1593 if (!gnssMeasurement.isOk()) {
1594 ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001595 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001596 gnssMeasurementIface_V2_0 = gnssMeasurement;
1597 gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
1598 gnssMeasurementIface = gnssMeasurementIface_V2_0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001599 }
Anil Admal94ec76a2019-01-15 09:42:01 -08001600 auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
1601 if (!gnssCorrections.isOk()) {
1602 ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
1603 } else {
1604 gnssCorrectionsIface = gnssCorrections;
1605 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001606 } else if (gnssHal_V1_1 != nullptr) {
1607 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
1608 if (!gnssMeasurement.isOk()) {
1609 ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
1610 } else {
1611 gnssMeasurementIface_V1_1 = gnssMeasurement;
1612 gnssMeasurementIface = gnssMeasurementIface_V1_1;
1613 }
1614 } else {
1615 auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
1616 if (!gnssMeasurement_V1_0.isOk()) {
1617 ALOGD("Unable to get a handle to GnssMeasurement");
1618 } else {
1619 gnssMeasurementIface = gnssMeasurement_V1_0;
1620 }
1621 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001622
Yu-Han Yang88d79102018-11-14 14:20:57 -08001623 auto gnssDebug = gnssHal->getExtensionGnssDebug();
1624 if (!gnssDebug.isOk()) {
1625 ALOGD("Unable to get a handle to GnssDebug");
1626 } else {
1627 gnssDebugIface = gnssDebug;
1628 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001629
Yu-Han Yang88d79102018-11-14 14:20:57 -08001630 auto gnssNi = gnssHal->getExtensionGnssNi();
1631 if (!gnssNi.isOk()) {
1632 ALOGD("Unable to get a handle to GnssNi");
1633 } else {
1634 gnssNiIface = gnssNi;
1635 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001636
Anil Admald71cf142018-12-21 14:59:36 -08001637 if (gnssHal_V2_0 != nullptr) {
1638 auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
1639 if (!gnssConfiguration.isOk()) {
1640 ALOGD("Unable to get a handle to GnssConfiguration_V2_0");
1641 } else {
1642 gnssConfigurationIface_V2_0 = gnssConfiguration;
1643 gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_0;
1644 gnssConfigurationIface = gnssConfigurationIface_V2_0;
1645 }
1646 } else if (gnssHal_V1_1 != nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001647 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
1648 if (!gnssConfiguration.isOk()) {
Anil Admald71cf142018-12-21 14:59:36 -08001649 ALOGD("Unable to get a handle to GnssConfiguration_V1_1");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01001650 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001651 gnssConfigurationIface_V1_1 = gnssConfiguration;
1652 gnssConfigurationIface = gnssConfigurationIface_V1_1;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001653 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001654 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08001655 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
1656 if (!gnssConfiguration_V1_0.isOk()) {
1657 ALOGD("Unable to get a handle to GnssConfiguration");
1658 } else {
1659 gnssConfigurationIface = gnssConfiguration_V1_0;
1660 }
1661 }
1662
1663 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
1664 if (!gnssGeofencing.isOk()) {
1665 ALOGD("Unable to get a handle to GnssGeofencing");
1666 } else {
1667 gnssGeofencingIface = gnssGeofencing;
1668 }
1669
1670 auto gnssBatching = gnssHal->getExtensionGnssBatching();
1671 if (!gnssBatching.isOk()) {
1672 ALOGD("Unable to get a handle to gnssBatching");
1673 } else {
1674 gnssBatchingIface = gnssBatching;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001675 }
Anil Admal94ec76a2019-01-15 09:42:01 -08001676
1677 if (gnssHal_V2_0 != nullptr) {
1678 auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl();
1679 if (!gnssVisibilityControl.isOk()) {
1680 ALOGD("Unable to get a handle to GnssVisibilityControl interface");
1681 } else {
1682 gnssVisibilityControlIface = gnssVisibilityControl;
1683 }
1684 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001685}
1686
1687static jboolean android_location_GnssLocationProvider_is_supported(
1688 JNIEnv* /* env */, jclass /* clazz */) {
1689 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
1690}
1691
Anil Admal50ba15e2018-11-01 16:42:42 -07001692static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001693 JNIEnv* /* env */, jclass /* clazz */) {
1694 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
1695}
1696
Anil Admald71cf142018-12-21 14:59:36 -08001697static jobject android_location_GnssConfiguration_get_gnss_configuration_version(
1698 JNIEnv* env, jclass /* jclazz */) {
1699 jint major, minor;
1700 if (gnssConfigurationIface_V2_0 != nullptr) {
1701 major = 2;
1702 minor = 0;
1703 } else if (gnssConfigurationIface_V1_1 != nullptr) {
1704 major = 1;
1705 minor = 1;
1706 } else if (gnssConfigurationIface != nullptr) {
1707 major = 1;
1708 minor = 0;
1709 } else {
1710 return nullptr;
1711 }
1712
1713 return createHalInterfaceVersionJavaObject(env, major, minor);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001714}
1715
1716static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
1717 /*
1718 * This must be set before calling into the HAL library.
1719 */
1720 if (!mCallbacksObj)
1721 mCallbacksObj = env->NewGlobalRef(obj);
1722
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001723 /*
1724 * Fail if the main interface fails to initialize
1725 */
1726 if (gnssHal == nullptr) {
1727 ALOGE("Unable to Initialize GNSS HAL\n");
1728 return JNI_FALSE;
1729 }
1730
Wyatt Rileyfb840922017-11-08 15:07:58 -08001731 sp<IGnssCallback> gnssCbIface = new GnssCallback();
1732
1733 Return<bool> result = false;
gomo226b7b72018-12-12 16:49:39 -08001734 if (gnssHal_V2_0 != nullptr) {
1735 result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
1736 } else if (gnssHal_V1_1 != nullptr) {
gomo48f1a642017-11-10 20:35:46 -08001737 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08001738 } else {
1739 result = gnssHal->setCallback(gnssCbIface);
1740 }
gomo226b7b72018-12-12 16:49:39 -08001741
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001742 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001743 ALOGE("SetCallback for Gnss Interface fails\n");
1744 return JNI_FALSE;
1745 }
1746
1747 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
1748 if (gnssXtraIface == nullptr) {
WyattRileybc5a8b02018-10-31 13:06:34 -07001749 ALOGI("Unable to initialize GNSS Xtra interface\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001750 } else {
1751 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001752 if (!result.isOk() || !result) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08001753 gnssXtraIface = nullptr;
Wyatt Rileyfb840922017-11-08 15:07:58 -08001754 ALOGI("SetCallback for Gnss Xtra Interface fails\n");
Hridya Valsarajue8650322016-12-05 20:23:21 -08001755 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001756 }
1757
Anil Admalc70344b2018-11-16 14:22:38 -08001758 if (agnssIface_V2_0 != nullptr) {
1759 sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
1760 agnssIface_V2_0->setCallback(aGnssCbIface);
1761 } else if (agnssIface != nullptr) {
1762 sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001763 agnssIface->setCallback(aGnssCbIface);
1764 } else {
Anil Admalc70344b2018-11-16 14:22:38 -08001765 ALOGI("Unable to initialize AGnss interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001766 }
1767
1768 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
1769 if (gnssGeofencingIface != nullptr) {
1770 gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
1771 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001772 ALOGI("Unable to initialize GNSS Geofencing interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001773 }
1774
1775 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08001776 if (gnssNiIface != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001777 gnssNiIface->setCallback(gnssNiCbIface);
1778 } else {
Wyatt Rileyfb840922017-11-08 15:07:58 -08001779 ALOGI("Unable to initialize GNSS NI interface\n");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001780 }
1781
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001782 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
1783 if (agnssRilIface != nullptr) {
1784 agnssRilIface->setCallback(aGnssRilCbIface);
1785 } else {
Anil Admal94ec76a2019-01-15 09:42:01 -08001786 ALOGI("Unable to initialize AGnss Ril interface\n");
1787 }
1788
1789 if (gnssVisibilityControlIface != nullptr) {
1790 sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
1791 new GnssVisibilityControlCallback();
1792 gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09001793 }
1794
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001795 return JNI_TRUE;
1796}
1797
1798static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
1799 if (gnssHal != nullptr) {
1800 gnssHal->cleanup();
1801 }
1802}
1803
1804static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
1805 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08001806 jint preferred_time, jboolean low_power_mode) {
1807 Return<bool> result = false;
1808 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001809 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1810 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1811 min_interval,
1812 preferred_accuracy,
1813 preferred_time,
1814 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08001815 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001816 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
1817 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
1818 min_interval,
1819 preferred_accuracy,
1820 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08001821 }
1822 if (!result.isOk()) {
1823 ALOGE("%s: GNSS setPositionMode failed\n", __func__);
1824 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001825 } else {
gomo48f1a642017-11-10 20:35:46 -08001826 return result;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001827 }
1828}
1829
1830static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
1831 if (gnssHal != nullptr) {
1832 auto result = gnssHal->start();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001833 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001834 return JNI_FALSE;
1835 } else {
1836 return result;
1837 }
1838 } else {
1839 return JNI_FALSE;
1840 }
1841}
1842
1843static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
1844 if (gnssHal != nullptr) {
1845 auto result = gnssHal->stop();
Steven Morelandd002a8b2017-01-03 17:18:24 -08001846 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001847 return JNI_FALSE;
1848 } else {
1849 return result;
1850 }
1851 } else {
1852 return JNI_FALSE;
1853 }
1854}
1855static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
1856 jobject /* obj */,
1857 jint flags) {
1858 if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08001859 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
Steven Morelandd002a8b2017-01-03 17:18:24 -08001860 if (!result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001861 ALOGE("Error in deleting aiding data");
1862 }
1863 }
1864}
1865
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001866static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
1867 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
Anil Admalb4995e22018-11-16 17:36:21 -08001868 IAGnssRil_V1_0::AGnssRefLocation location;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001869
1870 if (agnssRilIface == nullptr) {
1871 ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
1872 return;
1873 }
1874
Anil Admalb4995e22018-11-16 17:36:21 -08001875 switch (static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type)) {
1876 case IAGnssRil_V1_0::AGnssRefLocationType::GSM_CELLID:
1877 case IAGnssRil_V1_0::AGnssRefLocationType::UMTS_CELLID:
1878 location.type = static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001879 location.cellID.mcc = mcc;
1880 location.cellID.mnc = mnc;
1881 location.cellID.lac = lac;
1882 location.cellID.cid = cid;
1883 break;
1884 default:
1885 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
1886 return;
1887 break;
1888 }
1889
1890 agnssRilIface->setRefLocation(location);
1891}
1892
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001893static void android_location_GnssLocationProvider_agps_set_id(JNIEnv* env, jobject /* obj */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001894 jint type, jstring setid_string) {
1895 if (agnssRilIface == nullptr) {
1896 ALOGE("no AGPS RIL interface in agps_set_id");
1897 return;
1898 }
1899
Anil Admalc70344b2018-11-16 14:22:38 -08001900 ScopedJniString jniSetId{env, setid_string};
1901 agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001902}
1903
1904static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
1905 jbyteArray nmeaArray, jint buffer_size) {
1906 // this should only be called from within a call to reportNmea
1907 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
1908 int length = GnssCallback::sNmeaStringLength;
1909 if (length > buffer_size)
1910 length = buffer_size;
1911 memcpy(nmea, GnssCallback::sNmeaString, length);
1912 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
1913 return (jint) length;
1914}
1915
1916static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
1917 jlong time, jlong timeReference, jint uncertainty) {
1918 if (gnssHal != nullptr) {
1919 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001920 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001921 ALOGE("%s: Gnss injectTime() failed", __func__);
1922 }
1923 }
1924}
1925
Yu-Han Yange7baef32018-02-09 13:58:17 -08001926static void android_location_GnssLocationProvider_inject_best_location(
1927 JNIEnv*,
1928 jobject,
1929 jint gnssLocationFlags,
1930 jdouble latitudeDegrees,
1931 jdouble longitudeDegrees,
1932 jdouble altitudeMeters,
1933 jfloat speedMetersPerSec,
1934 jfloat bearingDegrees,
1935 jfloat horizontalAccuracyMeters,
1936 jfloat verticalAccuracyMeters,
1937 jfloat speedAccuracyMetersPerSecond,
1938 jfloat bearingAccuracyDegrees,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001939 jlong timestamp,
1940 jint elapsedRealtimeFlags,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +00001941 jlong elapsedRealtimeNanos,
1942 jlong elapsedRealtimeUncertaintyNanos) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001943 if (gnssHal_V2_0 != nullptr) {
1944 GnssLocation_V2_0 location = createGnssLocation_V2_0(
1945 gnssLocationFlags,
1946 latitudeDegrees,
1947 longitudeDegrees,
1948 altitudeMeters,
1949 speedMetersPerSec,
1950 bearingDegrees,
1951 horizontalAccuracyMeters,
1952 verticalAccuracyMeters,
1953 speedAccuracyMetersPerSecond,
1954 bearingAccuracyDegrees,
1955 timestamp,
1956 elapsedRealtimeFlags,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +00001957 elapsedRealtimeNanos,
1958 elapsedRealtimeUncertaintyNanos);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001959 auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
1960
1961 if (!result.isOk() || !result) {
1962 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1963 }
1964 return;
1965 }
1966
Yu-Han Yange7baef32018-02-09 13:58:17 -08001967 if (gnssHal_V1_1 != nullptr) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001968 GnssLocation_V1_0 location = createGnssLocation_V1_0(
Yu-Han Yange7baef32018-02-09 13:58:17 -08001969 gnssLocationFlags,
1970 latitudeDegrees,
1971 longitudeDegrees,
1972 altitudeMeters,
1973 speedMetersPerSec,
1974 bearingDegrees,
1975 horizontalAccuracyMeters,
1976 verticalAccuracyMeters,
1977 speedAccuracyMetersPerSecond,
1978 bearingAccuracyDegrees,
1979 timestamp);
1980 auto result = gnssHal_V1_1->injectBestLocation(location);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001981
Yu-Han Yange7baef32018-02-09 13:58:17 -08001982 if (!result.isOk() || !result) {
1983 ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
1984 }
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001985 return;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001986 }
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001987
1988 ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001989}
1990
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001991static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
1992 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
1993 if (gnssHal != nullptr) {
1994 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08001995 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001996 ALOGE("%s: Gnss injectLocation() failed", __func__);
1997 }
1998 }
1999}
2000
2001static jboolean android_location_GnssLocationProvider_supports_xtra(
2002 JNIEnv* /* env */, jobject /* obj */) {
2003 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2004}
2005
2006static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
2007 jbyteArray data, jint length) {
2008 if (gnssXtraIface == nullptr) {
2009 ALOGE("XTRA Interface not supported");
2010 return;
2011 }
2012
2013 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
2014 gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
2015 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
2016}
2017
Anil Admalc70344b2018-11-16 14:22:38 -08002018struct AGnssDispatcher {
2019 static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType);
2020 static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle,
2021 jstring apn, jint apnIpType);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002022
Anil Admalc70344b2018-11-16 14:22:38 -08002023 template <class T>
2024 static void dataConnClosed(sp<T> agnssIface);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002025
Anil Admalc70344b2018-11-16 14:22:38 -08002026 template <class T>
2027 static void dataConnFailed(sp<T> agnssIface);
2028
2029 template <class T, class U>
2030 static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port);
2031
2032private:
2033 AGnssDispatcher() = delete;
2034 AGnssDispatcher(const AGnssDispatcher&) = delete;
2035 AGnssDispatcher& operator=(const AGnssDispatcher&) = delete;
2036};
2037
2038void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn,
2039 jint apnIpType) {
2040 ScopedJniString jniApn{env, apn};
2041 auto result = agnssIface->dataConnOpen(jniApn,
2042 static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002043 if (!result.isOk() || !result){
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002044 ALOGE("%s: Failed to set APN and its IP type", __func__);
2045 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002046}
2047
Anil Admalc70344b2018-11-16 14:22:38 -08002048void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
2049 jlong networkHandle, jstring apn, jint apnIpType) {
2050 ScopedJniString jniApn{env, apn};
2051 auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
2052 static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
2053 if (!result.isOk() || !result){
2054 ALOGE("%s: Failed to set APN and its IP type", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002055 }
Anil Admalc70344b2018-11-16 14:22:38 -08002056}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002057
Anil Admalc70344b2018-11-16 14:22:38 -08002058template<class T>
2059void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002060 auto result = agnssIface->dataConnClosed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002061 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002062 ALOGE("%s: Failed to close AGnss data connection", __func__);
2063 }
2064}
2065
Anil Admalc70344b2018-11-16 14:22:38 -08002066template<class T>
2067void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002068 auto result = agnssIface->dataConnFailed();
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002069 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002070 ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
2071 }
2072}
2073
Anil Admalc70344b2018-11-16 14:22:38 -08002074template <class T, class U>
2075void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname,
2076 jint port) {
2077 ScopedJniString jniHostName{env, hostname};
2078 auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
2079 jniHostName, port);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002080 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002081 ALOGE("%s: Failed to set AGnss host name and port", __func__);
2082 }
Anil Admalc70344b2018-11-16 14:22:38 -08002083}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002084
Anil Admalc70344b2018-11-16 14:22:38 -08002085static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
2086 JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
2087 if (apn == nullptr) {
2088 jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
2089 return;
2090 }
2091
2092 if (agnssIface_V2_0 != nullptr) {
2093 AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType);
2094 } else if (agnssIface != nullptr) {
2095 AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
2096 } else {
2097 ALOGE("%s: AGPS interface not supported", __func__);
2098 return;
2099 }
2100}
2101
2102static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
2103 jobject /* obj */) {
2104 if (agnssIface_V2_0 != nullptr) {
2105 AGnssDispatcher::dataConnClosed(agnssIface_V2_0);
2106 } else if (agnssIface != nullptr) {
2107 AGnssDispatcher::dataConnClosed(agnssIface);
2108 } else {
2109 ALOGE("%s: AGPS interface not supported", __func__);
2110 return;
2111 }
2112}
2113
2114static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
2115 jobject /* obj */) {
2116 if (agnssIface_V2_0 != nullptr) {
2117 AGnssDispatcher::dataConnFailed(agnssIface_V2_0);
2118 } else if (agnssIface != nullptr) {
2119 AGnssDispatcher::dataConnFailed(agnssIface);
2120 } else {
2121 ALOGE("%s: AGPS interface not supported", __func__);
2122 return;
2123 }
2124}
2125
2126static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
2127 jint type, jstring hostname, jint port) {
2128 if (agnssIface_V2_0 != nullptr) {
2129 AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type,
2130 hostname, port);
2131 } else if (agnssIface != nullptr) {
2132 AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
2133 hostname, port);
2134 } else {
2135 ALOGE("%s: AGPS interface not supported", __func__);
2136 return;
2137 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002138}
2139
2140static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
2141 jobject /* obj */, jint notifId, jint response) {
2142 if (gnssNiIface == nullptr) {
2143 ALOGE("no NI interface in send_ni_response");
2144 return;
2145 }
2146
2147 gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
2148}
2149
2150static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
2151 jobject /* obj */) {
WyattRiley840c0b22018-10-31 09:03:53 -07002152 jstring result = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002153 /*
2154 * TODO(b/33089503) : Create a jobject to represent GnssDebug.
2155 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07002156
2157 std::stringstream internalState;
2158
2159 if (gnssDebugIface == nullptr) {
2160 internalState << "Gnss Debug Interface not available" << std::endl;
2161 } else {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002162 IGnssDebug::DebugData data;
2163 gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
2164 data = debugData;
2165 });
2166
Wyatt Riley268c6e02017-03-29 10:21:46 -07002167 internalState << "Gnss Location Data:: ";
2168 if (!data.position.valid) {
2169 internalState << "not valid";
2170 } else {
2171 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002172 << ", LongitudeDegrees: " << data.position.longitudeDegrees
2173 << ", altitudeMeters: " << data.position.altitudeMeters
gomo4402af62017-01-11 13:20:13 -08002174 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
2175 << ", bearingDegrees: " << data.position.bearingDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07002176 << ", horizontalAccuracyMeters: "
2177 << data.position.horizontalAccuracyMeters
gomo4402af62017-01-11 13:20:13 -08002178 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
Wyatt Riley268c6e02017-03-29 10:21:46 -07002179 << ", speedAccuracyMetersPerSecond: "
2180 << data.position.speedAccuracyMetersPerSecond
gomo4402af62017-01-11 13:20:13 -08002181 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
Wyatt Riley268c6e02017-03-29 10:21:46 -07002182 << ", ageSeconds: " << data.position.ageSeconds;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002183 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07002184 internalState << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002185
Wyatt Riley268c6e02017-03-29 10:21:46 -07002186 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
2187 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
2188 << ", frequencyUncertaintyNsPerSec: "
2189 << data.time.frequencyUncertaintyNsPerSec << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002190
2191 if (data.satelliteDataArray.size() != 0) {
Wyatt Riley268c6e02017-03-29 10:21:46 -07002192 internalState << "Satellite Data for " << data.satelliteDataArray.size()
2193 << " satellites:: " << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002194 }
2195
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002196 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL; "
2197 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
2198 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
2199 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002200 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002201 internalState << "constell: "
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002202 << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002203 << ", svid: " << std::setw(3) << data.satelliteDataArray[i].svid
2204 << ", serverPredAvail: "
Wyatt Riley268c6e02017-03-29 10:21:46 -07002205 << data.satelliteDataArray[i].serverPredictionIsAvailable
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002206 << ", serverPredAgeSec: " << std::setw(7)
Wyatt Riley268c6e02017-03-29 10:21:46 -07002207 << data.satelliteDataArray[i].serverPredictionAgeSeconds
Wyatt Rileyb6a50f02018-05-03 13:59:04 -07002208 << ", ephType: "
2209 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
2210 << ", ephSource: "
2211 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisSource)
2212 << ", ephHealth: "
2213 << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisHealth)
2214 << ", ephAgeSec: " << std::setw(7)
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002215 << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
2216 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002217 }
Wyatt Riley268c6e02017-03-29 10:21:46 -07002218
2219 result = env->NewStringUTF(internalState.str().c_str());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002220 return result;
2221}
2222
Anil Admal94ec76a2019-01-15 09:42:01 -08002223static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported(
2224 JNIEnv* /* env */, jclass /* clazz */) {
2225 return (gnssVisibilityControlIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2226}
2227
Anil Admal50ba15e2018-11-01 16:42:42 -07002228static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002229 jobject /* obj */,
2230 jboolean connected,
2231 jint type,
2232 jboolean roaming,
2233 jboolean available,
Anil Admalb4995e22018-11-16 17:36:21 -08002234 jstring apn,
2235 jlong networkHandle,
2236 jshort capabilities) {
Anil Admalb4995e22018-11-16 17:36:21 -08002237 if (agnssRilIface_V2_0 != nullptr) {
Anil Admalc70344b2018-11-16 14:22:38 -08002238 ScopedJniString jniApn{env, apn};
Anil Admalb4995e22018-11-16 17:36:21 -08002239 IAGnssRil_V2_0::NetworkAttributes networkAttributes = {
2240 .networkHandle = static_cast<uint64_t>(networkHandle),
2241 .isConnected = static_cast<bool>(connected),
2242 .capabilities = static_cast<uint16_t>(capabilities),
Anil Admalc70344b2018-11-16 14:22:38 -08002243 .apn = jniApn
Anil Admalb4995e22018-11-16 17:36:21 -08002244 };
2245
2246 auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
2247 if (!result.isOk() || !result) {
2248 ALOGE("updateNetworkState_2_0 failed");
2249 }
Anil Admalc70344b2018-11-16 14:22:38 -08002250 } else if (agnssRilIface != nullptr) {
2251 ScopedJniString jniApn{env, apn};
2252 hidl_string hidlApn{jniApn};
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002253 auto result = agnssRilIface->updateNetworkState(connected,
Anil Admalb4995e22018-11-16 17:36:21 -08002254 static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
Hridya Valsarajuf6423ba2017-02-28 09:40:48 -08002255 if (!result.isOk() || !result) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002256 ALOGE("updateNetworkState failed");
2257 }
2258
Anil Admalc70344b2018-11-16 14:22:38 -08002259 if (!hidlApn.empty()) {
2260 result = agnssRilIface->updateNetworkAvailability(available, hidlApn);
Anil Admalb4995e22018-11-16 17:36:21 -08002261 if (!result.isOk() || !result) {
2262 ALOGE("updateNetworkAvailability failed");
2263 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002264 }
Anil Admalc70344b2018-11-16 14:22:38 -08002265 } else {
2266 ALOGE("AGnssRilInterface does not exist");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002267 }
2268}
2269
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002270static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002271 JNIEnv* /* env */, jobject /* obj */) {
2272 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2273}
2274
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002275static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002276 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
2277 jint last_transition, jint monitor_transition, jint notification_responsiveness,
2278 jint unknown_timer) {
2279 if (gnssGeofencingIface != nullptr) {
2280 auto result = gnssGeofencingIface->addGeofence(
2281 geofenceId, latitude, longitude, radius,
2282 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
2283 monitor_transition, notification_responsiveness, unknown_timer);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002284 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002285 } else {
2286 ALOGE("Geofence Interface not available");
2287 }
2288 return JNI_FALSE;
2289}
2290
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002291static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002292 jobject /* obj */, jint geofenceId) {
2293 if (gnssGeofencingIface != nullptr) {
2294 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002295 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002296 } else {
2297 ALOGE("Geofence interface not available");
2298 }
2299 return JNI_FALSE;
2300}
2301
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002302static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002303 jobject /* obj */, jint geofenceId) {
2304 if (gnssGeofencingIface != nullptr) {
2305 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002306 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002307 } else {
2308 ALOGE("Geofence interface not available");
2309 }
2310 return JNI_FALSE;
2311}
2312
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002313static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002314 jobject /* obj */, jint geofenceId, jint monitor_transition) {
2315 if (gnssGeofencingIface != nullptr) {
2316 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002317 return boolToJbool(result.isOk());
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002318 } else {
2319 ALOGE("Geofence interface not available");
2320 }
2321 return JNI_FALSE;
2322}
2323
Yu-Han Yang8de21502018-04-23 01:40:25 -07002324static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002325 JNIEnv* env, jclass clazz) {
2326 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07002327 return JNI_TRUE;
2328 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002329
destradaaea8a8a62014-06-23 18:19:03 -07002330 return JNI_FALSE;
2331}
2332
Yu-Han Yang8de21502018-04-23 01:40:25 -07002333static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08002334 JNIEnv* /* env */,
2335 jobject /* obj */,
2336 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002337 if (gnssMeasurementIface == nullptr) {
2338 ALOGE("GNSS Measurement interface is not available.");
destradaaea8a8a62014-06-23 18:19:03 -07002339 return JNI_FALSE;
2340 }
2341
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002342 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
gomo48f1a642017-11-10 20:35:46 -08002343 IGnssMeasurement_V1_0::GnssMeasurementStatus result =
Yu-Han Yang88d79102018-11-14 14:20:57 -08002344 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
2345 if (gnssMeasurementIface_V2_0 != nullptr) {
2346 result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
2347 } else if (gnssMeasurementIface_V1_1 != nullptr) {
2348 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
gomo48f1a642017-11-10 20:35:46 -08002349 } else {
2350 if (enableFullTracking == JNI_TRUE) {
2351 // full tracking mode not supported in 1.0 HAL
2352 return JNI_FALSE;
2353 }
2354 result = gnssMeasurementIface->setCallback(cbIface);
2355 }
2356
2357 if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002358 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
2359 static_cast<int32_t>(result));
destradaaea8a8a62014-06-23 18:19:03 -07002360 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002361 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002362 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07002363 }
2364
2365 return JNI_TRUE;
2366}
2367
Yu-Han Yang8de21502018-04-23 01:40:25 -07002368static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07002369 JNIEnv* env,
2370 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002371 if (gnssMeasurementIface == nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07002372 ALOGE("Measurement interface not available");
2373 return JNI_FALSE;
2374 }
2375
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002376 auto result = gnssMeasurementIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08002377 return boolToJbool(result.isOk());
destradaaea8a8a62014-06-23 18:19:03 -07002378}
2379
gomo226b7b72018-12-12 16:49:39 -08002380static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections(
2381 JNIEnv* env,
2382 jobject obj /* clazz*/,
2383 jobject correctionsObj) {
2384
2385 if (gnssCorrectionsIface == nullptr) {
2386 ALOGW("Trying to inject GNSS corrections on a chipset that does not support them.");
2387 return JNI_FALSE;
2388 }
gomo226b7b72018-12-12 16:49:39 -08002389
2390 jdouble latitudeDegreesCorr = env->CallDoubleMethod(
2391 correctionsObj, method_correctionsGetLatitudeDegrees);
2392 jdouble longitudeDegreesCorr = env->CallDoubleMethod(
2393 correctionsObj, method_correctionsGetLongitudeDegrees);
2394 jdouble altitudeDegreesCorr = env->CallDoubleMethod(
2395 correctionsObj, method_correctionsGetAltitudeMeters);
gomo6ec95382019-01-26 03:08:18 -08002396 jdouble horizontalPositionUncertaintyMeters = env->CallDoubleMethod(
2397 correctionsObj, method_correctionsGetHorPosUncMeters);
2398 jdouble verticalPositionUncertaintyMeters = env->CallDoubleMethod(
2399 correctionsObj, method_correctionsGetVerPosUncMeters);
gomo226b7b72018-12-12 16:49:39 -08002400 jlong toaGpsNanosOfWeek = env->CallLongMethod(
2401 correctionsObj, method_correctionsGetToaGpsNanosecondsOfWeek);
2402 jobject singleSatCorrectionList = env->CallObjectMethod(correctionsObj,
2403 method_correctionsGetSingleSatCorrectionList);
2404
gomo226b7b72018-12-12 16:49:39 -08002405 auto len = (singleSatCorrectionList == nullptr)
2406 ? 0
2407 : env->CallIntMethod(singleSatCorrectionList, method_listSize);
gomo5716ab82019-02-27 22:57:56 -08002408 if (len == 0) {
2409 ALOGI("Empty correction list injected....Returning with no HAL injection");
2410 return JNI_TRUE;
2411 }
gomo226b7b72018-12-12 16:49:39 -08002412 hidl_vec<SingleSatCorrection> list(len);
2413
2414 for (uint16_t i = 0; i < len; ++i) {
2415 jobject singleSatCorrectionObj = env->CallObjectMethod(
gomo5716ab82019-02-27 22:57:56 -08002416 singleSatCorrectionList, method_correctionListGet, i);
gomo226b7b72018-12-12 16:49:39 -08002417
2418 jint correctionFlags =
2419 env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags);
2420 jint constType = env->CallIntMethod(singleSatCorrectionObj,
2421 method_correctionSatConstType);
2422 jint satId =
2423 env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId);
2424 jfloat carrierFreqHz = env->CallFloatMethod(
2425 singleSatCorrectionObj, method_correctionSatCarrierFreq);
gomob4635ba2019-01-17 04:02:53 -08002426 jfloat probSatIsLos = env->CallFloatMethod(singleSatCorrectionObj,
2427 method_correctionSatIsLosProb);
gomo226b7b72018-12-12 16:49:39 -08002428 jfloat eplMeters =
2429 env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl);
2430 jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj,
2431 method_correctionSatEplUnc);
gomo5716ab82019-02-27 22:57:56 -08002432 uint16_t corrFlags = static_cast<uint16_t>(correctionFlags);
2433 jobject reflectingPlaneObj;
2434 bool has_ref_plane = (corrFlags & GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE) != 0;
2435 if (has_ref_plane) {
2436 reflectingPlaneObj = env->CallObjectMethod(
2437 singleSatCorrectionObj, method_correctionSatRefPlane);
gomo226b7b72018-12-12 16:49:39 -08002438 }
2439
gomo5716ab82019-02-27 22:57:56 -08002440 ReflectingPlane reflectingPlane;
2441 if (has_ref_plane) {
2442 jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(
2443 reflectingPlaneObj, method_correctionPlaneLatDeg);
2444 jdouble longitudeDegreesRefPlane = env->CallDoubleMethod(
2445 reflectingPlaneObj, method_correctionPlaneLngDeg);
2446 jdouble altitudeDegreesRefPlane = env->CallDoubleMethod(
2447 reflectingPlaneObj, method_correctionPlaneAltDeg);
2448 jdouble azimuthDegreeRefPlane = env->CallDoubleMethod(
2449 reflectingPlaneObj, method_correctionPlaneAzimDeg);
2450 reflectingPlane = {
2451 .latitudeDegrees = latitudeDegreesRefPlane,
2452 .longitudeDegrees = longitudeDegreesRefPlane,
2453 .altitudeMeters = altitudeDegreesRefPlane,
2454 .azimuthDegrees = azimuthDegreeRefPlane,
2455 };
2456 }
gomo226b7b72018-12-12 16:49:39 -08002457
2458 SingleSatCorrection singleSatCorrection = {
gomo5716ab82019-02-27 22:57:56 -08002459 .singleSatCorrectionFlags = corrFlags,
gomo226b7b72018-12-12 16:49:39 -08002460 .constellation = static_cast<GnssConstellationType>(constType),
2461 .svid = static_cast<uint16_t>(satId),
2462 .carrierFrequencyHz = carrierFreqHz,
gomob4635ba2019-01-17 04:02:53 -08002463 .probSatIsLos = probSatIsLos,
gomo226b7b72018-12-12 16:49:39 -08002464 .excessPathLengthMeters = eplMeters,
2465 .excessPathLengthUncertaintyMeters = eplUncMeters,
2466 .reflectingPlane = reflectingPlane,
2467 };
2468 list[i] = singleSatCorrection;
2469 }
2470 MeasurementCorrections measurementCorrections = {
2471 .latitudeDegrees = latitudeDegreesCorr,
2472 .longitudeDegrees = longitudeDegreesCorr,
2473 .altitudeMeters = altitudeDegreesCorr,
gomo6ec95382019-01-26 03:08:18 -08002474 .horizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters,
2475 .verticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters,
gomo226b7b72018-12-12 16:49:39 -08002476 .toaGpsNanosecondsOfWeek = static_cast<uint64_t>(toaGpsNanosOfWeek),
2477 .satCorrections = list,
2478 };
2479
2480 gnssCorrectionsIface->setCorrections(measurementCorrections);
gomo226b7b72018-12-12 16:49:39 -08002481 return JNI_TRUE;
2482}
2483
Yu-Han Yang23d92162018-04-19 06:03:00 -07002484static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07002485 JNIEnv* env,
2486 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002487 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002488 return JNI_TRUE;
2489 }
2490 return JNI_FALSE;
2491}
2492
Yu-Han Yang23d92162018-04-19 06:03:00 -07002493static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07002494 JNIEnv* env,
2495 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002496 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002497 ALOGE("Navigation Message interface is not available.");
2498 return JNI_FALSE;
2499 }
2500
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002501 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
2502 new GnssNavigationMessageCallback();
2503 IGnssNavigationMessage::GnssNavigationMessageStatus result =
2504 gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
2505
2506 if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
2507 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
destradaa4b3e3932014-07-21 18:01:47 -07002508 return JNI_FALSE;
2509 }
2510
2511 return JNI_TRUE;
2512}
2513
Yu-Han Yang23d92162018-04-19 06:03:00 -07002514static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07002515 JNIEnv* env,
2516 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002517 if (gnssNavigationMessageIface == nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07002518 ALOGE("Navigation Message interface is not available.");
2519 return JNI_FALSE;
2520 }
2521
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002522 auto result = gnssNavigationMessageIface->close();
Steven Morelandd002a8b2017-01-03 17:18:24 -08002523 return boolToJbool(result.isOk());
destradaa4b3e3932014-07-21 18:01:47 -07002524}
2525
Anil Admald71cf142018-12-21 14:59:36 -08002526static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,
2527 jobject,
2528 jint emergencySuplPdn) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002529 if (gnssConfigurationIface == nullptr) {
2530 ALOGE("no GNSS configuration interface available");
2531 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002532 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002533
2534 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002535 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002536 return result;
2537 } else {
2538 return JNI_FALSE;
2539 }
2540}
2541
Anil Admald71cf142018-12-21 14:59:36 -08002542static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002543 jobject,
2544 jint version) {
2545 if (gnssConfigurationIface == nullptr) {
2546 ALOGE("no GNSS configuration interface available");
2547 return JNI_FALSE;
2548 }
2549 auto result = gnssConfigurationIface->setSuplVersion(version);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002550 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002551 return result;
2552 } else {
2553 return JNI_FALSE;
2554 }
2555}
2556
Anil Admald71cf142018-12-21 14:59:36 -08002557static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*,
2558 jobject,
2559 jint suplEs) {
2560 if (gnssConfigurationIface_V2_0 != nullptr) {
2561 ALOGI("Config parameter SUPL_ES is deprecated in IGnssConfiguration.hal version 2.0.");
2562 return JNI_FALSE;
2563 }
2564
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002565 if (gnssConfigurationIface == nullptr) {
2566 ALOGE("no GNSS configuration interface available");
2567 return JNI_FALSE;
2568 }
2569
2570 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002571 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002572 return result;
2573 } else {
2574 return JNI_FALSE;
2575 }
2576}
2577
Anil Admald71cf142018-12-21 14:59:36 -08002578static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*,
2579 jobject,
2580 jint mode) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002581 if (gnssConfigurationIface == nullptr) {
2582 ALOGE("no GNSS configuration interface available");
2583 return JNI_FALSE;
2584 }
2585
2586 auto result = gnssConfigurationIface->setSuplMode(mode);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002587 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002588 return result;
2589 } else {
2590 return JNI_FALSE;
2591 }
2592}
2593
Anil Admald71cf142018-12-21 14:59:36 -08002594static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*,
2595 jobject,
2596 jint gpsLock) {
2597 if (gnssConfigurationIface_V2_0 != nullptr) {
2598 ALOGI("Config parameter GPS_LOCK is deprecated in IGnssConfiguration.hal version 2.0.");
2599 return JNI_FALSE;
2600 }
2601
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002602 if (gnssConfigurationIface == nullptr) {
2603 ALOGE("no GNSS configuration interface available");
2604 return JNI_FALSE;
2605 }
2606
2607 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002608 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002609 return result;
2610 } else {
2611 return JNI_FALSE;
2612 }
2613}
2614
Anil Admald71cf142018-12-21 14:59:36 -08002615static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002616 jobject,
2617 jint lppProfile) {
2618 if (gnssConfigurationIface == nullptr) {
2619 ALOGE("no GNSS configuration interface available");
2620 return JNI_FALSE;
2621 }
2622
2623 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
2624
Steven Morelandd002a8b2017-01-03 17:18:24 -08002625 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002626 return result;
2627 } else {
2628 return JNI_FALSE;
2629 }
2630}
2631
Anil Admald71cf142018-12-21 14:59:36 -08002632static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*,
2633 jobject,
2634 jint gnssPosProtocol) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002635 if (gnssConfigurationIface == nullptr) {
2636 ALOGE("no GNSS configuration interface available");
2637 return JNI_FALSE;
2638 }
2639
2640 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Steven Morelandd002a8b2017-01-03 17:18:24 -08002641 if (result.isOk()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002642 return result;
2643 } else {
2644 return JNI_FALSE;
2645 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002646}
2647
Anil Admald71cf142018-12-21 14:59:36 -08002648static jboolean android_location_GnssConfiguration_set_satellite_blacklist(
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002649 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
2650 if (gnssConfigurationIface_V1_1 == nullptr) {
2651 ALOGI("No GNSS Satellite Blacklist interface available");
2652 return JNI_FALSE;
2653 }
2654
2655 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002656 if (nullptr == constellation_array) {
2657 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002658 return JNI_FALSE;
2659 }
2660 jsize length = env->GetArrayLength(constellations);
2661
2662 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07002663 if (nullptr == sv_id_array) {
2664 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002665 return JNI_FALSE;
2666 }
2667
2668 if (length != env->GetArrayLength(sv_ids)) {
2669 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
2670 return JNI_FALSE;
2671 }
2672
2673 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
2674 sources.resize(length);
2675
2676 for (int i = 0; i < length; i++) {
2677 sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
2678 sources[i].svid = sv_id_array[i];
2679 }
2680
2681 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
2682 if (result.isOk()) {
2683 return result;
2684 } else {
2685 return JNI_FALSE;
2686 }
2687}
2688
Anil Admald71cf142018-12-21 14:59:36 -08002689static jboolean android_location_GnssConfiguration_set_es_extension_sec(
2690 JNIEnv*, jobject, jint emergencyExtensionSeconds) {
2691 if (gnssConfigurationIface == nullptr) {
2692 ALOGE("no GNSS configuration interface available");
2693 return JNI_FALSE;
2694 }
2695
2696 if (gnssConfigurationIface_V2_0 == nullptr) {
2697 ALOGI("Config parameter ES_EXTENSION_SEC is not supported in IGnssConfiguration.hal"
2698 " versions earlier than 2.0.");
2699 return JNI_FALSE;
2700 }
2701
2702 auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds);
2703 if (result.isOk()) {
2704 return result;
2705 } else {
2706 return JNI_FALSE;
2707 }
2708}
2709
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002710static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002711 if (gnssBatchingIface == nullptr) {
2712 return 0; // batching not supported, size = 0
2713 }
2714 auto result = gnssBatchingIface->getBatchSize();
2715 if (result.isOk()) {
2716 return static_cast<jint>(result);
2717 } else {
2718 return 0; // failure in binder, don't support batching
2719 }
2720}
2721
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002722static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002723 if (gnssBatchingIface == nullptr) {
2724 return JNI_FALSE; // batching not supported
2725 }
2726 sp<IGnssBatchingCallback> gnssBatchingCbIface = new GnssBatchingCallback();
2727
2728 return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface));
2729}
2730
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002731static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002732 if (gnssBatchingIface == nullptr) {
2733 return; // batching not supported
2734 }
2735 gnssBatchingIface->cleanup();
2736}
2737
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002738static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08002739 jlong periodNanos, jboolean wakeOnFifoFull) {
2740 if (gnssBatchingIface == nullptr) {
2741 return JNI_FALSE; // batching not supported
2742 }
2743
2744 IGnssBatching::Options options;
2745 options.periodNanos = periodNanos;
2746 if (wakeOnFifoFull) {
2747 options.flags = static_cast<uint8_t>(IGnssBatching::Flag::WAKEUP_ON_FIFO_FULL);
2748 } else {
2749 options.flags = 0;
2750 }
2751
2752 return static_cast<jboolean>(gnssBatchingIface->start(options));
2753}
2754
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002755static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002756 if (gnssBatchingIface == nullptr) {
2757 return; // batching not supported
2758 }
2759
2760 gnssBatchingIface->flush();
2761}
2762
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002763static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002764 if (gnssBatchingIface == nullptr) {
2765 return JNI_FALSE; // batching not supported
2766 }
2767
2768 return gnssBatchingIface->stop();
2769}
2770
Anil Admal94ec76a2019-01-15 09:42:01 -08002771static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
2772 JNIEnv* env, jobject, jobjectArray proxyApps) {
2773 if (gnssVisibilityControlIface == nullptr) {
2774 ALOGI("No GNSS Visibility Control interface available");
2775 return JNI_FALSE;
2776 }
2777
2778 const jsize length = env->GetArrayLength(proxyApps);
2779 hidl_vec<hidl_string> hidlProxyApps(length);
2780 for (int i = 0; i < length; ++i) {
2781 jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i));
2782 ScopedJniString jniProxyApp(env, proxyApp);
2783 hidlProxyApps[i] = jniProxyApp;
2784 }
2785
2786 auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
2787 if (result.isOk()) {
2788 return result;
2789 } else {
2790 return JNI_FALSE;
2791 }
2792}
2793
Daniel Micay76f6a862015-09-19 17:31:01 -04002794static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002796 {"class_init_native", "()V", reinterpret_cast<void *>(
2797 android_location_GnssLocationProvider_class_init_native)},
2798 {"native_is_supported", "()Z", reinterpret_cast<void *>(
2799 android_location_GnssLocationProvider_is_supported)},
Yu-Han Yang6d317352018-03-15 11:53:01 -07002800 {"native_init_once", "()V", reinterpret_cast<void *>(
2801 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002802 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
2803 {"native_cleanup", "()V", reinterpret_cast<void *>(
2804 android_location_GnssLocationProvider_cleanup)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002805 {"native_set_position_mode", "(IIIIIZ)Z", reinterpret_cast<void *>(
2806 android_location_GnssLocationProvider_set_position_mode)},
2807 {"native_start", "()Z", reinterpret_cast<void *>(
2808 android_location_GnssLocationProvider_start)},
2809 {"native_stop", "()Z", reinterpret_cast<void *>(
2810 android_location_GnssLocationProvider_stop)},
2811 {"native_delete_aiding_data", "(I)V", reinterpret_cast<void *>(
2812 android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002813 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
2814 android_location_GnssLocationProvider_read_nmea)},
2815 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
2816 android_location_GnssLocationProvider_inject_time)},
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +00002817 {"native_inject_best_location", "(IDDDFFFFFFJIJJ)V", reinterpret_cast<void *>(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002818 android_location_GnssLocationProvider_inject_best_location)},
2819 {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
2820 android_location_GnssLocationProvider_inject_location)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002821 {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
2822 android_location_GnssLocationProvider_supports_xtra)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002823 {"native_inject_xtra_data", "([BI)V", reinterpret_cast<void *>(
2824 android_location_GnssLocationProvider_inject_xtra_data)},
2825 {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void *>(
2826 android_location_GnssLocationProvider_agps_set_id)},
2827 {"native_agps_set_ref_location_cellid", "(IIIII)V", reinterpret_cast<void *>(
2828 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
2829 {"native_set_agps_server", "(ILjava/lang/String;I)V", reinterpret_cast<void *>(
2830 android_location_GnssLocationProvider_set_agps_server)},
2831 {"native_send_ni_response", "(II)V", reinterpret_cast<void *>(
2832 android_location_GnssLocationProvider_send_ni_response)},
2833 {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(
2834 android_location_GnssLocationProvider_get_internal_state)},
Anil Admal94ec76a2019-01-15 09:42:01 -08002835 {"native_is_gnss_visibility_control_supported", "()Z", reinterpret_cast<void *>(
2836 android_location_GnssLocationProvider_is_gnss_visibility_control_supported)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002837};
2838
2839static const JNINativeMethod sMethodsBatching[] = {
2840 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08002841 {"native_get_batch_size",
2842 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002843 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002844 {"native_start_batch",
2845 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002846 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002847 {"native_flush_batch",
2848 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002849 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002850 {"native_stop_batch",
2851 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002852 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002853 {"native_init_batching",
2854 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002855 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08002856 {"native_cleanup_batching",
2857 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002858 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859};
2860
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002861static const JNINativeMethod sGeofenceMethods[] = {
2862 /* name, signature, funcPtr */
2863 {"native_is_geofence_supported",
2864 "()Z",
2865 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
2866 {"native_add_geofence",
2867 "(IDDDIIII)Z",
2868 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
2869 {"native_remove_geofence",
2870 "(I)Z",
2871 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
2872 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
2873 android_location_GnssGeofenceProvider_pause_geofence)},
2874 {"native_resume_geofence",
2875 "(II)Z",
2876 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
2877};
2878
Yu-Han Yang8de21502018-04-23 01:40:25 -07002879static const JNINativeMethod sMeasurementMethods[] = {
gomo226b7b72018-12-12 16:49:39 -08002880 /* name, signature, funcPtr */
2881 {"native_is_measurement_supported", "()Z",
2882 reinterpret_cast<void*>(
2883 android_location_GnssMeasurementsProvider_is_measurement_supported)},
2884 {"native_start_measurement_collection", "(Z)Z",
2885 reinterpret_cast<void*>(
2886 android_location_GnssMeasurementsProvider_start_measurement_collection)},
2887 {"native_stop_measurement_collection", "()Z",
2888 reinterpret_cast<void*>(
2889 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
2890 {"native_inject_gnss_measurement_corrections",
2891 "(Landroid/location/GnssMeasurementCorrections;)Z",
2892 reinterpret_cast<void*>(
2893 android_location_GnssMeasurementsProvider_inject_gnss_measurement_corrections)},
Yu-Han Yang8de21502018-04-23 01:40:25 -07002894};
2895
Yu-Han Yang23d92162018-04-19 06:03:00 -07002896static const JNINativeMethod sNavigationMessageMethods[] = {
2897 /* name, signature, funcPtr */
2898 {"native_is_navigation_message_supported",
2899 "()Z",
2900 reinterpret_cast<void *>(
2901 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
2902 {"native_start_navigation_message_collection",
2903 "()Z",
2904 reinterpret_cast<void *>(
2905 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
2906 {"native_stop_navigation_message_collection",
2907 "()Z",
2908 reinterpret_cast<void *>(
2909 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
2910};
2911
Anil Admal50ba15e2018-11-01 16:42:42 -07002912static const JNINativeMethod sNetworkConnectivityMethods[] = {
2913 /* name, signature, funcPtr */
2914 {"native_is_agps_ril_supported", "()Z",
2915 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
2916 {"native_update_network_state",
Anil Admalb4995e22018-11-16 17:36:21 -08002917 "(ZIZZLjava/lang/String;JS)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07002918 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
2919 {"native_agps_data_conn_open",
Anil Admalc70344b2018-11-16 14:22:38 -08002920 "(JLjava/lang/String;I)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07002921 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
2922 {"native_agps_data_conn_closed",
2923 "()V",
2924 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
2925 {"native_agps_data_conn_failed",
2926 "()V",
2927 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
2928};
2929
Anil Admald71cf142018-12-21 14:59:36 -08002930static const JNINativeMethod sConfigurationMethods[] = {
2931 /* name, signature, funcPtr */
2932 {"native_get_gnss_configuration_version",
2933 "()Lcom/android/server/location/GnssConfiguration$HalInterfaceVersion;",
2934 reinterpret_cast<void *>(
2935 android_location_GnssConfiguration_get_gnss_configuration_version)},
2936 {"native_set_supl_es",
2937 "(I)Z",
2938 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_es)},
2939 {"native_set_supl_version",
2940 "(I)Z",
2941 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_version)},
2942 {"native_set_supl_mode",
2943 "(I)Z",
2944 reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_mode)},
2945 {"native_set_lpp_profile",
2946 "(I)Z",
2947 reinterpret_cast<void *>(android_location_GnssConfiguration_set_lpp_profile)},
2948 {"native_set_gnss_pos_protocol_select",
2949 "(I)Z",
2950 reinterpret_cast<void *>(
2951 android_location_GnssConfiguration_set_gnss_pos_protocol_select)},
2952 {"native_set_gps_lock",
2953 "(I)Z",
2954 reinterpret_cast<void *>(android_location_GnssConfiguration_set_gps_lock)},
2955 {"native_set_emergency_supl_pdn",
2956 "(I)Z",
2957 reinterpret_cast<void *>(android_location_GnssConfiguration_set_emergency_supl_pdn)},
2958 {"native_set_satellite_blacklist",
2959 "([I[I)Z",
2960 reinterpret_cast<void *>(android_location_GnssConfiguration_set_satellite_blacklist)},
2961 {"native_set_es_extension_sec",
2962 "(I)Z",
2963 reinterpret_cast<void *>(android_location_GnssConfiguration_set_es_extension_sec)},
2964};
2965
Anil Admal94ec76a2019-01-15 09:42:01 -08002966static const JNINativeMethod sVisibilityControlMethods[] = {
2967 /* name, signature, funcPtr */
2968 {"native_enable_nfw_location_access",
2969 "([Ljava/lang/String;)Z",
2970 reinterpret_cast<void *>(
2971 android_location_GnssVisibilityControl_enable_nfw_location_access)},
2972};
2973
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002974int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07002975 jniRegisterNativeMethods(
2976 env,
2977 "com/android/server/location/GnssBatchingProvider",
2978 sMethodsBatching,
2979 NELEM(sMethodsBatching));
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002980 jniRegisterNativeMethods(
2981 env,
2982 "com/android/server/location/GnssGeofenceProvider",
2983 sGeofenceMethods,
2984 NELEM(sGeofenceMethods));
Yu-Han Yang8de21502018-04-23 01:40:25 -07002985 jniRegisterNativeMethods(
2986 env,
2987 "com/android/server/location/GnssMeasurementsProvider",
2988 sMeasurementMethods,
2989 NELEM(sMeasurementMethods));
Yu-Han Yang23d92162018-04-19 06:03:00 -07002990 jniRegisterNativeMethods(
2991 env,
2992 "com/android/server/location/GnssNavigationMessageProvider",
2993 sNavigationMessageMethods,
2994 NELEM(sNavigationMessageMethods));
Anil Admal50ba15e2018-11-01 16:42:42 -07002995 jniRegisterNativeMethods(
2996 env,
2997 "com/android/server/location/GnssNetworkConnectivityHandler",
2998 sNetworkConnectivityMethods,
2999 NELEM(sNetworkConnectivityMethods));
Anil Admald71cf142018-12-21 14:59:36 -08003000 jniRegisterNativeMethods(
3001 env,
3002 "com/android/server/location/GnssConfiguration",
3003 sConfigurationMethods,
3004 NELEM(sConfigurationMethods));
Anil Admal94ec76a2019-01-15 09:42:01 -08003005 jniRegisterNativeMethods(
3006 env,
3007 "com/android/server/location/GnssVisibilityControl",
3008 sVisibilityControlMethods,
3009 NELEM(sVisibilityControlMethods));
destradaaea8a8a62014-06-23 18:19:03 -07003010 return jniRegisterNativeMethods(
3011 env,
Lifu Tang30f95a72016-01-07 23:20:38 -08003012 "com/android/server/location/GnssLocationProvider",
destradaaea8a8a62014-06-23 18:19:03 -07003013 sMethods,
3014 NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015}
3016
3017} /* namespace android */