blob: 465a3518ab659fff20249e81307777934c5dc884 [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>
Yu-Han Yang5b9a3362019-11-10 13:31:03 -080024#include <android/hardware/gnss/2.1/IGnss.h>
Hridya Valsaraju2ea29602016-09-13 08:38:09 -070025
gomo48f1a642017-11-10 20:35:46 -080026#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
27#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
Yu-Han Yang88d79102018-11-14 14:20:57 -080028#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +000029#include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
Yu-Han Yang5b9a3362019-11-10 13:31:03 -080030#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
gomo226b7b72018-12-12 16:49:39 -080031#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -080032#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
Anil Admal94ec76a2019-01-15 09:42:01 -080033#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
Steven Morelandc95dca82017-08-01 10:18:40 -070034#include <nativehelper/JNIHelp.h>
Yu-Han Yangfef92472020-02-11 04:02:18 +000035#include "android_runtime/AndroidRuntime.h"
36#include "android_runtime/Log.h"
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +000037#include "hardware_legacy/power.h"
38#include "jni.h"
39#include "utils/Log.h"
40#include "utils/misc.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
destradaa931a37f2014-08-12 16:36:59 -070042#include <arpa/inet.h>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -080043#include <cinttypes>
44#include <iomanip>
Lifu Tang38bce792016-02-24 17:17:38 -080045#include <limits>
destradaa96a14702014-06-05 11:36:30 -070046#include <linux/in.h>
47#include <linux/in6.h>
Lifu Tang38bce792016-02-24 17:17:38 -080048#include <pthread.h>
49#include <string.h>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -080050#include <utils/SystemClock.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
Yu-Han Yang1a789452019-04-29 18:40:29 -070052static jclass class_gnssMeasurementsEvent;
53static jclass class_gnssMeasurement;
54static jclass class_location;
55static jclass class_gnssNavigationMessage;
56static jclass class_gnssClock;
57static jclass class_gnssConfiguration_halInterfaceVersion;
Sasha Kuznetsov213bb702020-02-14 16:14:39 -080058static jclass class_gnssAntennaInfoBuilder;
59static jclass class_phaseCenterOffset;
60static jclass class_sphericalCorrections;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +000061static jclass class_arrayList;
62static jclass class_doubleArray;
Yu-Han Yang1a789452019-04-29 18:40:29 -070063
WyattRiley840c0b22018-10-31 09:03:53 -070064static jobject mCallbacksObj = nullptr;
Mike Lockwoodf602d362010-06-20 14:28:16 -070065
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066static jmethodID method_reportLocation;
67static jmethodID method_reportStatus;
68static jmethodID method_reportSvStatus;
Mike Lockwoode3635c92009-05-11 08:38:02 -040069static jmethodID method_reportAGpsStatus;
Mike Lockwoodb16e7802009-08-06 09:26:02 -040070static jmethodID method_reportNmea;
Anil Admal312fddb2019-03-25 12:15:43 -070071static jmethodID method_setTopHalCapabilities;
Lifu Tang9363b942016-02-16 18:07:00 -080072static jmethodID method_setGnssYearOfHardware;
Wyatt Rileyd87cf912017-12-05 09:31:52 -080073static jmethodID method_setGnssHardwareModelName;
Kevin Tang8c6ac672019-03-22 12:31:01 -070074static jmethodID method_psdsDownloadRequest;
Danke Xie22d1f9f2009-08-18 18:28:45 -040075static jmethodID method_reportNiNotification;
Yu-Han Yange7baef32018-02-09 13:58:17 -080076static jmethodID method_requestLocation;
Miguel Torroja1e84da82010-07-27 07:02:24 +020077static jmethodID method_requestRefLocation;
78static jmethodID method_requestSetID;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -040079static jmethodID method_requestUtcTime;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070080static jmethodID method_reportGeofenceTransition;
81static jmethodID method_reportGeofenceStatus;
82static jmethodID method_reportGeofenceAddStatus;
83static jmethodID method_reportGeofenceRemoveStatus;
84static jmethodID method_reportGeofencePauseStatus;
85static jmethodID method_reportGeofenceResumeStatus;
destradaaea8a8a62014-06-23 18:19:03 -070086static jmethodID method_reportMeasurementData;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +000087static jmethodID method_reportAntennaInfo;
destradaa4b3e3932014-07-21 18:01:47 -070088static jmethodID method_reportNavigationMessages;
Wyatt Rileycf879db2017-01-12 13:57:38 -080089static jmethodID method_reportLocationBatch;
Yu-Han Yang52057622018-04-25 00:51:22 -070090static jmethodID method_reportGnssServiceDied;
Anil Admal312fddb2019-03-25 12:15:43 -070091static jmethodID method_setSubHalMeasurementCorrectionsCapabilities;
gomo226b7b72018-12-12 16:49:39 -080092static jmethodID method_correctionsGetLatitudeDegrees;
93static jmethodID method_correctionsGetLongitudeDegrees;
94static jmethodID method_correctionsGetAltitudeMeters;
gomo6ec95382019-01-26 03:08:18 -080095static jmethodID method_correctionsGetHorPosUncMeters;
96static jmethodID method_correctionsGetVerPosUncMeters;
gomo226b7b72018-12-12 16:49:39 -080097static jmethodID method_correctionsGetToaGpsNanosecondsOfWeek;
98static jmethodID method_correctionsGetSingleSatCorrectionList;
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -080099static jmethodID method_correctionsHasEnvironmentBearing;
100static jmethodID method_correctionsGetEnvironmentBearingDegrees;
101static jmethodID method_correctionsGetEnvironmentBearingUncertaintyDegrees;
gomo226b7b72018-12-12 16:49:39 -0800102static jmethodID method_listSize;
103static jmethodID method_correctionListGet;
104static jmethodID method_correctionSatFlags;
105static jmethodID method_correctionSatConstType;
106static jmethodID method_correctionSatId;
107static jmethodID method_correctionSatCarrierFreq;
gomob4635ba2019-01-17 04:02:53 -0800108static jmethodID method_correctionSatIsLosProb;
gomo226b7b72018-12-12 16:49:39 -0800109static jmethodID method_correctionSatEpl;
110static jmethodID method_correctionSatEplUnc;
111static jmethodID method_correctionSatRefPlane;
112static jmethodID method_correctionPlaneLatDeg;
113static jmethodID method_correctionPlaneLngDeg;
114static jmethodID method_correctionPlaneAltDeg;
115static jmethodID method_correctionPlaneAzimDeg;
Anil Admal94ec76a2019-01-15 09:42:01 -0800116static jmethodID method_reportNfwNotification;
117static jmethodID method_isInEmergencySession;
Yu-Han Yang1a789452019-04-29 18:40:29 -0700118static jmethodID method_gnssMeasurementsEventCtor;
119static jmethodID method_locationCtor;
120static jmethodID method_gnssNavigationMessageCtor;
121static jmethodID method_gnssClockCtor;
122static jmethodID method_gnssMeasurementCtor;
123static jmethodID method_halInterfaceVersionCtor;
Sasha Kuznetsov213bb702020-02-14 16:14:39 -0800124static jmethodID method_gnssAntennaInfoBuilderCtor;
125static jmethodID method_phaseCenterOffsetCtor;
126static jmethodID method_sphericalCorrectionsCtor;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000127static jmethodID method_arrayListCtor;
128static jmethodID method_arrayListAdd;
Sasha Kuznetsov213bb702020-02-14 16:14:39 -0800129static jmethodID method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz;
130static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterOffset;
131static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections;
132static jmethodID method_gnssAntennaInfoBuilderSetSignalGainCorrections;
133static jmethodID method_gnssAntennaInfoBuilderBuild;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800135/*
136 * Save a pointer to JavaVm to attach/detach threads executing
137 * callback methods that need to make JNI calls.
138 */
139static JavaVM* sJvm;
140
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700141using android::OK;
142using android::sp;
gomo25208882017-04-15 02:05:25 -0700143using android::wp;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700144using android::status_t;
145using android::String16;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700147using android::hardware::Return;
148using android::hardware::Void;
149using android::hardware::hidl_vec;
Anil Admalc70344b2018-11-16 14:22:38 -0800150using android::hardware::hidl_string;
gomo25208882017-04-15 02:05:25 -0700151using android::hardware::hidl_death_recipient;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800152
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800153using android::hardware::gnss::V1_0::GnssLocationFlags;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700154using android::hardware::gnss::V1_0::IAGnssRilCallback;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700155using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
156using android::hardware::gnss::V1_0::IGnssGeofencing;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700157using android::hardware::gnss::V1_0::IGnssNavigationMessage;
158using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
159using android::hardware::gnss::V1_0::IGnssNi;
160using android::hardware::gnss::V1_0::IGnssNiCallback;
161using android::hardware::gnss::V1_0::IGnssXtra;
162using android::hardware::gnss::V1_0::IGnssXtraCallback;
Wyatt Rileybb9bc842018-02-14 08:46:00 -0800163
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800164using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800165
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -0800166using MeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
167using MeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
168
Sasha Kuznetsovb6b98482020-02-19 11:57:51 -0800169using SingleSatCorrection_V1_0 =
170 android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
171using SingleSatCorrection_V1_1 =
172 android::hardware::gnss::measurement_corrections::V1_1::SingleSatCorrection;
gomo226b7b72018-12-12 16:49:39 -0800173using android::hardware::gnss::measurement_corrections::V1_0::ReflectingPlane;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800174
175using android::hidl::base::V1_0::IBase;
176
Sasha Kuznetsovae89e782019-12-13 20:35:06 -0800177using GnssConstellationType_V1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
178using GnssConstellationType_V2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800179using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
180using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800181using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
182using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800183using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800184using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700185using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800186using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback;
187using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700188using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
189using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
Anil Admald71cf142018-12-21 14:59:36 -0800190using IGnssConfiguration_V2_0 = android::hardware::gnss::V2_0::IGnssConfiguration;
Sasha Kuznetsovae89e782019-12-13 20:35:06 -0800191using IGnssConfiguration_V2_1 = android::hardware::gnss::V2_1::IGnssConfiguration;
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700192using IGnssDebug_V1_0 = android::hardware::gnss::V1_0::IGnssDebug;
193using IGnssDebug_V2_0 = android::hardware::gnss::V2_0::IGnssDebug;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000194using IGnssAntennaInfo = android::hardware::gnss::V2_1::IGnssAntennaInfo;
195using IGnssAntennaInfoCallback = android::hardware::gnss::V2_1::IGnssAntennaInfoCallback;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800196using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
197using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800198using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800199using IGnssMeasurement_V2_1 = android::hardware::gnss::V2_1::IGnssMeasurement;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800200using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
201using IGnssMeasurementCallback_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800202using IGnssMeasurementCallback_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800203using IGnssMeasurementCallback_V2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback;
Anil Admalb4995e22018-11-16 17:36:21 -0800204using IAGnssRil_V1_0 = android::hardware::gnss::V1_0::IAGnssRil;
205using IAGnssRil_V2_0 = android::hardware::gnss::V2_0::IAGnssRil;
Anil Admalc70344b2018-11-16 14:22:38 -0800206using IAGnss_V1_0 = android::hardware::gnss::V1_0::IAGnss;
207using IAGnss_V2_0 = android::hardware::gnss::V2_0::IAGnss;
208using IAGnssCallback_V1_0 = android::hardware::gnss::V1_0::IAGnssCallback;
209using IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
Anil Admalb8c235e2019-03-21 18:46:58 +0000210using IGnssBatching_V1_0 = android::hardware::gnss::V1_0::IGnssBatching;
211using IGnssBatching_V2_0 = android::hardware::gnss::V2_0::IGnssBatching;
212using IGnssBatchingCallback_V1_0 = android::hardware::gnss::V1_0::IGnssBatchingCallback;
213using IGnssBatchingCallback_V2_0 = android::hardware::gnss::V2_0::IGnssBatchingCallback;
Wyatt Rileyfb840922017-11-08 15:07:58 -0800214
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -0800215using IMeasurementCorrections_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
216using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_corrections::V1_1::IMeasurementCorrections;
Anil Admalefd9dc62019-03-12 17:39:20 -0700217using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
218using android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
gomo226b7b72018-12-12 16:49:39 -0800219
Anil Admal94ec76a2019-01-15 09:42:01 -0800220using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
221using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
222
gomo25208882017-04-15 02:05:25 -0700223struct GnssDeathRecipient : virtual public hidl_death_recipient
224{
225 // hidl_death_recipient interface
226 virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
Yu-Han Yang52057622018-04-25 00:51:22 -0700227 ALOGE("IGNSS hidl service failed, trying to recover...");
228
229 JNIEnv* env = android::AndroidRuntime::getJNIEnv();
230 env->CallVoidMethod(mCallbacksObj, method_reportGnssServiceDied);
gomo25208882017-04-15 02:05:25 -0700231 }
232};
Wyatt Rileyf6527ae2016-05-23 15:23:12 -0700233
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800234// Must match the value from GnssMeasurement.java
235static const uint32_t ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
Yu-Han Yang3ffaf3a2020-01-10 17:24:47 -0800236static const uint32_t SVID_FLAGS_HAS_BASEBAND_CN0 = (1<<4);
Wyatt Riley4cbcb412018-01-23 18:07:05 -0800237
gomo25208882017-04-15 02:05:25 -0700238sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
Wyatt Riley46ac9562018-03-02 20:16:58 -0800239sp<IGnss_V1_0> gnssHal = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800240sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800241sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800242sp<IGnss_V2_1> gnssHal_V2_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700243sp<IGnssXtra> gnssXtraIface = nullptr;
Anil Admalb4995e22018-11-16 17:36:21 -0800244sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
245sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700246sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
Anil Admalc70344b2018-11-16 14:22:38 -0800247sp<IAGnss_V1_0> agnssIface = nullptr;
248sp<IAGnss_V2_0> agnssIface_V2_0 = nullptr;
Anil Admalb8c235e2019-03-21 18:46:58 +0000249sp<IGnssBatching_V1_0> gnssBatchingIface = nullptr;
250sp<IGnssBatching_V2_0> gnssBatchingIface_V2_0 = nullptr;
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700251sp<IGnssDebug_V1_0> gnssDebugIface = nullptr;
252sp<IGnssDebug_V2_0> gnssDebugIface_V2_0 = nullptr;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700253sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
254sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
Anil Admald71cf142018-12-21 14:59:36 -0800255sp<IGnssConfiguration_V2_0> gnssConfigurationIface_V2_0 = nullptr;
Sasha Kuznetsovae89e782019-12-13 20:35:06 -0800256sp<IGnssConfiguration_V2_1> gnssConfigurationIface_V2_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700257sp<IGnssNi> gnssNiIface = nullptr;
gomo48f1a642017-11-10 20:35:46 -0800258sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
259sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
Yu-Han Yang88d79102018-11-14 14:20:57 -0800260sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800261sp<IGnssMeasurement_V2_1> gnssMeasurementIface_V2_1 = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700262sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -0800263sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr;
264sp<IMeasurementCorrections_V1_1> gnssCorrectionsIface_V1_1 = nullptr;
Anil Admal94ec76a2019-01-15 09:42:01 -0800265sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000266sp<IGnssAntennaInfo> gnssAntennaInfoIface = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267
Mike Lockwood8f5a8002010-04-07 09:05:26 -0400268#define WAKE_LOCK_NAME "GPS"
269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270namespace android {
271
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800272namespace {
273
274// Returns true if location has lat/long information.
275bool hasLatLong(const GnssLocation_V1_0& location) {
276 return (static_cast<uint32_t>(location.gnssLocationFlags) &
277 GnssLocationFlags::HAS_LAT_LONG) != 0;
278}
279
280// Returns true if location has lat/long information.
281bool hasLatLong(const GnssLocation_V2_0& location) {
282 return hasLatLong(location.v1_0);
283}
284
285} // namespace
Lifu Tang120480f2016-02-07 18:08:19 -0800286template<class T>
287class JavaMethodHelper {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700288 public:
289 // Helper function to call setter on a Java object.
290 static void callJavaMethod(
Lifu Tang120480f2016-02-07 18:08:19 -0800291 JNIEnv* env,
292 jclass clazz,
293 jobject object,
294 const char* method_name,
295 T value);
destradaaea8a8a62014-06-23 18:19:03 -0700296
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700297 private:
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800298 static const char* const signature_;
Lifu Tang120480f2016-02-07 18:08:19 -0800299};
Lifu Tange5a0e212016-01-25 18:02:17 -0800300
Lifu Tang120480f2016-02-07 18:08:19 -0800301template<class T>
302void JavaMethodHelper<T>::callJavaMethod(
303 JNIEnv* env,
304 jclass clazz,
305 jobject object,
306 const char* method_name,
307 T value) {
308 jmethodID method = env->GetMethodID(clazz, method_name, signature_);
309 env->CallVoidMethod(object, method, value);
310}
destradaaea8a8a62014-06-23 18:19:03 -0700311
Lifu Tang120480f2016-02-07 18:08:19 -0800312class JavaObject {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700313 public:
Yu-Han Yang1a789452019-04-29 18:40:29 -0700314 JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor);
315 JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char * sz_arg_1);
316 JavaObject(JNIEnv* env, jclass clazz, jobject object);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800317
Yu-Han Yang1a789452019-04-29 18:40:29 -0700318 virtual ~JavaObject() = default;
Lifu Tang120480f2016-02-07 18:08:19 -0800319
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700320 template<class T>
321 void callSetter(const char* method_name, T value);
322 template<class T>
323 void callSetter(const char* method_name, T* value, size_t size);
324 jobject get();
Lifu Tang120480f2016-02-07 18:08:19 -0800325
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700326 private:
327 JNIEnv* env_;
328 jclass clazz_;
329 jobject object_;
Lifu Tang120480f2016-02-07 18:08:19 -0800330};
331
Yu-Han Yang1a789452019-04-29 18:40:29 -0700332JavaObject::JavaObject(JNIEnv* env, jclass clazz, jmethodID defaultCtor) : env_(env),
333 clazz_(clazz) {
334 object_ = env_->NewObject(clazz_, defaultCtor);
Lifu Tang120480f2016-02-07 18:08:19 -0800335}
336
Yu-Han Yang1a789452019-04-29 18:40:29 -0700337
338JavaObject::JavaObject(JNIEnv* env, jclass clazz, jmethodID stringCtor, const char * sz_arg_1)
339 : env_(env), clazz_(clazz) {
Yu-Han Yangc19b3a82020-05-27 16:18:16 -0700340 jstring szArg = env->NewStringUTF(sz_arg_1);
341 object_ = env_->NewObject(clazz_, stringCtor, szArg);
342 if (szArg) {
343 env_->DeleteLocalRef(szArg);
344 }
Wyatt Rileycf879db2017-01-12 13:57:38 -0800345}
346
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800347
Yu-Han Yang1a789452019-04-29 18:40:29 -0700348JavaObject::JavaObject(JNIEnv* env, jclass clazz, jobject object)
349 : env_(env), clazz_(clazz), object_(object) {
Lifu Tang120480f2016-02-07 18:08:19 -0800350}
351
352template<class T>
353void JavaObject::callSetter(const char* method_name, T value) {
354 JavaMethodHelper<T>::callJavaMethod(
355 env_, clazz_, object_, method_name, value);
356}
357
358template<>
359void JavaObject::callSetter(
360 const char* method_name, uint8_t* value, size_t size) {
361 jbyteArray array = env_->NewByteArray(size);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700362 env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
Lifu Tang120480f2016-02-07 18:08:19 -0800363 jmethodID method = env_->GetMethodID(
364 clazz_,
365 method_name,
366 "([B)V");
367 env_->CallVoidMethod(object_, method, array);
Lifu Tangfe427f22016-10-08 02:57:53 -0700368 env_->DeleteLocalRef(array);
Lifu Tang120480f2016-02-07 18:08:19 -0800369}
370
371jobject JavaObject::get() {
372 return object_;
373}
374
375// Define Java method signatures for all known types.
Lifu Tang120480f2016-02-07 18:08:19 -0800376template<>
377const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
378template<>
379const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
380template<>
381const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
382template<>
383const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
384template<>
Lifu Tang9363b942016-02-16 18:07:00 -0800385const char *const JavaMethodHelper<int32_t>::signature_ = "(I)V";
386template<>
387const char *const JavaMethodHelper<uint32_t>::signature_ = "(I)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800388template<>
389const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
390template<>
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800391const char *const JavaMethodHelper<uint64_t>::signature_ = "(J)V";
392template<>
Lifu Tang120480f2016-02-07 18:08:19 -0800393const char *const JavaMethodHelper<float>::signature_ = "(F)V";
394template<>
395const char *const JavaMethodHelper<double>::signature_ = "(D)V";
396template<>
397const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
Yu-Han Yangfbcc5cf2019-03-11 12:01:10 -0700398template<>
Yu-Han Yang62c6c692019-03-15 14:00:02 -0700399const char *const JavaMethodHelper<jstring>::signature_ = "(Ljava/lang/String;)V";
Lifu Tang120480f2016-02-07 18:08:19 -0800400
401#define SET(setter, value) object.callSetter("set" # setter, (value))
Lifu Tangccb44882016-03-09 19:32:29 -0800402
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700403static inline jboolean boolToJbool(bool value) {
404 return value ? JNI_TRUE : JNI_FALSE;
405}
Lifu Tang120480f2016-02-07 18:08:19 -0800406
Anil Admal2ac70462019-06-28 19:17:41 -0700407template<class T>
408static inline void logHidlError(Return<T>& result, const char* errorMessage) {
409 ALOGE("%s HIDL transport error: %s", errorMessage, result.description().c_str());
410}
411
412template<class T>
413static jboolean checkHidlReturn(Return<T>& result, const char* errorMessage) {
414 if (!result.isOk()) {
415 logHidlError(result, errorMessage);
416 return JNI_FALSE;
417 } else {
418 return JNI_TRUE;
419 }
420}
421
422static jboolean checkHidlReturn(Return<bool>& result, const char* errorMessage) {
423 if (!result.isOk()) {
424 logHidlError(result, errorMessage);
425 return JNI_FALSE;
426 } else if (!result) {
427 ALOGE("%s", errorMessage);
428 return JNI_FALSE;
429 } else {
430 return JNI_TRUE;
431 }
432}
433
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700434static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
435 if (env->ExceptionCheck()) {
436 ALOGE("An exception was thrown by callback '%s'.", methodName);
437 LOGE_EX(env);
438 env->ExceptionClear();
439 }
440}
destradaaea8a8a62014-06-23 18:19:03 -0700441
Anil Admald71cf142018-12-21 14:59:36 -0800442static jobject createHalInterfaceVersionJavaObject(JNIEnv* env, jint major, jint minor) {
Yu-Han Yang1a789452019-04-29 18:40:29 -0700443 jobject version = env->NewObject(class_gnssConfiguration_halInterfaceVersion,
444 method_halInterfaceVersionCtor, major, minor);
Anil Admald71cf142018-12-21 14:59:36 -0800445 return version;
446}
447
Anil Admalc70344b2018-11-16 14:22:38 -0800448struct ScopedJniString {
449 ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) {
450 mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr);
451 }
452
453 ~ScopedJniString() {
454 if (mNativeString != nullptr) {
455 mEnv->ReleaseStringUTFChars(mJavaString, mNativeString);
456 }
457 }
458
459 const char* c_str() const {
460 return mNativeString;
461 }
462
463 operator hidl_string() const {
464 return hidl_string(mNativeString);
465 }
466
467private:
468 ScopedJniString(const ScopedJniString&) = delete;
469 ScopedJniString& operator=(const ScopedJniString&) = delete;
470
471 JNIEnv* mEnv;
472 jstring mJavaString;
473 const char* mNativeString;
474};
475
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800476class ScopedJniThreadAttach {
477public:
478 ScopedJniThreadAttach() {
479 /*
480 * attachResult will also be JNI_OK if the thead was already attached to
481 * JNI before the call to AttachCurrentThread().
482 */
483 jint attachResult = sJvm->AttachCurrentThread(&mEnv, nullptr);
484 LOG_ALWAYS_FATAL_IF(attachResult != JNI_OK, "Unable to attach thread. Error %d",
485 attachResult);
486 }
487
488 ~ScopedJniThreadAttach() {
489 jint detachResult = sJvm->DetachCurrentThread();
490 /*
491 * Return if the thread was already detached. Log error for any other
492 * failure.
493 */
494 if (detachResult == JNI_EDETACHED) {
495 return;
496 }
497
498 LOG_ALWAYS_FATAL_IF(detachResult != JNI_OK, "Unable to detach thread. Error %d",
499 detachResult);
500 }
501
502 JNIEnv* getEnv() {
503 /*
504 * Checking validity of mEnv in case the thread was detached elsewhere.
505 */
506 LOG_ALWAYS_FATAL_IF(AndroidRuntime::getJNIEnv() != mEnv);
507 return mEnv;
508 }
509
510private:
511 JNIEnv* mEnv = nullptr;
512};
513
514thread_local std::unique_ptr<ScopedJniThreadAttach> tJniThreadAttacher;
515
516static JNIEnv* getJniEnv() {
517 JNIEnv* env = AndroidRuntime::getJNIEnv();
518
519 /*
520 * If env is nullptr, the thread is not already attached to
521 * JNI. It is attached below and the destructor for ScopedJniThreadAttach
522 * will detach it on thread exit.
523 */
524 if (env == nullptr) {
525 tJniThreadAttacher.reset(new ScopedJniThreadAttach());
526 env = tJniThreadAttacher->getEnv();
527 }
528
529 return env;
530}
531
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800532static jobject translateGnssLocation(JNIEnv* env,
533 const GnssLocation_V1_0& location) {
Yu-Han Yang1a789452019-04-29 18:40:29 -0700534 JavaObject object(env, class_location, method_locationCtor, "gps");
Wyatt Riley5d229832017-02-10 17:06:00 -0800535
536 uint16_t flags = static_cast<uint32_t>(location.gnssLocationFlags);
Wyatt Rileyfb840922017-11-08 15:07:58 -0800537 if (flags & GnssLocationFlags::HAS_LAT_LONG) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800538 SET(Latitude, location.latitudeDegrees);
539 SET(Longitude, location.longitudeDegrees);
540 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800541 if (flags & GnssLocationFlags::HAS_ALTITUDE) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800542 SET(Altitude, location.altitudeMeters);
543 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800544 if (flags & GnssLocationFlags::HAS_SPEED) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800545 SET(Speed, location.speedMetersPerSec);
546 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800547 if (flags & GnssLocationFlags::HAS_BEARING) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800548 SET(Bearing, location.bearingDegrees);
549 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800550 if (flags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800551 SET(Accuracy, location.horizontalAccuracyMeters);
552 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800553 if (flags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800554 SET(VerticalAccuracyMeters, location.verticalAccuracyMeters);
555 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800556 if (flags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800557 SET(SpeedAccuracyMetersPerSecond, location.speedAccuracyMetersPerSecond);
558 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800559 if (flags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
Wyatt Riley5d229832017-02-10 17:06:00 -0800560 SET(BearingAccuracyDegrees, location.bearingAccuracyDegrees);
561 }
562 SET(Time, location.timestamp);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800563 SET(ElapsedRealtimeNanos, android::elapsedRealtimeNano());
Wyatt Riley5d229832017-02-10 17:06:00 -0800564
565 return object.get();
566}
567
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800568static jobject translateGnssLocation(JNIEnv* env,
569 const GnssLocation_V2_0& location) {
Yu-Han Yang1a789452019-04-29 18:40:29 -0700570 JavaObject object(env, class_location, translateGnssLocation(env, location.v1_0));
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800571
572 const uint16_t flags = static_cast<uint16_t>(location.elapsedRealtime.flags);
573
574 // Overwrite ElapsedRealtimeNanos when available from HAL.
575 if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
576 SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
577 }
578
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000579 if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
Yu-Han Yang3cd9a862019-03-25 17:00:03 -0700580 SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(location.elapsedRealtime.timeUncertaintyNs));
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000581 }
582
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800583 return object.get();
584}
585
586static GnssLocation_V1_0 createGnssLocation_V1_0(
587 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
588 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
589 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
590 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
Yu-Han Yange7baef32018-02-09 13:58:17 -0800591 jlong timestamp) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800592 GnssLocation_V1_0 location;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800593 location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
594 location.latitudeDegrees = static_cast<double>(latitudeDegrees);
595 location.longitudeDegrees = static_cast<double>(longitudeDegrees);
596 location.altitudeMeters = static_cast<double>(altitudeMeters);
597 location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
598 location.bearingDegrees = static_cast<float>(bearingDegrees);
599 location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
600 location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
601 location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
602 location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
603 location.timestamp = static_cast<uint64_t>(timestamp);
604
605 return location;
606}
607
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800608static GnssLocation_V2_0 createGnssLocation_V2_0(
609 jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
610 jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
611 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
612 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000613 jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
Yu-Han Yang3cd9a862019-03-25 17:00:03 -0700614 jdouble elapsedRealtimeUncertaintyNanos) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800615 GnssLocation_V2_0 location;
616 location.v1_0 = createGnssLocation_V1_0(
617 gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
618 speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
619 verticalAccuracyMeters, speedAccuracyMetersPerSecond,
620 bearingAccuracyDegrees, timestamp);
621
622 location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
623 location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +0000624 location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800625
626 return location;
627}
628
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700629/*
630 * GnssCallback class implements the callback methods for IGnss interface.
631 */
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800632struct GnssCallback : public IGnssCallback_V2_1 {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800633 Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800634 Return<void> gnssStatusCb(const IGnssCallback_V1_0::GnssStatusValue status) override;
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700635 Return<void> gnssSvStatusCb(const IGnssCallback_V1_0::GnssSvStatus& svStatus) override {
636 return gnssSvStatusCbImpl(svStatus);
637 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700638 Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
639 Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
640 Return<void> gnssAcquireWakelockCb() override;
641 Return<void> gnssReleaseWakelockCb() override;
642 Return<void> gnssRequestTimeCb() override;
Yu-Han Yang21988932018-01-23 15:07:37 -0800643 Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800644
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800645 Return<void> gnssSetSystemInfoCb(const IGnssCallback_V1_0::GnssSystemInfo& info) override;
Lifu Tang38bce792016-02-24 17:17:38 -0800646
Wyatt Rileyfb840922017-11-08 15:07:58 -0800647 // New in 1.1
648 Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
649
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800650 // New in 2.0
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800651 Return<void> gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool isUserEmergency)
652 override;
gomo226b7b72018-12-12 16:49:39 -0800653 Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800654 Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800655 Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList) override {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700656 return gnssSvStatusCbImpl(svInfoList);
657 }
Yu-Han Yang2ce47332020-02-13 16:08:48 -0800658
659 // New in 2.1
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800660 Return<void> gnssSvStatusCb_2_1(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList) override {
661 return gnssSvStatusCbImpl(svInfoList);
662 }
Yu-Han Yang2ce47332020-02-13 16:08:48 -0800663 Return<void> gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override;
Anil Admalefd9dc62019-03-12 17:39:20 -0700664
665 // TODO: Reconsider allocation cost vs threadsafety on these statics
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700666 static const char* sNmeaString;
667 static size_t sNmeaStringLength;
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700668private:
669 template<class T>
670 Return<void> gnssLocationCbImpl(const T& location);
671
672 template<class T>
673 Return<void> gnssSvStatusCbImpl(const T& svStatus);
674
Yu-Han Yang3ffaf3a2020-01-10 17:24:47 -0800675 template<class T>
676 uint32_t getHasBasebandCn0DbHzFlag(const T& svStatus) {
677 return 0;
678 }
679
680 template<class T>
681 double getBasebandCn0DbHz(const T& svStatus, size_t i) {
682 return 0.0;
683 }
684
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700685 uint32_t getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) {
686 return svStatus.numSvs;
687 }
688
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800689 uint32_t getGnssSvInfoListSize(const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList) {
690 return svInfoList.size();
691 }
692
693 uint32_t getGnssSvInfoListSize(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700694 return svInfoList.size();
695 }
696
697 const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
698 const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) {
699 return svStatus.gnssSvList.data()[i];
700 }
701
702 const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800703 const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList, size_t i) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700704 return svInfoList[i].v1_0;
705 }
706
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800707 const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
708 const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800709 return svInfoList[i].v2_0.v1_0;
710 }
711
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700712 uint32_t getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) {
713 return static_cast<uint32_t>(svStatus.gnssSvList.data()[i].constellation);
714 }
715
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800716 uint32_t getConstellationType(const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList, size_t i) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700717 return static_cast<uint32_t>(svInfoList[i].constellation);
718 }
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800719
720 uint32_t getConstellationType(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
721 return static_cast<uint32_t>(svInfoList[i].v2_0.constellation);
722 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700723};
724
Wyatt Rileyfb840922017-11-08 15:07:58 -0800725Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
726 ALOGD("%s: name=%s\n", __func__, name.c_str());
727
Wyatt Rileyfb840922017-11-08 15:07:58 -0800728 JNIEnv* env = getJniEnv();
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800729 jstring jstringName = env->NewStringUTF(name.c_str());
730 env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
Yu-Han Yangc19b3a82020-05-27 16:18:16 -0700731 if (jstringName) {
732 env->DeleteLocalRef(jstringName);
733 }
Wyatt Rileyfb840922017-11-08 15:07:58 -0800734 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800735
Wyatt Rileyfb840922017-11-08 15:07:58 -0800736 return Void();
737}
738
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700739const char* GnssCallback::sNmeaString = nullptr;
740size_t GnssCallback::sNmeaStringLength = 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700741
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800742template<class T>
743Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800744 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800745
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800746 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800747
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700748 env->CallVoidMethod(mCallbacksObj,
749 method_reportLocation,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800750 boolToJbool(hasLatLong(location)),
Wyatt Riley5d229832017-02-10 17:06:00 -0800751 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700752 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800753 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700754 return Void();
755}
756
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800757Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
758 return gnssLocationCbImpl<GnssLocation_V1_0>(location);
759}
760
761Return<void>
762GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
763 return gnssLocationCbImpl<GnssLocation_V2_0>(location);
764}
765
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800766Return<void> GnssCallback::gnssStatusCb(const IGnssCallback_V2_0::GnssStatusValue status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800767 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700768 env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
769 checkAndClearExceptionFromCallback(env, __FUNCTION__);
770 return Void();
771}
772
Yu-Han Yang3ffaf3a2020-01-10 17:24:47 -0800773template<>
774uint32_t GnssCallback::getHasBasebandCn0DbHzFlag(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>&
775 svStatus) {
776 return SVID_FLAGS_HAS_BASEBAND_CN0;
777}
778
779template<>
780double GnssCallback::getBasebandCn0DbHz(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList,
781 size_t i) {
782 return svInfoList[i].basebandCN0DbHz;
783}
784
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700785template<class T>
786Return<void> GnssCallback::gnssSvStatusCbImpl(const T& svStatus) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800787 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700788
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700789 uint32_t listSize = getGnssSvInfoListSize(svStatus);
Lifu Tang38bce792016-02-24 17:17:38 -0800790
Wyatt Riley26465d22018-02-12 13:44:24 -0800791 jintArray svidWithFlagArray = env->NewIntArray(listSize);
792 jfloatArray cn0Array = env->NewFloatArray(listSize);
793 jfloatArray elevArray = env->NewFloatArray(listSize);
794 jfloatArray azimArray = env->NewFloatArray(listSize);
795 jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
Yu-Han Yang15e43032019-11-22 13:50:41 -0800796 jfloatArray basebandCn0Array = env->NewFloatArray(listSize);
Wyatt Riley26465d22018-02-12 13:44:24 -0800797
798 jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
799 jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
800 jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
801 jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
802 jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
Yu-Han Yang15e43032019-11-22 13:50:41 -0800803 jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0);
Wyatt Riley26465d22018-02-12 13:44:24 -0800804
805 /*
806 * Read GNSS SV info.
807 */
808 for (size_t i = 0; i < listSize; ++i) {
809 enum ShiftWidth: uint8_t {
Yu-Han Yang15e43032019-11-22 13:50:41 -0800810 SVID_SHIFT_WIDTH = 12,
811 CONSTELLATION_TYPE_SHIFT_WIDTH = 8
Wyatt Riley26465d22018-02-12 13:44:24 -0800812 };
813
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700814 const IGnssCallback_V1_0::GnssSvInfo& info = getGnssSvInfoOfIndex(svStatus, i);
Wyatt Riley26465d22018-02-12 13:44:24 -0800815 svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
Yu-Han Yang8e8c7412019-03-15 09:10:18 -0700816 (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
Wyatt Riley26465d22018-02-12 13:44:24 -0800817 static_cast<uint32_t>(info.svFlag);
818 cn0s[i] = info.cN0Dbhz;
819 elev[i] = info.elevationDegrees;
820 azim[i] = info.azimuthDegrees;
821 carrierFreq[i] = info.carrierFrequencyHz;
Yu-Han Yang3ffaf3a2020-01-10 17:24:47 -0800822 svidWithFlags[i] |= getHasBasebandCn0DbHzFlag(svStatus);
823 basebandCn0s[i] = getBasebandCn0DbHz(svStatus, i);
Lifu Tang9363b942016-02-16 18:07:00 -0800824 }
destradaaea8a8a62014-06-23 18:19:03 -0700825
Wyatt Riley26465d22018-02-12 13:44:24 -0800826 env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
827 env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
828 env->ReleaseFloatArrayElements(elevArray, elev, 0);
829 env->ReleaseFloatArrayElements(azimArray, azim, 0);
830 env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
Yu-Han Yang15e43032019-11-22 13:50:41 -0800831 env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0);
Wyatt Riley26465d22018-02-12 13:44:24 -0800832
833 env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
834 static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
Yu-Han Yang15e43032019-11-22 13:50:41 -0800835 carrierFreqArray, basebandCn0Array);
Wyatt Riley26465d22018-02-12 13:44:24 -0800836
Yu-Han Yangc19b3a82020-05-27 16:18:16 -0700837 env->DeleteLocalRef(svidWithFlagArray);
838 env->DeleteLocalRef(cn0Array);
839 env->DeleteLocalRef(elevArray);
840 env->DeleteLocalRef(azimArray);
841 env->DeleteLocalRef(carrierFreqArray);
842 env->DeleteLocalRef(basebandCn0Array);
843
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700844 checkAndClearExceptionFromCallback(env, __FUNCTION__);
845 return Void();
destradaaea8a8a62014-06-23 18:19:03 -0700846}
847
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700848Return<void> GnssCallback::gnssNmeaCb(
849 int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800850 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700851 /*
852 * The Java code will call back to read these values.
853 * We do this to avoid creating unnecessary String objects.
854 */
855 sNmeaString = nmea.c_str();
856 sNmeaStringLength = nmea.size();
857
858 env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
859 checkAndClearExceptionFromCallback(env, __FUNCTION__);
860 return Void();
861}
862
863Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
Anil Admal62c42dc2019-04-03 15:39:22 -0700864 ALOGD("%s: %du\n", __func__, capabilities);
865
866 JNIEnv* env = getJniEnv();
867 env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
868 checkAndClearExceptionFromCallback(env, __FUNCTION__);
869 return Void();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700870}
871
gomo226b7b72018-12-12 16:49:39 -0800872Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
Anil Admal62c42dc2019-04-03 15:39:22 -0700873 return GnssCallback::gnssSetCapabilitesCb(capabilities);
gomo226b7b72018-12-12 16:49:39 -0800874}
875
Yu-Han Yang2ce47332020-02-13 16:08:48 -0800876Return<void> GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) {
877 return GnssCallback::gnssSetCapabilitesCb(capabilities);
878}
879
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700880Return<void> GnssCallback::gnssAcquireWakelockCb() {
881 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
882 return Void();
883}
884
885Return<void> GnssCallback::gnssReleaseWakelockCb() {
886 release_wake_lock(WAKE_LOCK_NAME);
887 return Void();
888}
889
890Return<void> GnssCallback::gnssRequestTimeCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800891 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700892 env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
893 checkAndClearExceptionFromCallback(env, __FUNCTION__);
894 return Void();
895}
896
Yu-Han Yang21988932018-01-23 15:07:37 -0800897Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800898 return GnssCallback::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */
899 false);
900}
901
902Return<void> GnssCallback::gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool
903 isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800904 JNIEnv* env = getJniEnv();
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800905 env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
906 boolToJbool(isUserEmergency));
Yu-Han Yange7baef32018-02-09 13:58:17 -0800907 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Yu-Han Yang21988932018-01-23 15:07:37 -0800908 return Void();
909}
910
Yu-Han Yang5b9a3362019-11-10 13:31:03 -0800911Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSystemInfo& info) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700912 ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
913
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800914 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700915 env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
916 info.yearOfHw);
917 checkAndClearExceptionFromCallback(env, __FUNCTION__);
918 return Void();
919}
920
921class GnssXtraCallback : public IGnssXtraCallback {
922 Return<void> downloadRequestCb() override;
923};
924
925/*
926 * GnssXtraCallback class implements the callback methods for the IGnssXtra
927 * interface.
928 */
929Return<void> GnssXtraCallback::downloadRequestCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800930 JNIEnv* env = getJniEnv();
Kevin Tang8c6ac672019-03-22 12:31:01 -0700931 env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700932 checkAndClearExceptionFromCallback(env, __FUNCTION__);
933 return Void();
934}
935
936/*
937 * GnssGeofenceCallback class implements the callback methods for the
938 * IGnssGeofence interface.
939 */
940struct GnssGeofenceCallback : public IGnssGeofenceCallback {
941 // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
942 Return<void> gnssGeofenceTransitionCb(
943 int32_t geofenceId,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800944 const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700945 GeofenceTransition transition,
946 hardware::gnss::V1_0::GnssUtcTime timestamp) override;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800947 Return<void>
948 gnssGeofenceStatusCb(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700949 GeofenceAvailability status,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800950 const GnssLocation_V1_0& location) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700951 Return<void> gnssGeofenceAddCb(int32_t geofenceId,
952 GeofenceStatus status) override;
953 Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
954 GeofenceStatus status) override;
955 Return<void> gnssGeofencePauseCb(int32_t geofenceId,
956 GeofenceStatus status) override;
957 Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
958 GeofenceStatus status) override;
959};
960
961Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800962 int32_t geofenceId, const GnssLocation_V1_0& location,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700963 GeofenceTransition transition,
964 hardware::gnss::V1_0::GnssUtcTime timestamp) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800965 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700966
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800967 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800968
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700969 env->CallVoidMethod(mCallbacksObj,
970 method_reportGeofenceTransition,
971 geofenceId,
Wyatt Riley5d229832017-02-10 17:06:00 -0800972 jLocation,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700973 transition,
974 timestamp);
975
976 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800977 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700978 return Void();
979}
980
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800981Return<void>
982GnssGeofenceCallback::gnssGeofenceStatusCb(GeofenceAvailability status,
983 const GnssLocation_V1_0& location) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800984 JNIEnv* env = getJniEnv();
Wyatt Riley5d229832017-02-10 17:06:00 -0800985
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800986 jobject jLocation = translateGnssLocation(env, location);
Wyatt Riley5d229832017-02-10 17:06:00 -0800987
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800988 env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
Wyatt Riley5d229832017-02-10 17:06:00 -0800989 jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700990 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Wyatt Riley26465d22018-02-12 13:44:24 -0800991 env->DeleteLocalRef(jLocation);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700992 return Void();
993}
994
995Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
996 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -0800997 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700998 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
999 ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
1000 }
1001
1002 env->CallVoidMethod(mCallbacksObj,
1003 method_reportGeofenceAddStatus,
1004 geofenceId,
1005 status);
1006 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1007 return Void();
1008}
1009
1010Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
1011 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001012 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001013 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
1014 ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
1015 }
1016
1017 env->CallVoidMethod(mCallbacksObj,
1018 method_reportGeofenceRemoveStatus,
1019 geofenceId, status);
1020 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1021 return Void();
1022}
1023
1024Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
1025 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001026 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001027 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
1028 ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
1029 }
1030
1031 env->CallVoidMethod(mCallbacksObj,
1032 method_reportGeofencePauseStatus,
1033 geofenceId, status);
1034 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1035 return Void();
1036}
1037
1038Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
1039 GeofenceStatus status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001040 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001041 if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
1042 ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
1043 }
1044
1045 env->CallVoidMethod(mCallbacksObj,
1046 method_reportGeofenceResumeStatus,
1047 geofenceId, status);
1048 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1049 return Void();
1050}
1051
1052/*
1053 * GnssNavigationMessageCallback interface implements the callback methods
1054 * required by the IGnssNavigationMessage interface.
1055 */
1056struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
1057 /*
1058 * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
1059 * follow.
1060 */
1061 Return<void> gnssNavigationMessageCb(
1062 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
1063};
1064
1065Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
1066 const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001067 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001068
1069 size_t dataLength = message.data.size();
1070
1071 std::vector<uint8_t> navigationData = message.data;
1072 uint8_t* data = &(navigationData[0]);
WyattRiley840c0b22018-10-31 09:03:53 -07001073 if (dataLength == 0 || data == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001074 ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
1075 dataLength);
1076 return Void();
1077 }
1078
Yu-Han Yang1a789452019-04-29 18:40:29 -07001079 JavaObject object(env, class_gnssNavigationMessage, method_gnssNavigationMessageCtor);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001080 SET(Type, static_cast<int32_t>(message.type));
1081 SET(Svid, static_cast<int32_t>(message.svid));
1082 SET(MessageId, static_cast<int32_t>(message.messageId));
1083 SET(SubmessageId, static_cast<int32_t>(message.submessageId));
1084 object.callSetter("setData", data, dataLength);
1085 SET(Status, static_cast<int32_t>(message.status));
1086
1087 jobject navigationMessage = object.get();
1088 env->CallVoidMethod(mCallbacksObj,
1089 method_reportNavigationMessages,
1090 navigationMessage);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001091 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001092 env->DeleteLocalRef(navigationMessage);
1093 return Void();
1094}
1095
1096/*
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001097 * GnssAntennaInfoCallback implements the callback methods required for the
1098 * GnssAntennaInfo interface.
1099 */
1100struct GnssAntennaInfoCallback : public IGnssAntennaInfoCallback {
1101 // Methods from V2_1::GnssAntennaInfoCallback follow.
1102 Return<void> gnssAntennaInfoCb(
1103 const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos);
1104
1105private:
1106 jobject translateAllGnssAntennaInfos(
1107 JNIEnv* env,
1108 const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos);
1109 jobject translateSingleGnssAntennaInfo(
1110 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo);
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001111 jobject translatePhaseCenterOffset(
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001112 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo);
1113 jobject translatePhaseCenterVariationCorrections(
1114 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo);
1115 jobject translateSignalGainCorrections(
1116 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo);
1117 jobjectArray translate2dDoubleArray(JNIEnv* env,
1118 const hidl_vec<IGnssAntennaInfoCallback::Row>& array);
1119 void translateAndReportGnssAntennaInfo(
1120 const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos);
1121 void reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray);
1122};
1123
1124Return<void> GnssAntennaInfoCallback::gnssAntennaInfoCb(
1125 const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
1126 translateAndReportGnssAntennaInfo(gnssAntennaInfos);
1127 return Void();
1128}
1129
1130jobjectArray GnssAntennaInfoCallback::translate2dDoubleArray(
1131 JNIEnv* env, const hidl_vec<IGnssAntennaInfoCallback::Row>& array) {
1132 jsize numRows = array.size();
1133 if (numRows == 0) {
1134 // Empty array
1135 return NULL;
1136 }
1137 jsize numCols = array[0].row.size();
1138 if (numCols <= 1) {
1139 // phi angle separation is computed as 180.0 / (numColumns - 1), so can't be < 2.
1140 return NULL;
1141 }
1142
1143 // Allocate array of double arrays
1144 jobjectArray returnArray = env->NewObjectArray(numRows, class_doubleArray, NULL);
1145
1146 // Create each double array
1147 for (uint8_t i = 0; i < numRows; i++) {
1148 jdoubleArray doubleArray = env->NewDoubleArray(numCols);
1149 env->SetDoubleArrayRegion(doubleArray, (jsize)0, numCols, array[i].row.data());
1150 env->SetObjectArrayElement(returnArray, (jsize)i, doubleArray);
1151 env->DeleteLocalRef(doubleArray);
1152 }
1153 return returnArray;
1154}
1155
1156jobject GnssAntennaInfoCallback::translateAllGnssAntennaInfos(
1157 JNIEnv* env, const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
1158 jobject arrayList = env->NewObject(class_arrayList,
1159 method_arrayListCtor); // Create new ArrayList instance
1160
1161 for (auto gnssAntennaInfo : gnssAntennaInfos) {
1162 jobject gnssAntennaInfoObject = translateSingleGnssAntennaInfo(env, gnssAntennaInfo);
1163
1164 env->CallBooleanMethod(arrayList, method_arrayListAdd,
1165 gnssAntennaInfoObject); // Add the antennaInfo to the ArrayList
1166
1167 // Delete Local Refs
1168 env->DeleteLocalRef(gnssAntennaInfoObject);
1169 }
1170 return arrayList;
1171}
1172
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001173jobject GnssAntennaInfoCallback::translatePhaseCenterOffset(
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001174 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo) {
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001175 jobject phaseCenterOffset =
1176 env->NewObject(class_phaseCenterOffset, method_phaseCenterOffsetCtor,
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001177 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.x,
1178 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.xUncertainty,
1179 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.y,
1180 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.yUncertainty,
1181 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.z,
1182 gnssAntennaInfo.phaseCenterOffsetCoordinateMillimeters.zUncertainty);
1183
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001184 return phaseCenterOffset;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001185}
1186
1187jobject GnssAntennaInfoCallback::translatePhaseCenterVariationCorrections(
1188 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo) {
1189 if (gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters == NULL ||
1190 gnssAntennaInfo.phaseCenterVariationCorrectionUncertaintyMillimeters == NULL) {
1191 return NULL;
1192 }
1193
1194 jobjectArray phaseCenterVariationCorrectionsArray =
1195 translate2dDoubleArray(env, gnssAntennaInfo.phaseCenterVariationCorrectionMillimeters);
1196 jobjectArray phaseCenterVariationCorrectionsUncertaintiesArray =
1197 translate2dDoubleArray(env,
1198 gnssAntennaInfo
1199 .phaseCenterVariationCorrectionUncertaintyMillimeters);
1200
1201 if (phaseCenterVariationCorrectionsArray == NULL ||
1202 phaseCenterVariationCorrectionsUncertaintiesArray == NULL) {
1203 return NULL;
1204 }
1205
1206 jobject phaseCenterVariationCorrections =
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001207 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001208 phaseCenterVariationCorrectionsArray,
1209 phaseCenterVariationCorrectionsUncertaintiesArray);
1210
1211 env->DeleteLocalRef(phaseCenterVariationCorrectionsArray);
1212 env->DeleteLocalRef(phaseCenterVariationCorrectionsUncertaintiesArray);
1213
1214 return phaseCenterVariationCorrections;
1215}
1216
1217jobject GnssAntennaInfoCallback::translateSignalGainCorrections(
1218 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo) {
1219 if (gnssAntennaInfo.signalGainCorrectionDbi == NULL ||
1220 gnssAntennaInfo.signalGainCorrectionUncertaintyDbi == NULL) {
1221 return NULL;
1222 }
1223 jobjectArray signalGainCorrectionsArray =
1224 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionDbi);
1225 jobjectArray signalGainCorrectionsUncertaintiesArray =
1226 translate2dDoubleArray(env, gnssAntennaInfo.signalGainCorrectionUncertaintyDbi);
1227
1228 if (signalGainCorrectionsArray == NULL || signalGainCorrectionsUncertaintiesArray == NULL) {
1229 return NULL;
1230 }
1231
1232 jobject signalGainCorrections =
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001233 env->NewObject(class_sphericalCorrections, method_sphericalCorrectionsCtor,
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001234 signalGainCorrectionsArray, signalGainCorrectionsUncertaintiesArray);
1235
1236 env->DeleteLocalRef(signalGainCorrectionsArray);
1237 env->DeleteLocalRef(signalGainCorrectionsUncertaintiesArray);
1238
1239 return signalGainCorrections;
1240}
1241
1242jobject GnssAntennaInfoCallback::translateSingleGnssAntennaInfo(
1243 JNIEnv* env, const IGnssAntennaInfoCallback::GnssAntennaInfo& gnssAntennaInfo) {
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001244 jobject phaseCenterOffset = translatePhaseCenterOffset(env, gnssAntennaInfo);
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001245
1246 // Nullable
1247 jobject phaseCenterVariationCorrections =
1248 translatePhaseCenterVariationCorrections(env, gnssAntennaInfo);
1249
1250 // Nullable
1251 jobject signalGainCorrections = translateSignalGainCorrections(env, gnssAntennaInfo);
1252
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001253 // Get builder
1254 jobject gnssAntennaInfoBuilderObject =
1255 env->NewObject(class_gnssAntennaInfoBuilder, method_gnssAntennaInfoBuilderCtor);
1256
1257 // Set fields
1258 env->CallObjectMethod(gnssAntennaInfoBuilderObject,
1259 method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz,
1260 gnssAntennaInfo.carrierFrequencyMHz);
1261 env->CallObjectMethod(gnssAntennaInfoBuilderObject,
1262 method_gnssAntennaInfoBuilderSetPhaseCenterOffset, phaseCenterOffset);
1263 env->CallObjectMethod(gnssAntennaInfoBuilderObject,
1264 method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections,
1265 phaseCenterVariationCorrections);
1266 env->CallObjectMethod(gnssAntennaInfoBuilderObject,
1267 method_gnssAntennaInfoBuilderSetSignalGainCorrections,
1268 signalGainCorrections);
1269
1270 // build
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001271 jobject gnssAntennaInfoObject =
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001272 env->CallObjectMethod(gnssAntennaInfoBuilderObject, method_gnssAntennaInfoBuilderBuild);
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001273
1274 // Delete Local Refs
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08001275 env->DeleteLocalRef(phaseCenterOffset);
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001276 env->DeleteLocalRef(phaseCenterVariationCorrections);
1277 env->DeleteLocalRef(signalGainCorrections);
1278
1279 return gnssAntennaInfoObject;
1280}
1281
1282void GnssAntennaInfoCallback::translateAndReportGnssAntennaInfo(
1283 const hidl_vec<IGnssAntennaInfoCallback::GnssAntennaInfo>& gnssAntennaInfos) {
1284 JNIEnv* env = getJniEnv();
1285
1286 jobject arrayList = translateAllGnssAntennaInfos(env, gnssAntennaInfos);
1287
1288 reportAntennaInfo(env, arrayList);
1289
1290 env->DeleteLocalRef(arrayList);
1291}
1292
1293void GnssAntennaInfoCallback::reportAntennaInfo(JNIEnv* env, const jobject antennaInfosArray) {
1294 env->CallVoidMethod(mCallbacksObj, method_reportAntennaInfo, antennaInfosArray);
1295 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1296}
1297
1298/*
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001299 * GnssMeasurementCallback implements the callback methods required for the
1300 * GnssMeasurement interface.
1301 */
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08001302struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_1 {
1303 Return<void> gnssMeasurementCb_2_1(const IGnssMeasurementCallback_V2_1::GnssData& data)
1304 override;
Yu-Han Yang88d79102018-11-14 14:20:57 -08001305 Return<void> gnssMeasurementCb_2_0(const IGnssMeasurementCallback_V2_0::GnssData& data)
1306 override;
Wyatt Riley46ac9562018-03-02 20:16:58 -08001307 Return<void> gnssMeasurementCb(const IGnssMeasurementCallback_V1_1::GnssData& data) override;
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001308 Return<void> GnssMeasurementCb(const IGnssMeasurementCallback_V1_0::GnssData& data) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001309 private:
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001310 template<class T>
1311 void translateSingleGnssMeasurement(const T* measurement, JavaObject& object);
1312
1313 template<class T>
1314 jobjectArray translateAllGnssMeasurements(JNIEnv* env, const T* measurements, size_t count);
1315
1316 template<class T>
1317 void translateAndSetGnssData(const T& data);
1318
1319 template<class T>
1320 size_t getMeasurementCount(const T& data);
1321
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001322 template<class T>
1323 void translateGnssClock(JavaObject& object, const T& data);
1324
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001325 void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
1326};
1327
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08001328Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_1(
1329 const IGnssMeasurementCallback_V2_1::GnssData& data) {
1330 translateAndSetGnssData(data);
1331 return Void();
1332}
1333
Yu-Han Yang88d79102018-11-14 14:20:57 -08001334Return<void> GnssMeasurementCallback::gnssMeasurementCb_2_0(
1335 const IGnssMeasurementCallback_V2_0::GnssData& data) {
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001336 translateAndSetGnssData(data);
Yu-Han Yang88d79102018-11-14 14:20:57 -08001337 return Void();
1338}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001339
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001340Return<void> GnssMeasurementCallback::gnssMeasurementCb(
Wyatt Riley46ac9562018-03-02 20:16:58 -08001341 const IGnssMeasurementCallback_V1_1::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001342 translateAndSetGnssData(data);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001343 return Void();
1344}
1345
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001346Return<void> GnssMeasurementCallback::GnssMeasurementCb(
1347 const IGnssMeasurementCallback_V1_0::GnssData& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001348 translateAndSetGnssData(data);
1349 return Void();
1350}
1351
1352template<class T>
1353void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001354 JNIEnv* env = getJniEnv();
Lifu Tang120480f2016-02-07 18:08:19 -08001355
Yu-Han Yang1a789452019-04-29 18:40:29 -07001356 JavaObject gnssClockJavaObject(env, class_gnssClock, method_gnssClockCtor);
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001357 translateGnssClock(gnssClockJavaObject, data);
1358 jobject clock = gnssClockJavaObject.get();
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001359
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001360 size_t count = getMeasurementCount(data);
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001361 jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001362 setMeasurementData(env, clock, measurementArray);
1363
1364 env->DeleteLocalRef(clock);
1365 env->DeleteLocalRef(measurementArray);
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001366}
1367
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001368template<>
1369size_t GnssMeasurementCallback::getMeasurementCount<IGnssMeasurementCallback_V1_0::GnssData>
1370 (const IGnssMeasurementCallback_V1_0::GnssData& data) {
1371 return data.measurementCount;
1372}
1373
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001374template<class T>
1375size_t GnssMeasurementCallback::getMeasurementCount(const T& data) {
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001376 return data.measurements.size();
1377}
1378
1379// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1380template<>
1381void GnssMeasurementCallback::translateSingleGnssMeasurement
1382 <IGnssMeasurementCallback_V1_0::GnssMeasurement>(
WyattRiley840c0b22018-10-31 09:03:53 -07001383 const IGnssMeasurementCallback_V1_0::GnssMeasurement* measurement,
Wyatt Riley46ac9562018-03-02 20:16:58 -08001384 JavaObject& object) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001385 uint32_t flags = static_cast<uint32_t>(measurement->flags);
Mike Cailean96635bd2016-03-24 19:34:16 -07001386
1387 SET(Svid, static_cast<int32_t>(measurement->svid));
Lifu Tang76a620f2016-02-26 19:53:01 -08001388 SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001389 SET(TimeOffsetNanos, measurement->timeOffsetNs);
Lifu Tang76a620f2016-02-26 19:53:01 -08001390 SET(State, static_cast<int32_t>(measurement->state));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001391 SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
Lifu Tang76a620f2016-02-26 19:53:01 -08001392 SET(ReceivedSvTimeUncertaintyNanos,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001393 measurement->receivedSvTimeUncertaintyInNs);
1394 SET(Cn0DbHz, measurement->cN0DbHz);
1395 SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
Lifu Tang76a620f2016-02-26 19:53:01 -08001396 SET(PseudorangeRateUncertaintyMetersPerSecond,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001397 measurement->pseudorangeRateUncertaintyMps);
Lifu Tang76a620f2016-02-26 19:53:01 -08001398 SET(AccumulatedDeltaRangeState,
Wyatt Riley4cbcb412018-01-23 18:07:05 -08001399 (static_cast<int32_t>(measurement->accumulatedDeltaRangeState) &
WyattRiley948dd6d2018-10-31 06:56:09 -07001400 ~ADR_STATE_HALF_CYCLE_REPORTED)); // Half Cycle state not reported from Hardware in V1_0
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001401 SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
Lifu Tang76a620f2016-02-26 19:53:01 -08001402 SET(AccumulatedDeltaRangeUncertaintyMeters,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001403 measurement->accumulatedDeltaRangeUncertaintyM);
1404
1405 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
1406 SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
1407 }
1408
Wyatt Rileybb9bc842018-02-14 08:46:00 -08001409 // Intentionally not copying deprecated fields of carrierCycles,
1410 // carrierPhase, carrierPhaseUncertainty
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001411
1412 SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
1413
1414 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
1415 SET(SnrInDb, measurement->snrDb);
1416 }
Lifu Tang120480f2016-02-07 18:08:19 -08001417
gomo4402af62017-01-11 13:20:13 -08001418 if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_AUTOMATIC_GAIN_CONTROL)) {
gomo127ba322017-01-15 20:26:48 -08001419 SET(AutomaticGainControlLevelInDb, measurement->agcLevelDb);
gomo4402af62017-01-11 13:20:13 -08001420 }
Lifu Tang120480f2016-02-07 18:08:19 -08001421}
1422
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001423// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1424template<>
1425void GnssMeasurementCallback::translateSingleGnssMeasurement
1426 <IGnssMeasurementCallback_V1_1::GnssMeasurement>(
1427 const IGnssMeasurementCallback_V1_1::GnssMeasurement* measurement_V1_1,
1428 JavaObject& object) {
1429 translateSingleGnssMeasurement(&(measurement_V1_1->v1_0), object);
1430
1431 // Set the V1_1 flag, and mark that new field has valid information for Java Layer
1432 SET(AccumulatedDeltaRangeState,
1433 (static_cast<int32_t>(measurement_V1_1->accumulatedDeltaRangeState) |
1434 ADR_STATE_HALF_CYCLE_REPORTED));
1435}
1436
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001437// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1438template<>
1439void GnssMeasurementCallback::translateSingleGnssMeasurement
1440 <IGnssMeasurementCallback_V2_0::GnssMeasurement>(
1441 const IGnssMeasurementCallback_V2_0::GnssMeasurement* measurement_V2_0,
1442 JavaObject& object) {
Yu-Han Yangfbcc5cf2019-03-11 12:01:10 -07001443 JNIEnv* env = getJniEnv();
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001444 translateSingleGnssMeasurement(&(measurement_V2_0->v1_1), object);
1445
Yu-Han Yangc19b3a82020-05-27 16:18:16 -07001446 jstring codeType = env->NewStringUTF(measurement_V2_0->codeType.c_str());
1447 SET(CodeType, codeType);
Yu-Han Yang786a2bd2019-02-01 19:52:28 -08001448
1449 // Overwrite with v2_0.state since v2_0->v1_1->v1_0.state is deprecated.
1450 SET(State, static_cast<int32_t>(measurement_V2_0->state));
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07001451
1452 // Overwrite with v2_0.constellation since v2_0->v1_1->v1_0.constellation is deprecated.
1453 SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation));
Yu-Han Yangc19b3a82020-05-27 16:18:16 -07001454
1455 if (codeType) {
1456 env->DeleteLocalRef(codeType);
1457 }
Yu-Han Yang3fbf6e52018-12-11 12:58:13 -08001458}
1459
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08001460// Preallocate object as: JavaObject object(env, "android/location/GnssMeasurement");
1461template<>
1462void GnssMeasurementCallback::translateSingleGnssMeasurement
1463 <IGnssMeasurementCallback_V2_1::GnssMeasurement>(
1464 const IGnssMeasurementCallback_V2_1::GnssMeasurement* measurement_V2_1,
1465 JavaObject& object) {
1466 translateSingleGnssMeasurement(&(measurement_V2_1->v2_0), object);
Yu-Han Yang3ffaf3a2020-01-10 17:24:47 -08001467
1468 SET(BasebandCn0DbHz, measurement_V2_1->basebandCN0DbHz);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001469
Yu-Han Yangb4f806f2020-03-09 12:22:44 -07001470 if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB) {
1471 SET(FullInterSignalBiasNanos, measurement_V2_1->fullInterSignalBiasNs);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001472 }
1473
Yu-Han Yangb4f806f2020-03-09 12:22:44 -07001474 if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_FULL_ISB_UNCERTAINTY) {
1475 SET(FullInterSignalBiasUncertaintyNanos,
1476 measurement_V2_1->fullInterSignalBiasUncertaintyNs);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001477 }
1478
1479 if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB) {
Yu-Han Yangbcb22742020-02-02 13:11:29 -08001480 SET(SatelliteInterSignalBiasNanos, measurement_V2_1->satelliteInterSignalBiasNs);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001481 }
1482
1483 if (measurement_V2_1->flags & GnssMeasurementFlags::HAS_SATELLITE_ISB_UNCERTAINTY) {
Yu-Han Yangbcb22742020-02-02 13:11:29 -08001484 SET(SatelliteInterSignalBiasUncertaintyNanos,
1485 measurement_V2_1->satelliteInterSignalBiasUncertaintyNs);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001486 }
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08001487}
1488
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001489template<class T>
1490void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) {
1491 translateGnssClock(object, data.clock);
1492}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001493
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001494template<>
1495void GnssMeasurementCallback::translateGnssClock(
1496 JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) {
1497 uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001498 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001499 SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001500 }
1501
1502 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001503 SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001504 }
1505
1506 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001507 SET(FullBiasNanos, clock.fullBiasNs);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001508 }
1509
1510 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001511 SET(BiasNanos, clock.biasNs);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001512 }
1513
1514 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001515 SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001516 }
1517
1518 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001519 SET(DriftNanosPerSecond, clock.driftNsps);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001520 }
1521
1522 if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001523 SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001524 }
1525
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001526 SET(TimeNanos, clock.timeNs);
1527 SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
1528}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001529
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001530template<>
1531void GnssMeasurementCallback::translateGnssClock(
Yu-Han Yangad03c472020-01-14 15:31:01 -08001532 JavaObject& object, const IGnssMeasurementCallback_V2_1::GnssClock& clock) {
1533 JNIEnv* env = getJniEnv();
1534 SET(ReferenceConstellationTypeForIsb,
1535 static_cast<int32_t>(clock.referenceSignalTypeForIsb.constellation));
1536 SET(ReferenceCarrierFrequencyHzForIsb, clock.referenceSignalTypeForIsb.carrierFrequencyHz);
Yu-Han Yangc19b3a82020-05-27 16:18:16 -07001537
1538 jstring referenceCodeTypeForIsb =
1539 env->NewStringUTF(clock.referenceSignalTypeForIsb.codeType.c_str());
1540 SET(ReferenceCodeTypeForIsb, referenceCodeTypeForIsb);
Yu-Han Yangad03c472020-01-14 15:31:01 -08001541
1542 translateGnssClock(object, clock.v1_0);
Yu-Han Yangc19b3a82020-05-27 16:18:16 -07001543
1544 if (referenceCodeTypeForIsb) {
1545 env->DeleteLocalRef(referenceCodeTypeForIsb);
1546 }
Yu-Han Yangad03c472020-01-14 15:31:01 -08001547}
1548
1549template<>
1550void GnssMeasurementCallback::translateGnssClock(
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001551 JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) {
1552 auto elapsedRealtime = data.elapsedRealtime;
1553 uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
1554 if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
1555 SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
1556 }
1557 if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07001558 SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(elapsedRealtime.timeUncertaintyNs));
Yu-Han Yang080fd2f2019-03-20 17:02:53 -07001559 }
1560 translateGnssClock(object, data.clock);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001561}
1562
Yu-Han Yangad03c472020-01-14 15:31:01 -08001563template<>
1564void GnssMeasurementCallback::translateGnssClock(
1565 JavaObject& object, const IGnssMeasurementCallback_V2_1::GnssData& data) {
1566 auto elapsedRealtime = data.elapsedRealtime;
1567 uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
1568 if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
1569 SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
1570 }
1571 if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
1572 SET(ElapsedRealtimeUncertaintyNanos, static_cast<double>(elapsedRealtime.timeUncertaintyNs));
1573 }
1574 translateGnssClock(object, data.clock);
1575}
1576
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001577template<class T>
1578jobjectArray GnssMeasurementCallback::translateAllGnssMeasurements(JNIEnv* env,
1579 const T* measurements,
1580 size_t count) {
Lifu Tang120480f2016-02-07 18:08:19 -08001581 if (count == 0) {
WyattRiley840c0b22018-10-31 09:03:53 -07001582 return nullptr;
destradaaea8a8a62014-06-23 18:19:03 -07001583 }
1584
Lifu Tang818aa2c2016-02-01 01:52:00 -08001585 jobjectArray gnssMeasurementArray = env->NewObjectArray(
Lifu Tang120480f2016-02-07 18:08:19 -08001586 count,
Yu-Han Yang1a789452019-04-29 18:40:29 -07001587 class_gnssMeasurement,
WyattRiley840c0b22018-10-31 09:03:53 -07001588 nullptr /* initialElement */);
destradaaea8a8a62014-06-23 18:19:03 -07001589
Lifu Tang120480f2016-02-07 18:08:19 -08001590 for (uint16_t i = 0; i < count; ++i) {
Yu-Han Yang1a789452019-04-29 18:40:29 -07001591 JavaObject object(env, class_gnssMeasurement, method_gnssMeasurementCtor);
Yu-Han Yanga397acd2018-12-07 10:59:48 -08001592 translateSingleGnssMeasurement(&(measurements[i]), object);
Yu-Han Yangc19b3a82020-05-27 16:18:16 -07001593 jobject gnssMeasurement = object.get();
1594 env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
1595 env->DeleteLocalRef(gnssMeasurement);
destradaaea8a8a62014-06-23 18:19:03 -07001596 }
1597
Lifu Tang818aa2c2016-02-01 01:52:00 -08001598 return gnssMeasurementArray;
destradaaea8a8a62014-06-23 18:19:03 -07001599}
1600
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001601void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
1602 jobjectArray measurementArray) {
Yu-Han Yang1a789452019-04-29 18:40:29 -07001603 jobject gnssMeasurementsEvent = env->NewObject(class_gnssMeasurementsEvent,
1604 method_gnssMeasurementsEventCtor,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001605 clock,
1606 measurementArray);
Lifu Tang120480f2016-02-07 18:08:19 -08001607
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001608 env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
1609 gnssMeasurementsEvent);
Lifu Tange5a0e212016-01-25 18:02:17 -08001610 checkAndClearExceptionFromCallback(env, __FUNCTION__);
Lifu Tang818aa2c2016-02-01 01:52:00 -08001611 env->DeleteLocalRef(gnssMeasurementsEvent);
destradaaea8a8a62014-06-23 18:19:03 -07001612}
1613
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001614/*
Anil Admalefd9dc62019-03-12 17:39:20 -07001615 * MeasurementCorrectionsCallback implements callback methods of interface
1616 * IMeasurementCorrectionsCallback.hal.
1617 */
1618struct MeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback {
1619 Return<void> setCapabilitiesCb(uint32_t capabilities) override;
1620};
1621
1622Return<void> MeasurementCorrectionsCallback::setCapabilitiesCb(uint32_t capabilities) {
1623 ALOGD("%s: %du\n", __func__, capabilities);
1624 JNIEnv* env = getJniEnv();
Anil Admal312fddb2019-03-25 12:15:43 -07001625 env->CallVoidMethod(mCallbacksObj, method_setSubHalMeasurementCorrectionsCapabilities,
1626 capabilities);
Anil Admalefd9dc62019-03-12 17:39:20 -07001627 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1628 return Void();
1629}
1630
1631/*
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001632 * GnssNiCallback implements callback methods required by the IGnssNi interface.
1633 */
1634struct GnssNiCallback : public IGnssNiCallback {
1635 Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
1636 override;
destradaaea8a8a62014-06-23 18:19:03 -07001637};
1638
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001639Return<void> GnssNiCallback::niNotifyCb(
1640 const IGnssNiCallback::GnssNiNotification& notification) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001641 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001642 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1643 jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
1644
1645 if (requestorId && text) {
1646 env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
1647 notification.notificationId, notification.niType,
1648 notification.notifyFlags, notification.timeoutSec,
1649 notification.defaultResponse, requestorId, text,
1650 notification.requestorIdEncoding,
1651 notification.notificationIdEncoding);
1652 } else {
1653 ALOGE("%s: OOM Error\n", __func__);
1654 }
1655
1656 if (requestorId) {
1657 env->DeleteLocalRef(requestorId);
1658 }
1659
1660 if (text) {
1661 env->DeleteLocalRef(text);
1662 }
1663 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1664 return Void();
1665}
1666
1667/*
Anil Admal94ec76a2019-01-15 09:42:01 -08001668 * GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
1669 */
1670struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
1671 Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
1672 override;
1673 Return<bool> isInEmergencySession() override;
1674};
1675
1676Return<void> GnssVisibilityControlCallback::nfwNotifyCb(
1677 const IGnssVisibilityControlCallback::NfwNotification& notification) {
1678 JNIEnv* env = getJniEnv();
1679 jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str());
1680 jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str());
1681 jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
1682
1683 if (proxyAppPackageName && otherProtocolStackName && requestorId) {
1684 env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
1685 notification.protocolStack, otherProtocolStackName,
Anil Admal060f5732019-04-24 08:57:59 -07001686 notification.requestor, requestorId, notification.responseType,
Anil Admal94ec76a2019-01-15 09:42:01 -08001687 notification.inEmergencyMode, notification.isCachedLocation);
1688 } else {
1689 ALOGE("%s: OOM Error\n", __func__);
1690 }
1691
1692 if (requestorId) {
1693 env->DeleteLocalRef(requestorId);
1694 }
1695
1696 if (otherProtocolStackName) {
1697 env->DeleteLocalRef(otherProtocolStackName);
1698 }
1699
1700 if (proxyAppPackageName) {
1701 env->DeleteLocalRef(proxyAppPackageName);
1702 }
1703
1704 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1705 return Void();
1706}
1707
1708Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
1709 JNIEnv* env = getJniEnv();
1710 auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
1711 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1712 return result;
1713}
1714
1715/*
Anil Admalc70344b2018-11-16 14:22:38 -08001716 * AGnssCallback_V1_0 implements callback methods required by the IAGnssCallback 1.0 interface.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001717 */
Anil Admalc70344b2018-11-16 14:22:38 -08001718struct AGnssCallback_V1_0 : public IAGnssCallback_V1_0 {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001719 // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
1720 Return<void> agnssStatusIpV6Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001721 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001722
1723 Return<void> agnssStatusIpV4Cb(
Anil Admalc70344b2018-11-16 14:22:38 -08001724 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001725 private:
1726 jbyteArray convertToIpV4(uint32_t ip);
1727};
1728
Anil Admalc70344b2018-11-16 14:22:38 -08001729Return<void> AGnssCallback_V1_0::agnssStatusIpV6Cb(
1730 const IAGnssCallback_V1_0::AGnssStatusIpV6& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001731 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001732 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001733
1734 byteArray = env->NewByteArray(16);
WyattRiley840c0b22018-10-31 09:03:53 -07001735 if (byteArray != nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001736 env->SetByteArrayRegion(byteArray, 0, 16,
1737 (const jbyte*)(agps_status.ipV6Addr.data()));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001738 } else {
1739 ALOGE("Unable to allocate byte array for IPv6 address.");
1740 }
1741
1742 IF_ALOGD() {
1743 // log the IP for reference in case there is a bogus value pushed by HAL
1744 char str[INET6_ADDRSTRLEN];
1745 inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
1746 ALOGD("AGPS IP is v6: %s", str);
1747 }
1748
WyattRiley840c0b22018-10-31 09:03:53 -07001749 jsize byteArrayLength = byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001750 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1751 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1752 agps_status.type, agps_status.status, byteArray);
1753
1754 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1755
1756 if (byteArray) {
1757 env->DeleteLocalRef(byteArray);
1758 }
1759
1760 return Void();
1761}
1762
Anil Admalc70344b2018-11-16 14:22:38 -08001763Return<void> AGnssCallback_V1_0::agnssStatusIpV4Cb(
1764 const IAGnssCallback_V1_0::AGnssStatusIpV4& agps_status) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001765 JNIEnv* env = getJniEnv();
WyattRiley840c0b22018-10-31 09:03:53 -07001766 jbyteArray byteArray = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001767
1768 uint32_t ipAddr = agps_status.ipV4Addr;
1769 byteArray = convertToIpV4(ipAddr);
1770
1771 IF_ALOGD() {
1772 /*
1773 * log the IP for reference in case there is a bogus value pushed by
1774 * HAL.
1775 */
1776 char str[INET_ADDRSTRLEN];
1777 inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
1778 ALOGD("AGPS IP is v4: %s", str);
1779 }
1780
1781 jsize byteArrayLength =
WyattRiley840c0b22018-10-31 09:03:53 -07001782 byteArray != nullptr ? env->GetArrayLength(byteArray) : 0;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001783 ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
1784 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
1785 agps_status.type, agps_status.status, byteArray);
1786
1787 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1788
1789 if (byteArray) {
1790 env->DeleteLocalRef(byteArray);
1791 }
1792 return Void();
1793}
1794
Anil Admalc70344b2018-11-16 14:22:38 -08001795jbyteArray AGnssCallback_V1_0::convertToIpV4(uint32_t ip) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001796 if (INADDR_NONE == ip) {
WyattRiley840c0b22018-10-31 09:03:53 -07001797 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001798 }
1799
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001800 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001801 jbyteArray byteArray = env->NewByteArray(4);
WyattRiley840c0b22018-10-31 09:03:53 -07001802 if (byteArray == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001803 ALOGE("Unable to allocate byte array for IPv4 address");
WyattRiley840c0b22018-10-31 09:03:53 -07001804 return nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001805 }
1806
1807 jbyte ipv4[4];
1808 ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
1809 memcpy(ipv4, &ip, sizeof(ipv4));
1810 env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
1811 return byteArray;
1812}
1813
1814/*
Anil Admalc70344b2018-11-16 14:22:38 -08001815 * AGnssCallback_V2_0 implements callback methods required by the IAGnssCallback 2.0 interface.
1816 */
1817struct AGnssCallback_V2_0 : public IAGnssCallback_V2_0 {
1818 // Methods from ::android::hardware::gps::V2_0::IAGnssCallback follow.
1819 Return<void> agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1820 IAGnssCallback_V2_0::AGnssStatusValue status) override;
1821};
1822
1823Return<void> AGnssCallback_V2_0::agnssStatusCb(IAGnssCallback_V2_0::AGnssType type,
1824 IAGnssCallback_V2_0::AGnssStatusValue status) {
1825 JNIEnv* env = getJniEnv();
1826 env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, type, status, nullptr);
1827 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1828 return Void();
1829}
1830
1831/*
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001832 * AGnssRilCallback implements the callback methods required by the AGnssRil
1833 * interface.
1834 */
1835struct AGnssRilCallback : IAGnssRilCallback {
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001836 Return<void> requestSetIdCb(uint32_t setIdFlag) override;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001837 Return<void> requestRefLocCb() override;
1838};
1839
Hridya Valsarajub39eb402017-01-11 08:07:40 -08001840Return<void> AGnssRilCallback::requestSetIdCb(uint32_t setIdFlag) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001841 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001842 env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
1843 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1844 return Void();
1845}
1846
1847Return<void> AGnssRilCallback::requestRefLocCb() {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08001848 JNIEnv* env = getJniEnv();
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001849 env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
1850 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1851 return Void();
1852}
1853
Anil Admalb8c235e2019-03-21 18:46:58 +00001854struct GnssBatchingCallbackUtil {
1855 template<class T>
1856 static Return<void> gnssLocationBatchCbImpl(const hidl_vec<T>& locations);
1857private:
1858 GnssBatchingCallbackUtil() = delete;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001859};
1860
Anil Admalb8c235e2019-03-21 18:46:58 +00001861template<class T>
1862Return<void> GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(const hidl_vec<T>& locations) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08001863 JNIEnv* env = getJniEnv();
1864
Yu-Han Yang1a789452019-04-29 18:40:29 -07001865 jobjectArray jLocations = env->NewObjectArray(locations.size(), class_location, nullptr);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001866
1867 for (uint16_t i = 0; i < locations.size(); ++i) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08001868 jobject jLocation = translateGnssLocation(env, locations[i]);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001869 env->SetObjectArrayElement(jLocations, i, jLocation);
1870 env->DeleteLocalRef(jLocation);
1871 }
1872
1873 env->CallVoidMethod(mCallbacksObj, method_reportLocationBatch, jLocations);
1874 checkAndClearExceptionFromCallback(env, __FUNCTION__);
1875
1876 env->DeleteLocalRef(jLocations);
1877
1878 return Void();
1879}
1880
Anil Admalb8c235e2019-03-21 18:46:58 +00001881/*
1882 * GnssBatchingCallback_V1_0 class implements the callback methods required by the
1883 * IGnssBatching 1.0 interface.
1884 */
1885struct GnssBatchingCallback_V1_0 : public IGnssBatchingCallback_V1_0 {
1886 /** Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback follow. */
1887 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V1_0>& locations) override {
1888 return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
1889 }
1890};
1891
1892/*
1893 * GnssBatchingCallback_V2_0 class implements the callback methods required by the
1894 * IGnssBatching 2.0 interface.
1895 */
1896struct GnssBatchingCallback_V2_0 : public IGnssBatchingCallback_V2_0 {
1897 /** Methods from ::android::hardware::gps::V2_0::IGnssBatchingCallback follow. */
1898 Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation_V2_0>& locations) override {
1899 return GnssBatchingCallbackUtil::gnssLocationBatchCbImpl(locations);
1900 }
1901};
1902
Anil Admal0c2b21bd2019-05-03 18:29:02 -07001903/* Initializes the GNSS service handle. */
1904static void android_location_GnssLocationProvider_set_gps_service_handle() {
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08001905 ALOGD("Trying IGnss_V2_1::getService()");
1906 gnssHal_V2_1 = IGnss_V2_1::getService();
1907 if (gnssHal_V2_1 != nullptr) {
1908 gnssHal = gnssHal_V2_1;
1909 gnssHal_V2_0 = gnssHal_V2_1;
1910 gnssHal_V1_1 = gnssHal_V2_1;
1911 gnssHal = gnssHal_V2_1;
1912 return;
1913 }
1914
1915 ALOGD("gnssHal 2.1 was null, trying 2.0");
Yu-Han Yang88d79102018-11-14 14:20:57 -08001916 gnssHal_V2_0 = IGnss_V2_0::getService();
1917 if (gnssHal_V2_0 != nullptr) {
1918 gnssHal = gnssHal_V2_0;
1919 gnssHal_V1_1 = gnssHal_V2_0;
1920 return;
Yu-Han Yang6d317352018-03-15 11:53:01 -07001921 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08001922
1923 ALOGD("gnssHal 2.0 was null, trying 1.1");
1924 gnssHal_V1_1 = IGnss_V1_1::getService();
1925 if (gnssHal_V1_1 != nullptr) {
1926 gnssHal = gnssHal_V1_1;
1927 return;
1928 }
1929
1930 ALOGD("gnssHal 1.1 was null, trying 1.0");
1931 gnssHal = IGnss_V1_0::getService();
Yu-Han Yang6d317352018-03-15 11:53:01 -07001932}
1933
Anil Admal0c2b21bd2019-05-03 18:29:02 -07001934/* One time initialization at system boot */
1935static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
1936 // Initialize the top level gnss HAL handle.
1937 android_location_GnssLocationProvider_set_gps_service_handle();
1938
1939 // Cache methodIDs and class IDs.
Wyatt Riley5d229832017-02-10 17:06:00 -08001940 method_reportLocation = env->GetMethodID(clazz, "reportLocation",
1941 "(ZLandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001942 method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
Yu-Han Yang15e43032019-11-22 13:50:41 -08001943 method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001944 method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
1945 method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
Anil Admal62c42dc2019-04-03 15:39:22 -07001946 method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001947 method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001948 method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
1949 "(Ljava/lang/String;)V");
Kevin Tang8c6ac672019-03-22 12:31:01 -07001950 method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "()V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001951 method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
1952 "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001953 method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001954 method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
1955 method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
1956 method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
1957 method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
Wyatt Riley5d229832017-02-10 17:06:00 -08001958 "(ILandroid/location/Location;IJ)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001959 method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
Wyatt Riley5d229832017-02-10 17:06:00 -08001960 "(ILandroid/location/Location;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001961 method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
1962 "(II)V");
1963 method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
1964 "(II)V");
1965 method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
1966 "(II)V");
1967 method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
1968 "(II)V");
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001969 method_reportAntennaInfo = env->GetMethodID(clazz, "reportAntennaInfo", "(Ljava/util/List;)V");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001970 method_reportMeasurementData = env->GetMethodID(
1971 clazz,
1972 "reportMeasurementData",
1973 "(Landroid/location/GnssMeasurementsEvent;)V");
1974 method_reportNavigationMessages = env->GetMethodID(
1975 clazz,
1976 "reportNavigationMessage",
1977 "(Landroid/location/GnssNavigationMessage;)V");
Wyatt Rileycf879db2017-01-12 13:57:38 -08001978 method_reportLocationBatch = env->GetMethodID(
1979 clazz,
1980 "reportLocationBatch",
1981 "([Landroid/location/Location;)V");
Yu-Han Yang52057622018-04-25 00:51:22 -07001982 method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
Anil Admal94ec76a2019-01-15 09:42:01 -08001983 method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
1984 "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
1985 method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001986
Anil Admal312fddb2019-03-25 12:15:43 -07001987 method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
1988 "setSubHalMeasurementCorrectionsCapabilities", "(I)V");
Anil Admalefd9dc62019-03-12 17:39:20 -07001989
gomo5716ab82019-02-27 22:57:56 -08001990 jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
1991 method_correctionsGetLatitudeDegrees = env->GetMethodID(
1992 measCorrClass,"getLatitudeDegrees", "()D");
1993 method_correctionsGetLongitudeDegrees = env->GetMethodID(
1994 measCorrClass, "getLongitudeDegrees", "()D");
1995 method_correctionsGetAltitudeMeters = env->GetMethodID(
1996 measCorrClass, "getAltitudeMeters", "()D");
1997 method_correctionsGetHorPosUncMeters = env->GetMethodID(
1998 measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
1999 method_correctionsGetVerPosUncMeters = env->GetMethodID(
2000 measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
2001 method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
2002 measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
2003
2004 method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
2005 measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava/util/List;");
2006
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002007 method_correctionsHasEnvironmentBearing = env->GetMethodID(
2008 measCorrClass, "hasEnvironmentBearing", "()Z");
2009 method_correctionsGetEnvironmentBearingDegrees = env->GetMethodID(
2010 measCorrClass, "getEnvironmentBearingDegrees", "()F");
2011 method_correctionsGetEnvironmentBearingUncertaintyDegrees = env->GetMethodID(
2012 measCorrClass, "getEnvironmentBearingUncertaintyDegrees", "()F");
2013
gomo5716ab82019-02-27 22:57:56 -08002014 jclass corrListClass = env->FindClass("java/util/List");
2015 method_listSize = env->GetMethodID(corrListClass, "size", "()I");
2016 method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;");
2017
2018 jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection");
2019 method_correctionSatFlags = env->GetMethodID(
2020 singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
2021 method_correctionSatConstType = env->GetMethodID(
2022 singleSatCorrClass, "getConstellationType", "()I");
2023 method_correctionSatId= env->GetMethodID(
2024 singleSatCorrClass, "getSatelliteId", "()I");
2025 method_correctionSatCarrierFreq = env->GetMethodID(
2026 singleSatCorrClass, "getCarrierFrequencyHz", "()F");
2027 method_correctionSatIsLosProb = env->GetMethodID(
2028 singleSatCorrClass,"getProbabilityLineOfSight", "()F");
2029 method_correctionSatEpl = env->GetMethodID(
2030 singleSatCorrClass, "getExcessPathLengthMeters", "()F");
2031 method_correctionSatEplUnc = env->GetMethodID(
2032 singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
2033 method_correctionSatRefPlane = env->GetMethodID(
2034 singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;");
2035
2036 jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane");
2037 method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D");
2038 method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D");
2039 method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D");
2040 method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D");
2041
Yu-Han Yang1a789452019-04-29 18:40:29 -07002042 jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
2043 class_gnssMeasurementsEvent= (jclass) env->NewGlobalRef(gnssMeasurementsEventClass);
2044 method_gnssMeasurementsEventCtor = env->GetMethodID(
2045 class_gnssMeasurementsEvent,
2046 "<init>",
2047 "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
2048
2049 jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
2050 class_gnssMeasurement = (jclass) env->NewGlobalRef(gnssMeasurementClass);
2051 method_gnssMeasurementCtor = env->GetMethodID(class_gnssMeasurement, "<init>", "()V");
2052
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08002053 jclass gnssAntennaInfoBuilder = env->FindClass("android/location/GnssAntennaInfo$Builder");
2054 class_gnssAntennaInfoBuilder = (jclass)env->NewGlobalRef(gnssAntennaInfoBuilder);
2055 method_gnssAntennaInfoBuilderCtor =
2056 env->GetMethodID(class_gnssAntennaInfoBuilder, "<init>", "()V");
2057 method_gnssAntennaInfoBuilderSetCarrierFrequencyMHz =
2058 env->GetMethodID(class_gnssAntennaInfoBuilder, "setCarrierFrequencyMHz",
2059 "(D)Landroid/location/GnssAntennaInfo$Builder;");
2060 method_gnssAntennaInfoBuilderSetPhaseCenterOffset =
2061 env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterOffset",
2062 "(Landroid/location/GnssAntennaInfo$PhaseCenterOffset;)"
2063 "Landroid/location/GnssAntennaInfo$Builder;");
2064 method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections =
2065 env->GetMethodID(class_gnssAntennaInfoBuilder, "setPhaseCenterVariationCorrections",
2066 "(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
2067 "Landroid/location/GnssAntennaInfo$Builder;");
2068 method_gnssAntennaInfoBuilderSetSignalGainCorrections =
2069 env->GetMethodID(class_gnssAntennaInfoBuilder, "setSignalGainCorrections",
2070 "(Landroid/location/GnssAntennaInfo$SphericalCorrections;)"
2071 "Landroid/location/GnssAntennaInfo$Builder;");
2072 method_gnssAntennaInfoBuilderBuild = env->GetMethodID(class_gnssAntennaInfoBuilder, "build",
2073 "()Landroid/location/GnssAntennaInfo;");
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002074
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08002075 jclass phaseCenterOffsetClass =
2076 env->FindClass("android/location/GnssAntennaInfo$PhaseCenterOffset");
2077 class_phaseCenterOffset = (jclass)env->NewGlobalRef(phaseCenterOffsetClass);
2078 method_phaseCenterOffsetCtor = env->GetMethodID(class_phaseCenterOffset, "<init>", "(DDDDDD)V");
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002079
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08002080 jclass sphericalCorrectionsClass =
2081 env->FindClass("android/location/GnssAntennaInfo$SphericalCorrections");
2082 class_sphericalCorrections = (jclass)env->NewGlobalRef(sphericalCorrectionsClass);
2083 method_sphericalCorrectionsCtor =
2084 env->GetMethodID(class_sphericalCorrections, "<init>", "([[D[[D)V");
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002085
Yu-Han Yang1a789452019-04-29 18:40:29 -07002086 jclass locationClass = env->FindClass("android/location/Location");
2087 class_location = (jclass) env->NewGlobalRef(locationClass);
2088 method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V");
2089
2090 jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
2091 class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass);
2092 method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");
2093
2094 jclass gnssClockClass = env->FindClass("android/location/GnssClock");
2095 class_gnssClock = (jclass) env->NewGlobalRef(gnssClockClass);
2096 method_gnssClockCtor = env->GetMethodID(class_gnssClock, "<init>", "()V");
2097
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -07002098 jclass gnssConfiguration_halInterfaceVersionClass = env->FindClass(
2099 "com/android/server/location/gnss/GnssConfiguration$HalInterfaceVersion");
Yu-Han Yang1a789452019-04-29 18:40:29 -07002100 class_gnssConfiguration_halInterfaceVersion =
2101 (jclass) env->NewGlobalRef(gnssConfiguration_halInterfaceVersionClass);
2102 method_halInterfaceVersionCtor =
2103 env->GetMethodID(class_gnssConfiguration_halInterfaceVersion, "<init>", "(II)V");
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002104
2105 jclass arrayListClass = env->FindClass("java/util/ArrayList");
2106 class_arrayList = (jclass)env->NewGlobalRef(arrayListClass);
2107 method_arrayListCtor = env->GetMethodID(class_arrayList, "<init>", "()V");
2108 method_arrayListAdd = env->GetMethodID(class_arrayList, "add", "(Ljava/lang/Object;)Z");
2109
2110 jclass doubleArrayClass = env->FindClass("[D");
2111 class_doubleArray = (jclass)env->NewGlobalRef(doubleArrayClass);
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002112}
Yu-Han Yang1a789452019-04-29 18:40:29 -07002113
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002114/* Initialization needed at system boot and whenever GNSS service dies. */
2115static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass clazz,
2116 jboolean reinitializeGnssServiceHandle) {
Hridya Valsarajub5b6ffe2017-01-05 15:13:34 -08002117 /*
2118 * Save a pointer to JVM.
2119 */
2120 jint jvmStatus = env->GetJavaVM(&sJvm);
2121 if (jvmStatus != JNI_OK) {
2122 LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
2123 }
2124
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002125 if (reinitializeGnssServiceHandle) {
2126 android_location_GnssLocationProvider_set_gps_service_handle();
2127 }
2128
Yu-Han Yang88d79102018-11-14 14:20:57 -08002129 if (gnssHal == nullptr) {
2130 ALOGE("Unable to get GPS service\n");
2131 return;
2132 }
gomo25208882017-04-15 02:05:25 -07002133
Yu-Han Yang88d79102018-11-14 14:20:57 -08002134 gnssHalDeathRecipient = new GnssDeathRecipient();
2135 hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
2136 if (!linked.isOk()) {
2137 ALOGE("Transaction error in linking to GnssHAL death: %s",
2138 linked.description().c_str());
2139 } else if (!linked) {
2140 ALOGW("Unable to link to GnssHal death notifications");
2141 } else {
2142 ALOGD("Link to death notification successful");
2143 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002144
Yu-Han Yang88d79102018-11-14 14:20:57 -08002145 auto gnssXtra = gnssHal->getExtensionXtra();
2146 if (!gnssXtra.isOk()) {
2147 ALOGD("Unable to get a handle to Xtra");
2148 } else {
2149 gnssXtraIface = gnssXtra;
2150 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002151
Anil Admalb4995e22018-11-16 17:36:21 -08002152 if (gnssHal_V2_0 != nullptr) {
2153 auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
2154 if (!agnssRil_V2_0.isOk()) {
2155 ALOGD("Unable to get a handle to AGnssRil_V2_0");
2156 } else {
2157 agnssRilIface_V2_0 = agnssRil_V2_0;
2158 agnssRilIface = agnssRilIface_V2_0;
2159 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08002160 } else {
Anil Admalb4995e22018-11-16 17:36:21 -08002161 auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
2162 if (!agnssRil_V1_0.isOk()) {
2163 ALOGD("Unable to get a handle to AGnssRil");
2164 } else {
2165 agnssRilIface = agnssRil_V1_0;
2166 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08002167 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002168
Anil Admalc70344b2018-11-16 14:22:38 -08002169 if (gnssHal_V2_0 != nullptr) {
2170 auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
2171 if (!agnss_V2_0.isOk()) {
2172 ALOGD("Unable to get a handle to AGnss_V2_0");
2173 } else {
2174 agnssIface_V2_0 = agnss_V2_0;
2175 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08002176 } else {
Anil Admalc70344b2018-11-16 14:22:38 -08002177 auto agnss_V1_0 = gnssHal->getExtensionAGnss();
2178 if (!agnss_V1_0.isOk()) {
2179 ALOGD("Unable to get a handle to AGnss");
2180 } else {
2181 agnssIface = agnss_V1_0;
2182 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08002183 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002184
Yu-Han Yang88d79102018-11-14 14:20:57 -08002185 auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
2186 if (!gnssNavigationMessage.isOk()) {
2187 ALOGD("Unable to get a handle to GnssNavigationMessage");
2188 } else {
2189 gnssNavigationMessageIface = gnssNavigationMessage;
2190 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002191
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002192 // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means,
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08002193 // 2.1@IGnss can be paired with {1.0, 1,1, 2.0, 2.1}@IGnssMeasurement
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002194 // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement
2195 // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
2196 // 1.0@IGnss is paired with 1.0@IGnssMeasurement
2197 gnssMeasurementIface = nullptr;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08002198 if (gnssHal_V2_1 != nullptr) {
2199 auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1();
2200 if (!gnssMeasurement.isOk()) {
2201 ALOGD("Unable to get a handle to GnssMeasurement_V2_1");
2202 } else {
2203 gnssMeasurementIface_V2_1 = gnssMeasurement;
2204 gnssMeasurementIface_V2_0 = gnssMeasurementIface_V2_1;
2205 gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
2206 gnssMeasurementIface = gnssMeasurementIface_V1_1;
2207 }
2208 }
2209 if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002210 auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
2211 if (!gnssMeasurement.isOk()) {
2212 ALOGD("Unable to get a handle to GnssMeasurement_V2_0");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01002213 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002214 gnssMeasurementIface_V2_0 = gnssMeasurement;
2215 gnssMeasurementIface_V1_1 = gnssMeasurementIface_V2_0;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08002216 gnssMeasurementIface = gnssMeasurementIface_V1_1;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002217 }
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002218 }
2219 if (gnssHal_V1_1 != nullptr && gnssMeasurementIface == nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002220 auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
2221 if (!gnssMeasurement.isOk()) {
2222 ALOGD("Unable to get a handle to GnssMeasurement_V1_1");
2223 } else {
2224 gnssMeasurementIface_V1_1 = gnssMeasurement;
2225 gnssMeasurementIface = gnssMeasurementIface_V1_1;
2226 }
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002227 }
2228 if (gnssMeasurementIface == nullptr) {
2229 auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
2230 if (!gnssMeasurement.isOk()) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002231 ALOGD("Unable to get a handle to GnssMeasurement");
2232 } else {
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002233 gnssMeasurementIface = gnssMeasurement;
Yu-Han Yang88d79102018-11-14 14:20:57 -08002234 }
2235 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002236
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002237 if (gnssHal_V2_1 != nullptr) {
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002238 auto gnssAntennaInfo = gnssHal_V2_1->getExtensionGnssAntennaInfo();
2239 if (!gnssAntennaInfo.isOk()) {
2240 ALOGD("Unable to get a handle to GnssAntennaInfo");
2241 } else {
2242 gnssAntennaInfoIface = gnssAntennaInfo;
2243 }
2244 }
2245
2246 if (gnssHal_V2_1 != nullptr) {
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002247 auto gnssCorrections = gnssHal_V2_1->getExtensionMeasurementCorrections_1_1();
2248 if (!gnssCorrections.isOk()) {
2249 ALOGD("Unable to get a handle to GnssMeasurementCorrections 1.1 interface");
2250 } else {
2251 gnssCorrectionsIface_V1_1 = gnssCorrections;
2252 gnssCorrectionsIface_V1_0 = gnssCorrectionsIface_V1_1;
2253 }
2254 } else if (gnssHal_V2_0 != nullptr) {
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002255 auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
2256 if (!gnssCorrections.isOk()) {
2257 ALOGD("Unable to get a handle to GnssMeasurementCorrections interface");
2258 } else {
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002259 gnssCorrectionsIface_V1_0 = gnssCorrections;
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002260 }
2261 }
2262
Yu-Han Yangbc113102019-04-11 15:55:34 -07002263 // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
2264 // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
2265 // 1.0@IGnss is paired with 1.0@IGnssDebug
2266 gnssDebugIface = nullptr;
Yu-Han Yang72d5b952019-03-26 17:49:33 -07002267 if (gnssHal_V2_0 != nullptr) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002268 auto gnssDebug = gnssHal_V2_0->getExtensionGnssDebug_2_0();
2269 if (!gnssDebug.isOk()) {
2270 ALOGD("Unable to get a handle to GnssDebug_V2_0");
2271 } else {
2272 gnssDebugIface_V2_0 = gnssDebug;
2273 gnssDebugIface = gnssDebugIface_V2_0;
2274 }
Yu-Han Yangbc113102019-04-11 15:55:34 -07002275 }
2276 if (gnssDebugIface == nullptr) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002277 auto gnssDebug = gnssHal->getExtensionGnssDebug();
2278 if (!gnssDebug.isOk()) {
2279 ALOGD("Unable to get a handle to GnssDebug");
2280 } else {
2281 gnssDebugIface = gnssDebug;
2282 }
Yu-Han Yang88d79102018-11-14 14:20:57 -08002283 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002284
Yu-Han Yang88d79102018-11-14 14:20:57 -08002285 auto gnssNi = gnssHal->getExtensionGnssNi();
2286 if (!gnssNi.isOk()) {
2287 ALOGD("Unable to get a handle to GnssNi");
2288 } else {
2289 gnssNiIface = gnssNi;
2290 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002291
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08002292 if (gnssHal_V2_1 != nullptr) {
2293 auto gnssConfiguration = gnssHal_V2_1->getExtensionGnssConfiguration_2_1();
2294 if (!gnssConfiguration.isOk()) {
2295 ALOGD("Unable to get a handle to GnssConfiguration_V2_1");
2296 } else {
2297 gnssConfigurationIface_V2_1 = gnssConfiguration;
2298 gnssConfigurationIface_V2_0 = gnssConfigurationIface_V2_1;
2299 gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_1;
2300 gnssConfigurationIface = gnssConfigurationIface_V2_1;
2301 }
2302 } else if (gnssHal_V2_0 != nullptr) {
Anil Admald71cf142018-12-21 14:59:36 -08002303 auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
2304 if (!gnssConfiguration.isOk()) {
2305 ALOGD("Unable to get a handle to GnssConfiguration_V2_0");
2306 } else {
2307 gnssConfigurationIface_V2_0 = gnssConfiguration;
2308 gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_0;
2309 gnssConfigurationIface = gnssConfigurationIface_V2_0;
2310 }
2311 } else if (gnssHal_V1_1 != nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002312 auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
2313 if (!gnssConfiguration.isOk()) {
Anil Admald71cf142018-12-21 14:59:36 -08002314 ALOGD("Unable to get a handle to GnssConfiguration_V1_1");
Martijn Coenen3a3a4ac2017-01-04 12:57:47 +01002315 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002316 gnssConfigurationIface_V1_1 = gnssConfiguration;
2317 gnssConfigurationIface = gnssConfigurationIface_V1_1;
Wyatt Rileycf879db2017-01-12 13:57:38 -08002318 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002319 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08002320 auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
2321 if (!gnssConfiguration_V1_0.isOk()) {
2322 ALOGD("Unable to get a handle to GnssConfiguration");
2323 } else {
2324 gnssConfigurationIface = gnssConfiguration_V1_0;
2325 }
2326 }
2327
2328 auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
2329 if (!gnssGeofencing.isOk()) {
2330 ALOGD("Unable to get a handle to GnssGeofencing");
2331 } else {
2332 gnssGeofencingIface = gnssGeofencing;
2333 }
2334
Anil Admalb8c235e2019-03-21 18:46:58 +00002335 // If IGnssBatching.hal@2.0 is not supported, use IGnssBatching.hal@1.0
2336 if (gnssHal_V2_0 != nullptr) {
2337 auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0();
2338 if (!gnssBatching_V2_0.isOk()) {
2339 ALOGD("Unable to get a handle to GnssBatching_V2_0");
2340 } else {
2341 gnssBatchingIface_V2_0 = gnssBatching_V2_0;
2342 }
2343 }
2344 if (gnssBatchingIface_V2_0 == nullptr ) {
2345 auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching();
2346 if (!gnssBatching_V1_0.isOk()) {
2347 ALOGD("Unable to get a handle to GnssBatching");
2348 } else {
2349 gnssBatchingIface = gnssBatching_V1_0;
2350 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002351 }
Anil Admal94ec76a2019-01-15 09:42:01 -08002352
2353 if (gnssHal_V2_0 != nullptr) {
2354 auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl();
2355 if (!gnssVisibilityControl.isOk()) {
2356 ALOGD("Unable to get a handle to GnssVisibilityControl interface");
2357 } else {
2358 gnssVisibilityControlIface = gnssVisibilityControl;
2359 }
2360 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002361}
2362
2363static jboolean android_location_GnssLocationProvider_is_supported(
2364 JNIEnv* /* env */, jclass /* clazz */) {
2365 return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
2366}
2367
Anil Admal50ba15e2018-11-01 16:42:42 -07002368static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002369 JNIEnv* /* env */, jclass /* clazz */) {
2370 return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2371}
2372
Anil Admald71cf142018-12-21 14:59:36 -08002373static jobject android_location_GnssConfiguration_get_gnss_configuration_version(
2374 JNIEnv* env, jclass /* jclazz */) {
2375 jint major, minor;
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08002376 if (gnssConfigurationIface_V2_1 != nullptr) {
2377 major = 2;
2378 minor = 1;
2379 }
2380 else if (gnssConfigurationIface_V2_0 != nullptr) {
Anil Admald71cf142018-12-21 14:59:36 -08002381 major = 2;
2382 minor = 0;
2383 } else if (gnssConfigurationIface_V1_1 != nullptr) {
2384 major = 1;
2385 minor = 1;
2386 } else if (gnssConfigurationIface != nullptr) {
2387 major = 1;
2388 minor = 0;
2389 } else {
2390 return nullptr;
2391 }
2392
2393 return createHalInterfaceVersionJavaObject(env, major, minor);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002394}
2395
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002396/* Initialization needed each time the GPS service is shutdown. */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002397static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
2398 /*
2399 * This must be set before calling into the HAL library.
2400 */
2401 if (!mCallbacksObj)
2402 mCallbacksObj = env->NewGlobalRef(obj);
2403
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002404 /*
2405 * Fail if the main interface fails to initialize
2406 */
2407 if (gnssHal == nullptr) {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002408 ALOGE("Unable to initialize GNSS HAL.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002409 return JNI_FALSE;
2410 }
2411
Wyatt Rileyfb840922017-11-08 15:07:58 -08002412 Return<bool> result = false;
Anil Admal68f6b9b2019-04-26 18:28:22 -07002413
2414 // Set top level IGnss.hal callback.
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08002415 sp<IGnssCallback_V2_1> gnssCbIface = new GnssCallback();
2416 if (gnssHal_V2_1 != nullptr) {
2417 result = gnssHal_V2_1->setCallback_2_1(gnssCbIface);
2418 } else if (gnssHal_V2_0 != nullptr) {
gomo226b7b72018-12-12 16:49:39 -08002419 result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
2420 } else if (gnssHal_V1_1 != nullptr) {
gomo48f1a642017-11-10 20:35:46 -08002421 result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
Wyatt Rileyfb840922017-11-08 15:07:58 -08002422 } else {
2423 result = gnssHal->setCallback(gnssCbIface);
2424 }
gomo226b7b72018-12-12 16:49:39 -08002425
Anil Admal2ac70462019-06-28 19:17:41 -07002426 if (!checkHidlReturn(result, "IGnss setCallback() failed.")) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002427 return JNI_FALSE;
2428 }
2429
Anil Admal68f6b9b2019-04-26 18:28:22 -07002430 // Set IGnssXtra.hal callback.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002431 if (gnssXtraIface == nullptr) {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002432 ALOGI("Unable to initialize IGnssXtra interface.");
Hridya Valsarajue8650322016-12-05 20:23:21 -08002433 } else {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002434 sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
Hridya Valsarajue8650322016-12-05 20:23:21 -08002435 result = gnssXtraIface->setCallback(gnssXtraCbIface);
Anil Admal2ac70462019-06-28 19:17:41 -07002436 if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
Hridya Valsarajue8650322016-12-05 20:23:21 -08002437 gnssXtraIface = nullptr;
Hridya Valsarajue8650322016-12-05 20:23:21 -08002438 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002439 }
2440
Anil Admal68f6b9b2019-04-26 18:28:22 -07002441 // Set IAGnss.hal callback.
Anil Admalc70344b2018-11-16 14:22:38 -08002442 if (agnssIface_V2_0 != nullptr) {
2443 sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
Anil Admal2ac70462019-06-28 19:17:41 -07002444 auto agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
2445 checkHidlReturn(agnssStatus, "IAGnss 2.0 setCallback() failed.");
Anil Admalc70344b2018-11-16 14:22:38 -08002446 } else if (agnssIface != nullptr) {
2447 sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
Anil Admal2ac70462019-06-28 19:17:41 -07002448 auto agnssStatus = agnssIface->setCallback(aGnssCbIface);
2449 checkHidlReturn(agnssStatus, "IAGnss setCallback() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002450 } else {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002451 ALOGI("Unable to initialize IAGnss interface.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002452 }
2453
Anil Admal68f6b9b2019-04-26 18:28:22 -07002454 // Set IGnssGeofencing.hal callback.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002455 sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
2456 if (gnssGeofencingIface != nullptr) {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002457 auto status = gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
Anil Admal2ac70462019-06-28 19:17:41 -07002458 checkHidlReturn(status, "IGnssGeofencing setCallback() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002459 } else {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002460 ALOGI("Unable to initialize IGnssGeofencing interface.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002461 }
2462
Anil Admal68f6b9b2019-04-26 18:28:22 -07002463 // Set IGnssNi.hal callback.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002464 sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
Hridya Valsaraju388e9682017-03-08 10:57:06 -08002465 if (gnssNiIface != nullptr) {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002466 auto status = gnssNiIface->setCallback(gnssNiCbIface);
Anil Admal2ac70462019-06-28 19:17:41 -07002467 checkHidlReturn(status, "IGnssNi setCallback() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002468 } else {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002469 ALOGI("Unable to initialize IGnssNi interface.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002470 }
2471
Anil Admal68f6b9b2019-04-26 18:28:22 -07002472 // Set IAGnssRil.hal callback.
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09002473 sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
2474 if (agnssRilIface != nullptr) {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002475 auto status = agnssRilIface->setCallback(aGnssRilCbIface);
Anil Admal2ac70462019-06-28 19:17:41 -07002476 checkHidlReturn(status, "IAGnssRil setCallback() failed.");
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09002477 } else {
Anil Admal68f6b9b2019-04-26 18:28:22 -07002478 ALOGI("Unable to initialize IAGnssRil interface.");
Anil Admal94ec76a2019-01-15 09:42:01 -08002479 }
2480
Anil Admal68f6b9b2019-04-26 18:28:22 -07002481 // Set IGnssVisibilityControl.hal callback.
Anil Admal94ec76a2019-01-15 09:42:01 -08002482 if (gnssVisibilityControlIface != nullptr) {
2483 sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
2484 new GnssVisibilityControlCallback();
Anil Admal68f6b9b2019-04-26 18:28:22 -07002485 result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
Anil Admal2ac70462019-06-28 19:17:41 -07002486 checkHidlReturn(result, "IGnssVisibilityControl setCallback() failed.");
Jaekyun Seokf9038ad2017-11-13 15:03:21 +09002487 }
2488
Anil Admal68f6b9b2019-04-26 18:28:22 -07002489 // Set IMeasurementCorrections.hal callback.
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002490 if (gnssCorrectionsIface_V1_1 != nullptr) {
2491 sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
2492 new MeasurementCorrectionsCallback();
2493 result = gnssCorrectionsIface_V1_1->setCallback(gnssCorrectionsIfaceCbIface);
2494 checkHidlReturn(result, "IMeasurementCorrections 1.1 setCallback() failed.");
2495 } else if (gnssCorrectionsIface_V1_0 != nullptr) {
Anil Admalefd9dc62019-03-12 17:39:20 -07002496 sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
2497 new MeasurementCorrectionsCallback();
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08002498 result = gnssCorrectionsIface_V1_0->setCallback(gnssCorrectionsIfaceCbIface);
2499 checkHidlReturn(result, "IMeasurementCorrections 1.0 setCallback() failed.");
2500 } else {
2501 ALOGI("Unable to find IMeasurementCorrections.");
Anil Admalefd9dc62019-03-12 17:39:20 -07002502 }
2503
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002504 return JNI_TRUE;
2505}
2506
2507static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
Anil Admal2ac70462019-06-28 19:17:41 -07002508 if (gnssHal == nullptr) {
2509 return;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002510 }
Anil Admal2ac70462019-06-28 19:17:41 -07002511
2512 auto result = gnssHal->cleanup();
2513 checkHidlReturn(result, "IGnss cleanup() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002514}
2515
2516static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
2517 jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
gomo48f1a642017-11-10 20:35:46 -08002518 jint preferred_time, jboolean low_power_mode) {
2519 Return<bool> result = false;
2520 if (gnssHal_V1_1 != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08002521 result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
2522 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
2523 min_interval,
2524 preferred_accuracy,
2525 preferred_time,
2526 low_power_mode);
gomo48f1a642017-11-10 20:35:46 -08002527 } else if (gnssHal != nullptr) {
Wyatt Riley46ac9562018-03-02 20:16:58 -08002528 result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
2529 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
2530 min_interval,
2531 preferred_accuracy,
2532 preferred_time);
gomo48f1a642017-11-10 20:35:46 -08002533 }
Anil Admal2ac70462019-06-28 19:17:41 -07002534
2535 return checkHidlReturn(result, "IGnss setPositionMode() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002536}
2537
2538static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
Anil Admal2ac70462019-06-28 19:17:41 -07002539 if (gnssHal == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002540 return JNI_FALSE;
2541 }
Anil Admal2ac70462019-06-28 19:17:41 -07002542
2543 auto result = gnssHal->start();
2544 return checkHidlReturn(result, "IGnss start() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002545}
2546
2547static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
Anil Admal2ac70462019-06-28 19:17:41 -07002548 if (gnssHal == nullptr) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002549 return JNI_FALSE;
2550 }
Anil Admal2ac70462019-06-28 19:17:41 -07002551
2552 auto result = gnssHal->stop();
2553 return checkHidlReturn(result, "IGnss stop() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002554}
Anil Admal2ac70462019-06-28 19:17:41 -07002555
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002556static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
2557 jobject /* obj */,
2558 jint flags) {
Anil Admal2ac70462019-06-28 19:17:41 -07002559 if (gnssHal == nullptr) {
2560 return;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002561 }
Anil Admal2ac70462019-06-28 19:17:41 -07002562
2563 auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
2564 checkHidlReturn(result, "IGnss deleteAidingData() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002565}
2566
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002567static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
2568 JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
Anil Admalb4995e22018-11-16 17:36:21 -08002569 IAGnssRil_V1_0::AGnssRefLocation location;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002570
2571 if (agnssRilIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07002572 ALOGE("%s: IAGnssRil interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002573 return;
2574 }
2575
Anil Admalb4995e22018-11-16 17:36:21 -08002576 switch (static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type)) {
2577 case IAGnssRil_V1_0::AGnssRefLocationType::GSM_CELLID:
2578 case IAGnssRil_V1_0::AGnssRefLocationType::UMTS_CELLID:
2579 location.type = static_cast<IAGnssRil_V1_0::AGnssRefLocationType>(type);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002580 location.cellID.mcc = mcc;
2581 location.cellID.mnc = mnc;
2582 location.cellID.lac = lac;
2583 location.cellID.cid = cid;
2584 break;
2585 default:
2586 ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
2587 return;
2588 break;
2589 }
2590
Anil Admal2ac70462019-06-28 19:17:41 -07002591 auto result = agnssRilIface->setRefLocation(location);
2592 checkHidlReturn(result, "IAGnssRil setRefLocation() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002593}
2594
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002595static void android_location_GnssLocationProvider_agps_set_id(JNIEnv* env, jobject /* obj */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002596 jint type, jstring setid_string) {
2597 if (agnssRilIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07002598 ALOGE("%s: IAGnssRil interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002599 return;
2600 }
2601
Anil Admalc70344b2018-11-16 14:22:38 -08002602 ScopedJniString jniSetId{env, setid_string};
Anil Admal2ac70462019-06-28 19:17:41 -07002603 auto result = agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
2604 checkHidlReturn(result, "IAGnssRil setSetId() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002605}
2606
2607static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
2608 jbyteArray nmeaArray, jint buffer_size) {
2609 // this should only be called from within a call to reportNmea
2610 jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
2611 int length = GnssCallback::sNmeaStringLength;
2612 if (length > buffer_size)
2613 length = buffer_size;
2614 memcpy(nmea, GnssCallback::sNmeaString, length);
2615 env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
2616 return (jint) length;
2617}
2618
2619static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
2620 jlong time, jlong timeReference, jint uncertainty) {
Anil Admal2ac70462019-06-28 19:17:41 -07002621 if (gnssHal == nullptr) {
2622 return;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002623 }
Anil Admal2ac70462019-06-28 19:17:41 -07002624
2625 auto result = gnssHal->injectTime(time, timeReference, uncertainty);
2626 checkHidlReturn(result, "IGnss injectTime() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002627}
2628
Yu-Han Yange7baef32018-02-09 13:58:17 -08002629static void android_location_GnssLocationProvider_inject_best_location(
2630 JNIEnv*,
2631 jobject,
2632 jint gnssLocationFlags,
2633 jdouble latitudeDegrees,
2634 jdouble longitudeDegrees,
2635 jdouble altitudeMeters,
2636 jfloat speedMetersPerSec,
2637 jfloat bearingDegrees,
2638 jfloat horizontalAccuracyMeters,
2639 jfloat verticalAccuracyMeters,
2640 jfloat speedAccuracyMetersPerSecond,
2641 jfloat bearingAccuracyDegrees,
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002642 jlong timestamp,
2643 jint elapsedRealtimeFlags,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +00002644 jlong elapsedRealtimeNanos,
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07002645 jdouble elapsedRealtimeUncertaintyNanos) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002646 if (gnssHal_V2_0 != nullptr) {
2647 GnssLocation_V2_0 location = createGnssLocation_V2_0(
2648 gnssLocationFlags,
2649 latitudeDegrees,
2650 longitudeDegrees,
2651 altitudeMeters,
2652 speedMetersPerSec,
2653 bearingDegrees,
2654 horizontalAccuracyMeters,
2655 verticalAccuracyMeters,
2656 speedAccuracyMetersPerSecond,
2657 bearingAccuracyDegrees,
2658 timestamp,
2659 elapsedRealtimeFlags,
Pierre Fite-georgel19f6cbfe2019-03-04 23:23:18 +00002660 elapsedRealtimeNanos,
2661 elapsedRealtimeUncertaintyNanos);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002662 auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
Anil Admal2ac70462019-06-28 19:17:41 -07002663 checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed.");
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002664 return;
2665 }
2666
Yu-Han Yange7baef32018-02-09 13:58:17 -08002667 if (gnssHal_V1_1 != nullptr) {
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002668 GnssLocation_V1_0 location = createGnssLocation_V1_0(
Yu-Han Yange7baef32018-02-09 13:58:17 -08002669 gnssLocationFlags,
2670 latitudeDegrees,
2671 longitudeDegrees,
2672 altitudeMeters,
2673 speedMetersPerSec,
2674 bearingDegrees,
2675 horizontalAccuracyMeters,
2676 verticalAccuracyMeters,
2677 speedAccuracyMetersPerSecond,
2678 bearingAccuracyDegrees,
2679 timestamp);
2680 auto result = gnssHal_V1_1->injectBestLocation(location);
Anil Admal2ac70462019-06-28 19:17:41 -07002681 checkHidlReturn(result, "IGnss injectBestLocation() failed.");
Yu-Han Yange7baef32018-02-09 13:58:17 -08002682 }
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002683
Anil Admal2ac70462019-06-28 19:17:41 -07002684 ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available.");
Yu-Han Yange7baef32018-02-09 13:58:17 -08002685}
2686
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002687static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
2688 jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
Anil Admal2ac70462019-06-28 19:17:41 -07002689 if (gnssHal == nullptr) {
2690 return;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002691 }
Anil Admal2ac70462019-06-28 19:17:41 -07002692
2693 auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
2694 checkHidlReturn(result, "IGnss injectLocation() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002695}
2696
Kevin Tang8c6ac672019-03-22 12:31:01 -07002697static jboolean android_location_GnssLocationProvider_supports_psds(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002698 JNIEnv* /* env */, jobject /* obj */) {
2699 return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2700}
2701
Kevin Tang8c6ac672019-03-22 12:31:01 -07002702static void android_location_GnssLocationProvider_inject_psds_data(JNIEnv* env, jobject /* obj */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002703 jbyteArray data, jint length) {
2704 if (gnssXtraIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07002705 ALOGE("%s: IGnssXtra interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002706 return;
2707 }
2708
2709 jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
Anil Admal2ac70462019-06-28 19:17:41 -07002710 auto result = gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
2711 checkHidlReturn(result, "IGnssXtra injectXtraData() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002712 env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
2713}
2714
Anil Admalc70344b2018-11-16 14:22:38 -08002715struct AGnssDispatcher {
2716 static void dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn, jint apnIpType);
2717 static void dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env, jlong networkHandle,
2718 jstring apn, jint apnIpType);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002719
Anil Admalc70344b2018-11-16 14:22:38 -08002720 template <class T>
2721 static void dataConnClosed(sp<T> agnssIface);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002722
Anil Admalc70344b2018-11-16 14:22:38 -08002723 template <class T>
2724 static void dataConnFailed(sp<T> agnssIface);
2725
2726 template <class T, class U>
2727 static void setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname, jint port);
2728
2729private:
2730 AGnssDispatcher() = delete;
Anil Admalc70344b2018-11-16 14:22:38 -08002731};
2732
2733void AGnssDispatcher::dataConnOpen(sp<IAGnss_V1_0> agnssIface, JNIEnv* env, jstring apn,
2734 jint apnIpType) {
2735 ScopedJniString jniApn{env, apn};
2736 auto result = agnssIface->dataConnOpen(jniApn,
2737 static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
Anil Admal2ac70462019-06-28 19:17:41 -07002738 checkHidlReturn(result, "IAGnss dataConnOpen() failed. APN and its IP type not set.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002739}
2740
Anil Admalc70344b2018-11-16 14:22:38 -08002741void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
2742 jlong networkHandle, jstring apn, jint apnIpType) {
2743 ScopedJniString jniApn{env, apn};
2744 auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
2745 static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
Anil Admal2ac70462019-06-28 19:17:41 -07002746 checkHidlReturn(result, "IAGnss 2.0 dataConnOpen() failed. APN and its IP type not set.");
Anil Admalc70344b2018-11-16 14:22:38 -08002747}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002748
Anil Admalc70344b2018-11-16 14:22:38 -08002749template<class T>
2750void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002751 auto result = agnssIface->dataConnClosed();
Anil Admal2ac70462019-06-28 19:17:41 -07002752 checkHidlReturn(result, "IAGnss dataConnClosed() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002753}
2754
Anil Admalc70344b2018-11-16 14:22:38 -08002755template<class T>
2756void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002757 auto result = agnssIface->dataConnFailed();
Anil Admal2ac70462019-06-28 19:17:41 -07002758 checkHidlReturn(result, "IAGnss dataConnFailed() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002759}
2760
Anil Admalc70344b2018-11-16 14:22:38 -08002761template <class T, class U>
2762void AGnssDispatcher::setServer(sp<T> agnssIface, JNIEnv* env, jint type, jstring hostname,
2763 jint port) {
2764 ScopedJniString jniHostName{env, hostname};
2765 auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
2766 jniHostName, port);
Anil Admal2ac70462019-06-28 19:17:41 -07002767 checkHidlReturn(result, "IAGnss setServer() failed. Host name and port not set.");
Anil Admalc70344b2018-11-16 14:22:38 -08002768}
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002769
Anil Admalc70344b2018-11-16 14:22:38 -08002770static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
2771 JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
2772 if (apn == nullptr) {
2773 jniThrowException(env, "java/lang/IllegalArgumentException", nullptr);
2774 return;
2775 }
2776
2777 if (agnssIface_V2_0 != nullptr) {
2778 AGnssDispatcher::dataConnOpen(agnssIface_V2_0, env, networkHandle, apn, apnIpType);
2779 } else if (agnssIface != nullptr) {
2780 AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
2781 } else {
Anil Admal2ac70462019-06-28 19:17:41 -07002782 ALOGE("%s: IAGnss interface not available.", __func__);
Anil Admalc70344b2018-11-16 14:22:38 -08002783 return;
2784 }
2785}
2786
2787static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
2788 jobject /* obj */) {
2789 if (agnssIface_V2_0 != nullptr) {
2790 AGnssDispatcher::dataConnClosed(agnssIface_V2_0);
2791 } else if (agnssIface != nullptr) {
2792 AGnssDispatcher::dataConnClosed(agnssIface);
2793 } else {
Anil Admal2ac70462019-06-28 19:17:41 -07002794 ALOGE("%s: IAGnss interface not available.", __func__);
Anil Admalc70344b2018-11-16 14:22:38 -08002795 return;
2796 }
2797}
2798
2799static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
2800 jobject /* obj */) {
2801 if (agnssIface_V2_0 != nullptr) {
2802 AGnssDispatcher::dataConnFailed(agnssIface_V2_0);
2803 } else if (agnssIface != nullptr) {
2804 AGnssDispatcher::dataConnFailed(agnssIface);
2805 } else {
Anil Admal2ac70462019-06-28 19:17:41 -07002806 ALOGE("%s: IAGnss interface not available.", __func__);
Anil Admalc70344b2018-11-16 14:22:38 -08002807 return;
2808 }
2809}
2810
2811static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
2812 jint type, jstring hostname, jint port) {
2813 if (agnssIface_V2_0 != nullptr) {
2814 AGnssDispatcher::setServer<IAGnss_V2_0, IAGnssCallback_V2_0>(agnssIface_V2_0, env, type,
2815 hostname, port);
2816 } else if (agnssIface != nullptr) {
2817 AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
2818 hostname, port);
2819 } else {
Anil Admal2ac70462019-06-28 19:17:41 -07002820 ALOGE("%s: IAGnss interface not available.", __func__);
Anil Admalc70344b2018-11-16 14:22:38 -08002821 return;
2822 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002823}
2824
2825static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
Anil Admal2ac70462019-06-28 19:17:41 -07002826 jobject /* obj */, jint notifId, jint response) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002827 if (gnssNiIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07002828 ALOGE("%s: IGnssNi interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002829 return;
2830 }
2831
Anil Admal2ac70462019-06-28 19:17:41 -07002832 auto result = gnssNiIface->respond(notifId,
2833 static_cast<IGnssNiCallback::GnssUserResponseType>(response));
2834 checkHidlReturn(result, "IGnssNi respond() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002835}
2836
Anil Admal2ac70462019-06-28 19:17:41 -07002837const IGnssDebug_V1_0::SatelliteData& getSatelliteData(
2838 const hidl_vec<IGnssDebug_V1_0::SatelliteData>& satelliteDataArray, size_t i) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002839 return satelliteDataArray[i];
2840}
2841
Anil Admal2ac70462019-06-28 19:17:41 -07002842const IGnssDebug_V1_0::SatelliteData& getSatelliteData(
2843 const hidl_vec<IGnssDebug_V2_0::SatelliteData>& satelliteDataArray, size_t i) {
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002844 return satelliteDataArray[i].v1_0;
2845}
2846
2847template<class T>
2848uint32_t getConstellationType(const hidl_vec<T>& satelliteDataArray, size_t i) {
2849 return static_cast<uint32_t>(satelliteDataArray[i].constellation);
2850}
2851
2852template<class T>
2853static jstring parseDebugData(JNIEnv* env, std::stringstream& internalState, const T& data) {
2854 internalState << "Gnss Location Data:: ";
2855 if (!data.position.valid) {
2856 internalState << "not valid";
2857 } else {
2858 internalState << "LatitudeDegrees: " << data.position.latitudeDegrees
2859 << ", LongitudeDegrees: " << data.position.longitudeDegrees
2860 << ", altitudeMeters: " << data.position.altitudeMeters
2861 << ", speedMetersPerSecond: " << data.position.speedMetersPerSec
2862 << ", bearingDegrees: " << data.position.bearingDegrees
2863 << ", horizontalAccuracyMeters: "
2864 << data.position.horizontalAccuracyMeters
2865 << ", verticalAccuracyMeters: " << data.position.verticalAccuracyMeters
2866 << ", speedAccuracyMetersPerSecond: "
2867 << data.position.speedAccuracyMetersPerSecond
2868 << ", bearingAccuracyDegrees: " << data.position.bearingAccuracyDegrees
2869 << ", ageSeconds: " << data.position.ageSeconds;
2870 }
2871 internalState << std::endl;
2872
2873 internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
2874 << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs
2875 << ", frequencyUncertaintyNsPerSec: "
2876 << data.time.frequencyUncertaintyNsPerSec << std::endl;
2877
2878 if (data.satelliteDataArray.size() != 0) {
2879 internalState << "Satellite Data for " << data.satelliteDataArray.size()
2880 << " satellites:: " << std::endl;
2881 }
2882
2883 internalState << "constell: 1=GPS, 2=SBAS, 3=GLO, 4=QZSS, 5=BDS, 6=GAL, 7=IRNSS; "
2884 << "ephType: 0=Eph, 1=Alm, 2=Unk; "
2885 << "ephSource: 0=Demod, 1=Supl, 2=Server, 3=Unk; "
2886 << "ephHealth: 0=Good, 1=Bad, 2=Unk" << std::endl;
2887 for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
2888 IGnssDebug_V1_0::SatelliteData satelliteData =
2889 getSatelliteData(data.satelliteDataArray, i);
2890 internalState << "constell: "
2891 << getConstellationType(data.satelliteDataArray, i)
2892 << ", svid: " << std::setw(3) << satelliteData.svid
2893 << ", serverPredAvail: "
2894 << satelliteData.serverPredictionIsAvailable
2895 << ", serverPredAgeSec: " << std::setw(7)
2896 << satelliteData.serverPredictionAgeSeconds
2897 << ", ephType: "
2898 << static_cast<uint32_t>(satelliteData.ephemerisType)
2899 << ", ephSource: "
2900 << static_cast<uint32_t>(satelliteData.ephemerisSource)
2901 << ", ephHealth: "
2902 << static_cast<uint32_t>(satelliteData.ephemerisHealth)
2903 << ", ephAgeSec: " << std::setw(7)
2904 << satelliteData.ephemerisAgeSeconds << std::endl;
2905 }
2906 return (jstring) env->NewStringUTF(internalState.str().c_str());
2907}
2908
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002909static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
2910 jobject /* obj */) {
Anil Admal2ac70462019-06-28 19:17:41 -07002911 jstring internalStateStr = nullptr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002912 /*
Anil Admalefd9dc62019-03-12 17:39:20 -07002913 * TODO: Create a jobject to represent GnssDebug.
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002914 */
Wyatt Riley268c6e02017-03-29 10:21:46 -07002915
2916 std::stringstream internalState;
2917
2918 if (gnssDebugIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07002919 ALOGE("%s: IGnssDebug interface not available.", __func__);
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002920 } else if (gnssDebugIface_V2_0 != nullptr) {
2921 IGnssDebug_V2_0::DebugData data;
Anil Admal2ac70462019-06-28 19:17:41 -07002922 auto result = gnssDebugIface_V2_0->getDebugData_2_0(
2923 [&data](const IGnssDebug_V2_0::DebugData& debugData) {
2924 data = debugData;
2925 });
2926 if (checkHidlReturn(result, "IGnssDebug getDebugData_2_0() failed.")) {
2927 internalStateStr = parseDebugData(env, internalState, data);
2928 }
Yu-Han Yang8e8c7412019-03-15 09:10:18 -07002929 } else {
2930 IGnssDebug_V1_0::DebugData data;
Anil Admal2ac70462019-06-28 19:17:41 -07002931 auto result = gnssDebugIface->getDebugData(
2932 [&data](const IGnssDebug_V1_0::DebugData& debugData) {
2933 data = debugData;
2934 });
2935 if (checkHidlReturn(result, "IGnssDebug getDebugData() failed.")) {
2936 internalStateStr = parseDebugData(env, internalState, data);
2937 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002938 }
Anil Admal2ac70462019-06-28 19:17:41 -07002939 return internalStateStr;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002940}
2941
Anil Admal94ec76a2019-01-15 09:42:01 -08002942static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported(
2943 JNIEnv* /* env */, jclass /* clazz */) {
2944 return (gnssVisibilityControlIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2945}
2946
Anil Admal50ba15e2018-11-01 16:42:42 -07002947static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002948 jobject /* obj */,
2949 jboolean connected,
2950 jint type,
2951 jboolean roaming,
2952 jboolean available,
Anil Admalb4995e22018-11-16 17:36:21 -08002953 jstring apn,
2954 jlong networkHandle,
2955 jshort capabilities) {
Anil Admalb4995e22018-11-16 17:36:21 -08002956 if (agnssRilIface_V2_0 != nullptr) {
Anil Admalc70344b2018-11-16 14:22:38 -08002957 ScopedJniString jniApn{env, apn};
Anil Admalb4995e22018-11-16 17:36:21 -08002958 IAGnssRil_V2_0::NetworkAttributes networkAttributes = {
2959 .networkHandle = static_cast<uint64_t>(networkHandle),
2960 .isConnected = static_cast<bool>(connected),
2961 .capabilities = static_cast<uint16_t>(capabilities),
Anil Admalc70344b2018-11-16 14:22:38 -08002962 .apn = jniApn
Anil Admalb4995e22018-11-16 17:36:21 -08002963 };
2964
2965 auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
Anil Admal2ac70462019-06-28 19:17:41 -07002966 checkHidlReturn(result, "IAGnssRil updateNetworkState_2_0() failed.");
Anil Admalc70344b2018-11-16 14:22:38 -08002967 } else if (agnssRilIface != nullptr) {
2968 ScopedJniString jniApn{env, apn};
2969 hidl_string hidlApn{jniApn};
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002970 auto result = agnssRilIface->updateNetworkState(connected,
Anil Admalb4995e22018-11-16 17:36:21 -08002971 static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
Anil Admal2ac70462019-06-28 19:17:41 -07002972 checkHidlReturn(result, "IAGnssRil updateNetworkState() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002973
Anil Admalc70344b2018-11-16 14:22:38 -08002974 if (!hidlApn.empty()) {
2975 result = agnssRilIface->updateNetworkAvailability(available, hidlApn);
Anil Admal2ac70462019-06-28 19:17:41 -07002976 checkHidlReturn(result, "IAGnssRil updateNetworkAvailability() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002977 }
Anil Admalc70344b2018-11-16 14:22:38 -08002978 } else {
Anil Admal2ac70462019-06-28 19:17:41 -07002979 ALOGE("%s: IAGnssRil interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002980 }
2981}
2982
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002983static jboolean android_location_GnssGeofenceProvider_is_geofence_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002984 JNIEnv* /* env */, jobject /* obj */) {
2985 return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
2986}
2987
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07002988static jboolean android_location_GnssGeofenceProvider_add_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002989 jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
2990 jint last_transition, jint monitor_transition, jint notification_responsiveness,
2991 jint unknown_timer) {
Anil Admal2ac70462019-06-28 19:17:41 -07002992 if (gnssGeofencingIface == nullptr) {
2993 ALOGE("%s: IGnssGeofencing interface not available.", __func__);
2994 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002995 }
Anil Admal2ac70462019-06-28 19:17:41 -07002996
2997 auto result = gnssGeofencingIface->addGeofence(
2998 geofenceId, latitude, longitude, radius,
2999 static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
3000 monitor_transition, notification_responsiveness, unknown_timer);
3001 return checkHidlReturn(result, "IGnssGeofencing addGeofence() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003002}
3003
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07003004static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003005 jobject /* obj */, jint geofenceId) {
Anil Admal2ac70462019-06-28 19:17:41 -07003006 if (gnssGeofencingIface == nullptr) {
3007 ALOGE("%s: IGnssGeofencing interface not available.", __func__);
3008 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003009 }
Anil Admal2ac70462019-06-28 19:17:41 -07003010
3011 auto result = gnssGeofencingIface->removeGeofence(geofenceId);
3012 return checkHidlReturn(result, "IGnssGeofencing removeGeofence() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003013}
3014
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07003015static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003016 jobject /* obj */, jint geofenceId) {
Anil Admal2ac70462019-06-28 19:17:41 -07003017 if (gnssGeofencingIface == nullptr) {
3018 ALOGE("%s: IGnssGeofencing interface not available.", __func__);
3019 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003020 }
Anil Admal2ac70462019-06-28 19:17:41 -07003021
3022 auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
3023 return checkHidlReturn(result, "IGnssGeofencing pauseGeofence() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003024}
3025
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07003026static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003027 jobject /* obj */, jint geofenceId, jint monitor_transition) {
Anil Admal2ac70462019-06-28 19:17:41 -07003028 if (gnssGeofencingIface == nullptr) {
3029 ALOGE("%s: IGnssGeofencing interface not available.", __func__);
3030 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003031 }
Anil Admal2ac70462019-06-28 19:17:41 -07003032
3033 auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
3034 return checkHidlReturn(result, "IGnssGeofencing resumeGeofence() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003035}
3036
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00003037static jboolean android_location_GnssAntennaInfoProvider_is_antenna_info_supported(JNIEnv* env,
3038 jclass clazz) {
3039 if (gnssAntennaInfoIface != nullptr) {
3040 return JNI_TRUE;
3041 }
3042 return JNI_FALSE;
3043}
3044
3045static jboolean android_location_GnssAntennaInfoProvider_start_antenna_info_listening(
3046 JNIEnv* /* env */, jobject /* obj */) {
3047 if (gnssAntennaInfoIface == nullptr) {
3048 ALOGE("%s: IGnssAntennaInfo interface not available.", __func__);
3049 return JNI_FALSE;
3050 }
3051
3052 sp<GnssAntennaInfoCallback> cbIface = new GnssAntennaInfoCallback();
3053
3054 auto result = gnssAntennaInfoIface->setCallback(cbIface);
3055
3056 if (!checkHidlReturn(result, "IGnssAntennaInfo setCallback() failed.")) {
3057 return JNI_FALSE;
3058 }
3059
3060 IGnssAntennaInfo::GnssAntennaInfoStatus initRet = result;
3061 if (initRet != IGnssAntennaInfo::GnssAntennaInfoStatus::SUCCESS) {
3062 ALOGE("An error has been found on GnssAntennaInfoInterface::init, status=%d",
3063 static_cast<int32_t>(initRet));
3064 return JNI_FALSE;
3065 } else {
3066 ALOGD("gnss antenna info has been enabled");
3067 }
3068
3069 return JNI_TRUE;
3070}
3071
3072static jboolean android_location_GnssAntennaInfoProvider_stop_antenna_info_listening(
3073 JNIEnv* /* env */, jobject /* obj */) {
3074 if (gnssAntennaInfoIface == nullptr) {
3075 ALOGE("%s: IGnssAntennaInfo interface not available.", __func__);
3076 return JNI_FALSE;
3077 }
3078
3079 auto result = gnssAntennaInfoIface->close();
3080 return checkHidlReturn(result, "IGnssAntennaInfo close() failed.");
3081}
3082
Yu-Han Yang8de21502018-04-23 01:40:25 -07003083static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003084 JNIEnv* env, jclass clazz) {
3085 if (gnssMeasurementIface != nullptr) {
destradaaea8a8a62014-06-23 18:19:03 -07003086 return JNI_TRUE;
3087 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003088
destradaaea8a8a62014-06-23 18:19:03 -07003089 return JNI_FALSE;
3090}
3091
Yu-Han Yang8de21502018-04-23 01:40:25 -07003092static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
gomo48f1a642017-11-10 20:35:46 -08003093 JNIEnv* /* env */,
3094 jobject /* obj */,
3095 jboolean enableFullTracking) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003096 if (gnssMeasurementIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003097 ALOGE("%s: IGnssMeasurement interface not available.", __func__);
destradaaea8a8a62014-06-23 18:19:03 -07003098 return JNI_FALSE;
3099 }
3100
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003101 sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
Anil Admal2ac70462019-06-28 19:17:41 -07003102 Return<IGnssMeasurement_V1_0::GnssMeasurementStatus> result =
Yu-Han Yang88d79102018-11-14 14:20:57 -08003103 IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
Yu-Han Yang5b9a3362019-11-10 13:31:03 -08003104 if (gnssMeasurementIface_V2_1 != nullptr) {
3105 result = gnssMeasurementIface_V2_1->setCallback_2_1(cbIface, enableFullTracking);
3106 } else if (gnssMeasurementIface_V2_0 != nullptr) {
Yu-Han Yang88d79102018-11-14 14:20:57 -08003107 result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
3108 } else if (gnssMeasurementIface_V1_1 != nullptr) {
3109 result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface, enableFullTracking);
gomo48f1a642017-11-10 20:35:46 -08003110 } else {
3111 if (enableFullTracking == JNI_TRUE) {
Yu-Han Yang57939132020-06-22 11:42:07 -07003112 ALOGW("Full tracking mode not supported in 1.0 GNSS HAL.");
gomo48f1a642017-11-10 20:35:46 -08003113 }
3114 result = gnssMeasurementIface->setCallback(cbIface);
3115 }
3116
Anil Admal2ac70462019-06-28 19:17:41 -07003117 if (!checkHidlReturn(result, "IGnssMeasurement setCallback() failed.")) {
3118 return JNI_FALSE;
3119 }
3120
3121 IGnssMeasurement_V1_0::GnssMeasurementStatus initRet = result;
3122 if (initRet != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003123 ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
Anil Admal2ac70462019-06-28 19:17:41 -07003124 static_cast<int32_t>(initRet));
destradaaea8a8a62014-06-23 18:19:03 -07003125 return JNI_FALSE;
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003126 } else {
Yu-Han Yang88d79102018-11-14 14:20:57 -08003127 ALOGD("gnss measurement infc has been enabled");
destradaaea8a8a62014-06-23 18:19:03 -07003128 }
3129
3130 return JNI_TRUE;
3131}
3132
Yu-Han Yang8de21502018-04-23 01:40:25 -07003133static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
destradaaea8a8a62014-06-23 18:19:03 -07003134 JNIEnv* env,
3135 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003136 if (gnssMeasurementIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003137 ALOGE("%s: IGnssMeasurement interface not available.", __func__);
destradaaea8a8a62014-06-23 18:19:03 -07003138 return JNI_FALSE;
3139 }
3140
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003141 auto result = gnssMeasurementIface->close();
Anil Admal2ac70462019-06-28 19:17:41 -07003142 return checkHidlReturn(result, "IGnssMeasurement close() failed.");
destradaaea8a8a62014-06-23 18:19:03 -07003143}
3144
Anil Admalefd9dc62019-03-12 17:39:20 -07003145static jboolean
3146 android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported(
3147 JNIEnv* env, jclass clazz) {
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003148 if (gnssCorrectionsIface_V1_0 != nullptr || gnssCorrectionsIface_V1_1 != nullptr) {
Anil Admalefd9dc62019-03-12 17:39:20 -07003149 return JNI_TRUE;
3150 }
3151
3152 return JNI_FALSE;
3153}
3154
Sasha Kuznetsovb6b98482020-02-19 11:57:51 -08003155static SingleSatCorrection_V1_0 getSingleSatCorrection_1_0_withoutConstellation(
3156 JNIEnv* env, jobject singleSatCorrectionObj) {
3157 jint correctionFlags = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags);
3158 jint satId = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId);
3159 jfloat carrierFreqHz =
3160 env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatCarrierFreq);
3161 jfloat probSatIsLos =
3162 env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatIsLosProb);
3163 jfloat eplMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl);
3164 jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEplUnc);
3165 uint16_t corrFlags = static_cast<uint16_t>(correctionFlags);
3166 jobject reflectingPlaneObj;
3167 bool has_ref_plane = (corrFlags & GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE) != 0;
3168 if (has_ref_plane) {
3169 reflectingPlaneObj =
3170 env->CallObjectMethod(singleSatCorrectionObj, method_correctionSatRefPlane);
3171 }
3172
3173 ReflectingPlane reflectingPlane;
3174 if (has_ref_plane) {
3175 jdouble latitudeDegreesRefPlane =
3176 env->CallDoubleMethod(reflectingPlaneObj, method_correctionPlaneLatDeg);
3177 jdouble longitudeDegreesRefPlane =
3178 env->CallDoubleMethod(reflectingPlaneObj, method_correctionPlaneLngDeg);
3179 jdouble altitudeDegreesRefPlane =
3180 env->CallDoubleMethod(reflectingPlaneObj, method_correctionPlaneAltDeg);
3181 jdouble azimuthDegreeRefPlane =
3182 env->CallDoubleMethod(reflectingPlaneObj, method_correctionPlaneAzimDeg);
3183 reflectingPlane = {
3184 .latitudeDegrees = latitudeDegreesRefPlane,
3185 .longitudeDegrees = longitudeDegreesRefPlane,
3186 .altitudeMeters = altitudeDegreesRefPlane,
3187 .azimuthDegrees = azimuthDegreeRefPlane,
3188 };
3189 }
3190
3191 SingleSatCorrection_V1_0 singleSatCorrection = {
3192 .singleSatCorrectionFlags = corrFlags,
3193 .svid = static_cast<uint16_t>(satId),
3194 .carrierFrequencyHz = carrierFreqHz,
3195 .probSatIsLos = probSatIsLos,
3196 .excessPathLengthMeters = eplMeters,
3197 .excessPathLengthUncertaintyMeters = eplUncMeters,
3198 .reflectingPlane = reflectingPlane,
3199 };
3200
3201 return singleSatCorrection;
3202}
3203
3204static void getSingleSatCorrectionList_1_1(JNIEnv* env, jobject singleSatCorrectionList,
3205 hidl_vec<SingleSatCorrection_V1_1>& list) {
3206 for (uint16_t i = 0; i < list.size(); ++i) {
3207 jobject singleSatCorrectionObj =
3208 env->CallObjectMethod(singleSatCorrectionList, method_correctionListGet, i);
3209
3210 SingleSatCorrection_V1_0 singleSatCorrection_1_0 =
3211 getSingleSatCorrection_1_0_withoutConstellation(env, singleSatCorrectionObj);
3212
3213 jint constType = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatConstType);
3214
3215 SingleSatCorrection_V1_1 singleSatCorrection_1_1 = {
3216 .v1_0 = singleSatCorrection_1_0,
3217 .constellation = static_cast<GnssConstellationType_V2_0>(constType),
3218 };
3219
3220 list[i] = singleSatCorrection_1_1;
3221 }
3222}
3223
3224static void getSingleSatCorrectionList_1_0(JNIEnv* env, jobject singleSatCorrectionList,
3225 hidl_vec<SingleSatCorrection_V1_0>& list) {
3226 for (uint16_t i = 0; i < list.size(); ++i) {
3227 jobject singleSatCorrectionObj =
3228 env->CallObjectMethod(singleSatCorrectionList, method_correctionListGet, i);
3229
3230 SingleSatCorrection_V1_0 singleSatCorrection =
3231 getSingleSatCorrection_1_0_withoutConstellation(env, singleSatCorrectionObj);
3232
3233 jint constType = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatConstType);
3234
3235 singleSatCorrection.constellation = static_cast<GnssConstellationType_V1_0>(constType),
3236
3237 list[i] = singleSatCorrection;
3238 }
3239}
Anil Admalefd9dc62019-03-12 17:39:20 -07003240static jboolean
3241 android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections(
gomo226b7b72018-12-12 16:49:39 -08003242 JNIEnv* env,
3243 jobject obj /* clazz*/,
3244 jobject correctionsObj) {
3245
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003246 if (gnssCorrectionsIface_V1_0 == nullptr && gnssCorrectionsIface_V1_1 == nullptr) {
Anil Admalefd9dc62019-03-12 17:39:20 -07003247 ALOGW("Trying to inject GNSS measurement corrections on a chipset that does not"
3248 " support them.");
gomo226b7b72018-12-12 16:49:39 -08003249 return JNI_FALSE;
3250 }
gomo226b7b72018-12-12 16:49:39 -08003251
gomo226b7b72018-12-12 16:49:39 -08003252 jobject singleSatCorrectionList = env->CallObjectMethod(correctionsObj,
3253 method_correctionsGetSingleSatCorrectionList);
3254
gomo226b7b72018-12-12 16:49:39 -08003255 auto len = (singleSatCorrectionList == nullptr)
3256 ? 0
3257 : env->CallIntMethod(singleSatCorrectionList, method_listSize);
gomo5716ab82019-02-27 22:57:56 -08003258 if (len == 0) {
3259 ALOGI("Empty correction list injected....Returning with no HAL injection");
3260 return JNI_TRUE;
3261 }
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003262
3263 jdouble latitudeDegreesCorr = env->CallDoubleMethod(
3264 correctionsObj, method_correctionsGetLatitudeDegrees);
3265 jdouble longitudeDegreesCorr = env->CallDoubleMethod(
3266 correctionsObj, method_correctionsGetLongitudeDegrees);
3267 jdouble altitudeDegreesCorr = env->CallDoubleMethod(
3268 correctionsObj, method_correctionsGetAltitudeMeters);
3269 jdouble horizontalPositionUncertaintyMeters = env->CallDoubleMethod(
3270 correctionsObj, method_correctionsGetHorPosUncMeters);
3271 jdouble verticalPositionUncertaintyMeters = env->CallDoubleMethod(
3272 correctionsObj, method_correctionsGetVerPosUncMeters);
3273 jlong toaGpsNanosOfWeek = env->CallLongMethod(
3274 correctionsObj, method_correctionsGetToaGpsNanosecondsOfWeek);
3275
3276 MeasurementCorrections_V1_0 measurementCorrections_1_0 = {
gomo226b7b72018-12-12 16:49:39 -08003277 .latitudeDegrees = latitudeDegreesCorr,
3278 .longitudeDegrees = longitudeDegreesCorr,
3279 .altitudeMeters = altitudeDegreesCorr,
gomo6ec95382019-01-26 03:08:18 -08003280 .horizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters,
3281 .verticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters,
gomo226b7b72018-12-12 16:49:39 -08003282 .toaGpsNanosecondsOfWeek = static_cast<uint64_t>(toaGpsNanosOfWeek),
gomo226b7b72018-12-12 16:49:39 -08003283 };
3284
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003285 if (gnssCorrectionsIface_V1_1 != nullptr) {
3286
3287 jboolean hasEnvironmentBearingCorr = env->CallBooleanMethod(
3288 correctionsObj, method_correctionsHasEnvironmentBearing);
3289 jfloat environmentBearingDegreesCorr = env->CallFloatMethod(
3290 correctionsObj, method_correctionsGetEnvironmentBearingDegrees);
3291 jfloat environmentBearingUncertaintyDegreesCorr = env->CallFloatMethod(
3292 correctionsObj, method_correctionsGetEnvironmentBearingUncertaintyDegrees);
3293
Sasha Kuznetsovb6b98482020-02-19 11:57:51 -08003294 hidl_vec<SingleSatCorrection_V1_1> list(len);
3295 getSingleSatCorrectionList_1_1(env, singleSatCorrectionList, list);
3296
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003297 MeasurementCorrections_V1_1 measurementCorrections_1_1 = {
Sasha Kuznetsovb6b98482020-02-19 11:57:51 -08003298 .v1_0 = measurementCorrections_1_0,
3299 .hasEnvironmentBearing = static_cast<bool>(hasEnvironmentBearingCorr),
3300 .environmentBearingDegrees = environmentBearingDegreesCorr,
3301 .environmentBearingUncertaintyDegrees = environmentBearingUncertaintyDegreesCorr,
3302 .satCorrections = list,
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003303 };
3304
3305 auto result = gnssCorrectionsIface_V1_1->setCorrections_1_1(measurementCorrections_1_1);
3306 return checkHidlReturn(result, "IMeasurementCorrections 1.1 setCorrections() failed.");
3307 }
3308
Sasha Kuznetsovb6b98482020-02-19 11:57:51 -08003309 hidl_vec<SingleSatCorrection_V1_0> list(len);
3310 getSingleSatCorrectionList_1_0(env, singleSatCorrectionList, list);
3311 measurementCorrections_1_0.satCorrections = list;
3312
Sasha Kuznetsov1ebf6152020-01-06 20:55:14 -08003313 auto result = gnssCorrectionsIface_V1_0->setCorrections(measurementCorrections_1_0);
3314 return checkHidlReturn(result, "IMeasurementCorrections 1.0 setCorrections() failed.");
gomo226b7b72018-12-12 16:49:39 -08003315}
3316
Yu-Han Yang23d92162018-04-19 06:03:00 -07003317static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
destradaa4b3e3932014-07-21 18:01:47 -07003318 JNIEnv* env,
3319 jclass clazz) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003320 if (gnssNavigationMessageIface != nullptr) {
destradaa4b3e3932014-07-21 18:01:47 -07003321 return JNI_TRUE;
3322 }
3323 return JNI_FALSE;
3324}
3325
Yu-Han Yang23d92162018-04-19 06:03:00 -07003326static jboolean android_location_GnssNavigationMessageProvider_start_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07003327 JNIEnv* env,
3328 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003329 if (gnssNavigationMessageIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003330 ALOGE("%s: IGnssNavigationMessage interface not available.", __func__);
destradaa4b3e3932014-07-21 18:01:47 -07003331 return JNI_FALSE;
3332 }
3333
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003334 sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
3335 new GnssNavigationMessageCallback();
Anil Admal2ac70462019-06-28 19:17:41 -07003336 auto result = gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
3337 if (!checkHidlReturn(result, "IGnssNavigationMessage setCallback() failed.")) {
3338 return JNI_FALSE;
3339 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003340
Anil Admal2ac70462019-06-28 19:17:41 -07003341 IGnssNavigationMessage::GnssNavigationMessageStatus initRet = result;
3342 if (initRet != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
3343 ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(initRet));
destradaa4b3e3932014-07-21 18:01:47 -07003344 return JNI_FALSE;
3345 }
3346
3347 return JNI_TRUE;
3348}
3349
Yu-Han Yang23d92162018-04-19 06:03:00 -07003350static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_message_collection(
destradaa4b3e3932014-07-21 18:01:47 -07003351 JNIEnv* env,
3352 jobject obj) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003353 if (gnssNavigationMessageIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003354 ALOGE("%s: IGnssNavigationMessage interface not available.", __func__);
destradaa4b3e3932014-07-21 18:01:47 -07003355 return JNI_FALSE;
3356 }
3357
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003358 auto result = gnssNavigationMessageIface->close();
Anil Admal2ac70462019-06-28 19:17:41 -07003359 return checkHidlReturn(result, "IGnssNavigationMessage close() failed.");
destradaa4b3e3932014-07-21 18:01:47 -07003360}
3361
Anil Admald71cf142018-12-21 14:59:36 -08003362static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,
3363 jobject,
3364 jint emergencySuplPdn) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003365 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003366 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003367 return JNI_FALSE;
Tsuwei Chen52617bb2014-08-25 11:49:11 -07003368 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003369
3370 auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
Anil Admal2ac70462019-06-28 19:17:41 -07003371 return checkHidlReturn(result, "IGnssConfiguration setEmergencySuplPdn() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003372}
3373
Anil Admald71cf142018-12-21 14:59:36 -08003374static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003375 jobject,
3376 jint version) {
3377 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003378 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003379 return JNI_FALSE;
3380 }
3381 auto result = gnssConfigurationIface->setSuplVersion(version);
Anil Admal2ac70462019-06-28 19:17:41 -07003382 return checkHidlReturn(result, "IGnssConfiguration setSuplVersion() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003383}
3384
Anil Admald71cf142018-12-21 14:59:36 -08003385static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*,
3386 jobject,
3387 jint suplEs) {
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08003388 if (gnssConfigurationIface_V2_0 != nullptr || gnssConfigurationIface_V2_1 != nullptr) {
3389 ALOGI("Config parameter SUPL_ES is deprecated in IGnssConfiguration.hal version 2.0 and higher.");
Anil Admald71cf142018-12-21 14:59:36 -08003390 return JNI_FALSE;
3391 }
3392
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003393 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003394 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003395 return JNI_FALSE;
3396 }
3397
3398 auto result = gnssConfigurationIface->setSuplEs(suplEs);
Anil Admal2ac70462019-06-28 19:17:41 -07003399 return checkHidlReturn(result, "IGnssConfiguration setSuplEs() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003400}
3401
Anil Admald71cf142018-12-21 14:59:36 -08003402static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*,
3403 jobject,
3404 jint mode) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003405 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003406 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003407 return JNI_FALSE;
3408 }
3409
3410 auto result = gnssConfigurationIface->setSuplMode(mode);
Anil Admal2ac70462019-06-28 19:17:41 -07003411 return checkHidlReturn(result, "IGnssConfiguration setSuplMode() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003412}
3413
Anil Admald71cf142018-12-21 14:59:36 -08003414static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*,
3415 jobject,
3416 jint gpsLock) {
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08003417 if (gnssConfigurationIface_V2_0 != nullptr || gnssConfigurationIface_V2_1 != nullptr) {
Anil Admald71cf142018-12-21 14:59:36 -08003418 ALOGI("Config parameter GPS_LOCK is deprecated in IGnssConfiguration.hal version 2.0.");
3419 return JNI_FALSE;
3420 }
3421
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003422 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003423 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003424 return JNI_FALSE;
3425 }
3426
3427 auto result = gnssConfigurationIface->setGpsLock(gpsLock);
Anil Admal2ac70462019-06-28 19:17:41 -07003428 return checkHidlReturn(result, "IGnssConfiguration setGpsLock() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003429}
3430
Anil Admald71cf142018-12-21 14:59:36 -08003431static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003432 jobject,
3433 jint lppProfile) {
3434 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003435 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003436 return JNI_FALSE;
3437 }
3438
3439 auto result = gnssConfigurationIface->setLppProfile(lppProfile);
Anil Admal2ac70462019-06-28 19:17:41 -07003440 return checkHidlReturn(result, "IGnssConfiguration setLppProfile() failed.");
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003441}
3442
Anil Admald71cf142018-12-21 14:59:36 -08003443static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*,
3444 jobject,
3445 jint gnssPosProtocol) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003446 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003447 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003448 return JNI_FALSE;
3449 }
3450
3451 auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
Anil Admal2ac70462019-06-28 19:17:41 -07003452 return checkHidlReturn(result, "IGnssConfiguration setGlonassPositioningProtocol() failed.");
Tsuwei Chen52617bb2014-08-25 11:49:11 -07003453}
3454
Anil Admald71cf142018-12-21 14:59:36 -08003455static jboolean android_location_GnssConfiguration_set_satellite_blacklist(
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003456 JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08003457 if (gnssConfigurationIface_V1_1 == nullptr && gnssConfigurationIface_V2_1 == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003458 ALOGI("IGnssConfiguration interface does not support satellite blacklist.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003459 return JNI_FALSE;
3460 }
3461
3462 jint *constellation_array = env->GetIntArrayElements(constellations, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07003463 if (nullptr == constellation_array) {
3464 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003465 return JNI_FALSE;
3466 }
3467 jsize length = env->GetArrayLength(constellations);
3468
3469 jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
WyattRiley840c0b22018-10-31 09:03:53 -07003470 if (nullptr == sv_id_array) {
3471 ALOGI("GetIntArrayElements returns nullptr.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003472 return JNI_FALSE;
3473 }
3474
3475 if (length != env->GetArrayLength(sv_ids)) {
3476 ALOGI("Lengths of constellations and sv_ids are inconsistent.");
3477 return JNI_FALSE;
3478 }
3479
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08003480 if (gnssConfigurationIface_V2_1 != nullptr) {
3481 hidl_vec<IGnssConfiguration_V2_1::BlacklistedSource> sources;
3482 sources.resize(length);
3483
3484 for (int i = 0; i < length; i++) {
3485 sources[i].constellation = static_cast<GnssConstellationType_V2_0>(constellation_array[i]);
3486 sources[i].svid = sv_id_array[i];
3487 }
3488
3489 auto result = gnssConfigurationIface_V2_1->setBlacklist_2_1(sources);
3490 return checkHidlReturn(result, "IGnssConfiguration_V2_1 setBlacklist_2_1() failed.");
3491 }
3492
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003493 hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
3494 sources.resize(length);
3495
3496 for (int i = 0; i < length; i++) {
Sasha Kuznetsovae89e782019-12-13 20:35:06 -08003497 sources[i].constellation = static_cast<GnssConstellationType_V1_0>(constellation_array[i]);
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003498 sources[i].svid = sv_id_array[i];
3499 }
3500
3501 auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
Anil Admal2ac70462019-06-28 19:17:41 -07003502 return checkHidlReturn(result, "IGnssConfiguration setBlacklist() failed.");
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07003503}
3504
Anil Admald71cf142018-12-21 14:59:36 -08003505static jboolean android_location_GnssConfiguration_set_es_extension_sec(
3506 JNIEnv*, jobject, jint emergencyExtensionSeconds) {
3507 if (gnssConfigurationIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003508 ALOGE("%s: IGnssConfiguration interface not available.", __func__);
Anil Admald71cf142018-12-21 14:59:36 -08003509 return JNI_FALSE;
3510 }
3511
3512 if (gnssConfigurationIface_V2_0 == nullptr) {
3513 ALOGI("Config parameter ES_EXTENSION_SEC is not supported in IGnssConfiguration.hal"
3514 " versions earlier than 2.0.");
3515 return JNI_FALSE;
3516 }
3517
3518 auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds);
Anil Admal2ac70462019-06-28 19:17:41 -07003519 return checkHidlReturn(result, "IGnssConfiguration setEsExtensionSec() failed.");
Anil Admald71cf142018-12-21 14:59:36 -08003520}
3521
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003522static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003523 if (gnssBatchingIface == nullptr) {
3524 return 0; // batching not supported, size = 0
3525 }
3526 auto result = gnssBatchingIface->getBatchSize();
Anil Admal2ac70462019-06-28 19:17:41 -07003527 if (!checkHidlReturn(result, "IGnssBatching getBatchSize() failed.")) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003528 return 0; // failure in binder, don't support batching
3529 }
Anil Admal2ac70462019-06-28 19:17:41 -07003530
3531 return static_cast<jint>(result);
Wyatt Rileycf879db2017-01-12 13:57:38 -08003532}
3533
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003534static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
Anil Admalb8c235e2019-03-21 18:46:58 +00003535 if (gnssBatchingIface_V2_0 != nullptr) {
3536 sp<IGnssBatchingCallback_V2_0> gnssBatchingCbIface_V2_0 = new GnssBatchingCallback_V2_0();
Anil Admal2ac70462019-06-28 19:17:41 -07003537 auto result = gnssBatchingIface_V2_0->init_2_0(gnssBatchingCbIface_V2_0);
3538 return checkHidlReturn(result, "IGnssBatching init_2_0() failed.");
Anil Admalb8c235e2019-03-21 18:46:58 +00003539 } else if (gnssBatchingIface != nullptr) {
3540 sp<IGnssBatchingCallback_V1_0> gnssBatchingCbIface_V1_0 = new GnssBatchingCallback_V1_0();
Anil Admal2ac70462019-06-28 19:17:41 -07003541 auto result = gnssBatchingIface->init(gnssBatchingCbIface_V1_0);
3542 return checkHidlReturn(result, "IGnssBatching init() failed.");
Anil Admalb8c235e2019-03-21 18:46:58 +00003543 } else {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003544 return JNI_FALSE; // batching not supported
3545 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08003546}
3547
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003548static void android_location_GnssBatchingProvider_cleanup_batching(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003549 if (gnssBatchingIface == nullptr) {
3550 return; // batching not supported
3551 }
Anil Admal2ac70462019-06-28 19:17:41 -07003552 auto result = gnssBatchingIface->cleanup();
3553 checkHidlReturn(result, "IGnssBatching cleanup() failed.");
Wyatt Rileycf879db2017-01-12 13:57:38 -08003554}
3555
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003556static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
Wyatt Rileycf879db2017-01-12 13:57:38 -08003557 jlong periodNanos, jboolean wakeOnFifoFull) {
3558 if (gnssBatchingIface == nullptr) {
3559 return JNI_FALSE; // batching not supported
3560 }
3561
Anil Admalb8c235e2019-03-21 18:46:58 +00003562 IGnssBatching_V1_0::Options options;
Wyatt Rileycf879db2017-01-12 13:57:38 -08003563 options.periodNanos = periodNanos;
3564 if (wakeOnFifoFull) {
Anil Admalb8c235e2019-03-21 18:46:58 +00003565 options.flags = static_cast<uint8_t>(IGnssBatching_V1_0::Flag::WAKEUP_ON_FIFO_FULL);
Wyatt Rileycf879db2017-01-12 13:57:38 -08003566 } else {
3567 options.flags = 0;
3568 }
3569
Anil Admal2ac70462019-06-28 19:17:41 -07003570 auto result = gnssBatchingIface->start(options);
3571 return checkHidlReturn(result, "IGnssBatching start() failed.");
Wyatt Rileycf879db2017-01-12 13:57:38 -08003572}
3573
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003574static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003575 if (gnssBatchingIface == nullptr) {
3576 return; // batching not supported
3577 }
Anil Admal2ac70462019-06-28 19:17:41 -07003578 auto result = gnssBatchingIface->flush();
3579 checkHidlReturn(result, "IGnssBatching flush() failed.");
Wyatt Rileycf879db2017-01-12 13:57:38 -08003580}
3581
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003582static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08003583 if (gnssBatchingIface == nullptr) {
3584 return JNI_FALSE; // batching not supported
3585 }
Anil Admal2ac70462019-06-28 19:17:41 -07003586 auto result = gnssBatchingIface->stop();
3587 return checkHidlReturn(result, "IGnssBatching stop() failed.");
Wyatt Rileycf879db2017-01-12 13:57:38 -08003588}
3589
Anil Admal94ec76a2019-01-15 09:42:01 -08003590static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
3591 JNIEnv* env, jobject, jobjectArray proxyApps) {
3592 if (gnssVisibilityControlIface == nullptr) {
Anil Admal2ac70462019-06-28 19:17:41 -07003593 ALOGI("IGnssVisibilityControl interface not available.");
Anil Admal94ec76a2019-01-15 09:42:01 -08003594 return JNI_FALSE;
3595 }
3596
3597 const jsize length = env->GetArrayLength(proxyApps);
3598 hidl_vec<hidl_string> hidlProxyApps(length);
3599 for (int i = 0; i < length; ++i) {
3600 jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i));
3601 ScopedJniString jniProxyApp(env, proxyApp);
3602 hidlProxyApps[i] = jniProxyApp;
3603 }
3604
3605 auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
Anil Admal2ac70462019-06-28 19:17:41 -07003606 return checkHidlReturn(result, "IGnssVisibilityControl enableNfwLocationAccess() failed.");
Anil Admal94ec76a2019-01-15 09:42:01 -08003607}
3608
Daniel Micay76f6a862015-09-19 17:31:01 -04003609static const JNINativeMethod sMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 /* name, signature, funcPtr */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003611 {"class_init_native", "()V", reinterpret_cast<void *>(
3612 android_location_GnssLocationProvider_class_init_native)},
3613 {"native_is_supported", "()Z", reinterpret_cast<void *>(
3614 android_location_GnssLocationProvider_is_supported)},
Anil Admal0c2b21bd2019-05-03 18:29:02 -07003615 {"native_init_once", "(Z)V", reinterpret_cast<void *>(
Yu-Han Yang6d317352018-03-15 11:53:01 -07003616 android_location_GnssLocationProvider_init_once)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003617 {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
3618 {"native_cleanup", "()V", reinterpret_cast<void *>(
3619 android_location_GnssLocationProvider_cleanup)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08003620 {"native_set_position_mode", "(IIIIIZ)Z", reinterpret_cast<void *>(
3621 android_location_GnssLocationProvider_set_position_mode)},
3622 {"native_start", "()Z", reinterpret_cast<void *>(
3623 android_location_GnssLocationProvider_start)},
3624 {"native_stop", "()Z", reinterpret_cast<void *>(
3625 android_location_GnssLocationProvider_stop)},
3626 {"native_delete_aiding_data", "(I)V", reinterpret_cast<void *>(
3627 android_location_GnssLocationProvider_delete_aiding_data)},
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003628 {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
3629 android_location_GnssLocationProvider_read_nmea)},
3630 {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
3631 android_location_GnssLocationProvider_inject_time)},
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07003632 {"native_inject_best_location", "(IDDDFFFFFFJIJD)V", reinterpret_cast<void *>(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08003633 android_location_GnssLocationProvider_inject_best_location)},
3634 {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
3635 android_location_GnssLocationProvider_inject_location)},
Kevin Tang8c6ac672019-03-22 12:31:01 -07003636 {"native_supports_psds", "()Z", reinterpret_cast<void *>(
3637 android_location_GnssLocationProvider_supports_psds)},
3638 {"native_inject_psds_data", "([BI)V", reinterpret_cast<void *>(
3639 android_location_GnssLocationProvider_inject_psds_data)},
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08003640 {"native_agps_set_id", "(ILjava/lang/String;)V", reinterpret_cast<void *>(
3641 android_location_GnssLocationProvider_agps_set_id)},
3642 {"native_agps_set_ref_location_cellid", "(IIIII)V", reinterpret_cast<void *>(
3643 android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
3644 {"native_set_agps_server", "(ILjava/lang/String;I)V", reinterpret_cast<void *>(
3645 android_location_GnssLocationProvider_set_agps_server)},
3646 {"native_send_ni_response", "(II)V", reinterpret_cast<void *>(
3647 android_location_GnssLocationProvider_send_ni_response)},
3648 {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(
3649 android_location_GnssLocationProvider_get_internal_state)},
Anil Admal94ec76a2019-01-15 09:42:01 -08003650 {"native_is_gnss_visibility_control_supported", "()Z", reinterpret_cast<void *>(
3651 android_location_GnssLocationProvider_is_gnss_visibility_control_supported)},
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003652};
3653
3654static const JNINativeMethod sMethodsBatching[] = {
3655 /* name, signature, funcPtr */
Wyatt Rileycf879db2017-01-12 13:57:38 -08003656 {"native_get_batch_size",
3657 "()I",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003658 reinterpret_cast<void *>(android_location_GnssBatchingProvider_get_batch_size)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08003659 {"native_start_batch",
3660 "(JZ)Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003661 reinterpret_cast<void *>(android_location_GnssBatchingProvider_start_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08003662 {"native_flush_batch",
3663 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003664 reinterpret_cast<void *>(android_location_GnssBatchingProvider_flush_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08003665 {"native_stop_batch",
3666 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003667 reinterpret_cast<void *>(android_location_GnssBatchingProvider_stop_batch)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08003668 {"native_init_batching",
3669 "()Z",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003670 reinterpret_cast<void *>(android_location_GnssBatchingProvider_init_batching)},
Wyatt Rileycf879db2017-01-12 13:57:38 -08003671 {"native_cleanup_batching",
3672 "()V",
Yu-Han Yang3557cc72018-03-21 12:48:36 -07003673 reinterpret_cast<void *>(android_location_GnssBatchingProvider_cleanup_batching)},
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003674};
3675
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00003676static const JNINativeMethod sAntennaInfoMethods[] = {
3677 /* name, signature, funcPtr */
3678 {"native_is_antenna_info_supported", "()Z",
3679 reinterpret_cast<void*>(
3680 android_location_GnssAntennaInfoProvider_is_antenna_info_supported)},
3681 {"native_start_antenna_info_listening", "()Z",
3682 reinterpret_cast<void*>(
3683 android_location_GnssAntennaInfoProvider_start_antenna_info_listening)},
3684 {"native_stop_antenna_info_listening", "()Z",
3685 reinterpret_cast<void*>(
3686 android_location_GnssAntennaInfoProvider_stop_antenna_info_listening)},
3687};
3688
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07003689static const JNINativeMethod sGeofenceMethods[] = {
3690 /* name, signature, funcPtr */
3691 {"native_is_geofence_supported",
3692 "()Z",
3693 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_is_geofence_supported)},
3694 {"native_add_geofence",
3695 "(IDDDIIII)Z",
3696 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_add_geofence)},
3697 {"native_remove_geofence",
3698 "(I)Z",
3699 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_remove_geofence)},
3700 {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
3701 android_location_GnssGeofenceProvider_pause_geofence)},
3702 {"native_resume_geofence",
3703 "(II)Z",
3704 reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
3705};
3706
Yu-Han Yang8de21502018-04-23 01:40:25 -07003707static const JNINativeMethod sMeasurementMethods[] = {
gomo226b7b72018-12-12 16:49:39 -08003708 /* name, signature, funcPtr */
3709 {"native_is_measurement_supported", "()Z",
Anil Admalefd9dc62019-03-12 17:39:20 -07003710 reinterpret_cast<void*>(
3711 android_location_GnssMeasurementsProvider_is_measurement_supported)},
gomo226b7b72018-12-12 16:49:39 -08003712 {"native_start_measurement_collection", "(Z)Z",
Anil Admalefd9dc62019-03-12 17:39:20 -07003713 reinterpret_cast<void*>(
3714 android_location_GnssMeasurementsProvider_start_measurement_collection)},
gomo226b7b72018-12-12 16:49:39 -08003715 {"native_stop_measurement_collection", "()Z",
Anil Admalefd9dc62019-03-12 17:39:20 -07003716 reinterpret_cast<void*>(
3717 android_location_GnssMeasurementsProvider_stop_measurement_collection)},
3718};
3719
3720static const JNINativeMethod sMeasurementCorrectionsMethods[] = {
3721 /* name, signature, funcPtr */
3722 {"native_is_measurement_corrections_supported", "()Z",
3723 reinterpret_cast<void*>(
3724 android_location_GnssMeasurementCorrectionsProvider_is_measurement_corrections_supported)},
gomo226b7b72018-12-12 16:49:39 -08003725 {"native_inject_gnss_measurement_corrections",
Anil Admalefd9dc62019-03-12 17:39:20 -07003726 "(Landroid/location/GnssMeasurementCorrections;)Z",
3727 reinterpret_cast<void*>(
3728 android_location_GnssMeasurementCorrectionsProvider_inject_gnss_measurement_corrections)},
Yu-Han Yang8de21502018-04-23 01:40:25 -07003729};
3730
Yu-Han Yang23d92162018-04-19 06:03:00 -07003731static const JNINativeMethod sNavigationMessageMethods[] = {
3732 /* name, signature, funcPtr */
3733 {"native_is_navigation_message_supported",
3734 "()Z",
3735 reinterpret_cast<void *>(
3736 android_location_GnssNavigationMessageProvider_is_navigation_message_supported)},
3737 {"native_start_navigation_message_collection",
3738 "()Z",
3739 reinterpret_cast<void *>(
3740 android_location_GnssNavigationMessageProvider_start_navigation_message_collection)},
3741 {"native_stop_navigation_message_collection",
3742 "()Z",
3743 reinterpret_cast<void *>(
3744 android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
3745};
3746
Anil Admal50ba15e2018-11-01 16:42:42 -07003747static const JNINativeMethod sNetworkConnectivityMethods[] = {
3748 /* name, signature, funcPtr */
3749 {"native_is_agps_ril_supported", "()Z",
3750 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
3751 {"native_update_network_state",
Anil Admalb4995e22018-11-16 17:36:21 -08003752 "(ZIZZLjava/lang/String;JS)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07003753 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
3754 {"native_agps_data_conn_open",
Anil Admalc70344b2018-11-16 14:22:38 -08003755 "(JLjava/lang/String;I)V",
Anil Admal50ba15e2018-11-01 16:42:42 -07003756 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
3757 {"native_agps_data_conn_closed",
3758 "()V",
3759 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
3760 {"native_agps_data_conn_failed",
3761 "()V",
3762 reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
3763};
3764
Anil Admald71cf142018-12-21 14:59:36 -08003765static const JNINativeMethod sConfigurationMethods[] = {
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -07003766 /* name, signature, funcPtr */
3767 {"native_get_gnss_configuration_version",
3768 "()Lcom/android/server/location/gnss/GnssConfiguration$HalInterfaceVersion;",
3769 reinterpret_cast<void*>(
3770 android_location_GnssConfiguration_get_gnss_configuration_version)},
3771 {"native_set_supl_es", "(I)Z",
3772 reinterpret_cast<void*>(android_location_GnssConfiguration_set_supl_es)},
3773 {"native_set_supl_version", "(I)Z",
3774 reinterpret_cast<void*>(android_location_GnssConfiguration_set_supl_version)},
3775 {"native_set_supl_mode", "(I)Z",
3776 reinterpret_cast<void*>(android_location_GnssConfiguration_set_supl_mode)},
3777 {"native_set_lpp_profile", "(I)Z",
3778 reinterpret_cast<void*>(android_location_GnssConfiguration_set_lpp_profile)},
3779 {"native_set_gnss_pos_protocol_select", "(I)Z",
3780 reinterpret_cast<void*>(android_location_GnssConfiguration_set_gnss_pos_protocol_select)},
3781 {"native_set_gps_lock", "(I)Z",
3782 reinterpret_cast<void*>(android_location_GnssConfiguration_set_gps_lock)},
3783 {"native_set_emergency_supl_pdn", "(I)Z",
3784 reinterpret_cast<void*>(android_location_GnssConfiguration_set_emergency_supl_pdn)},
3785 {"native_set_satellite_blacklist", "([I[I)Z",
3786 reinterpret_cast<void*>(android_location_GnssConfiguration_set_satellite_blacklist)},
3787 {"native_set_es_extension_sec", "(I)Z",
3788 reinterpret_cast<void*>(android_location_GnssConfiguration_set_es_extension_sec)},
Anil Admald71cf142018-12-21 14:59:36 -08003789};
3790
Anil Admal94ec76a2019-01-15 09:42:01 -08003791static const JNINativeMethod sVisibilityControlMethods[] = {
3792 /* name, signature, funcPtr */
3793 {"native_enable_nfw_location_access",
3794 "([Ljava/lang/String;)Z",
3795 reinterpret_cast<void *>(
3796 android_location_GnssVisibilityControl_enable_nfw_location_access)},
3797};
3798
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07003799int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -07003800 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssAntennaInfoProvider",
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00003801 sAntennaInfoMethods, NELEM(sAntennaInfoMethods));
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -07003802 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssBatchingProvider",
3803 sMethodsBatching, NELEM(sMethodsBatching));
3804 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssGeofenceProvider",
3805 sGeofenceMethods, NELEM(sGeofenceMethods));
3806 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssMeasurementsProvider",
3807 sMeasurementMethods, NELEM(sMeasurementMethods));
3808 jniRegisterNativeMethods(env,
3809 "com/android/server/location/gnss/GnssMeasurementCorrectionsProvider",
3810 sMeasurementCorrectionsMethods, NELEM(sMeasurementCorrectionsMethods));
3811 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssNavigationMessageProvider",
3812 sNavigationMessageMethods, NELEM(sNavigationMessageMethods));
3813 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssNetworkConnectivityHandler",
3814 sNetworkConnectivityMethods, NELEM(sNetworkConnectivityMethods));
3815 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssConfiguration",
3816 sConfigurationMethods, NELEM(sConfigurationMethods));
3817 jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssVisibilityControl",
3818 sVisibilityControlMethods, NELEM(sVisibilityControlMethods));
3819 return jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssLocationProvider",
3820 sMethods, NELEM(sMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821}
3822
3823} /* namespace android */