• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 package com.android.server.location.gnss.hal;
18 
19 import static com.android.server.location.gnss.GnssManagerService.TAG;
20 
21 import android.annotation.CallbackExecutor;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.Nullable;
25 import android.location.GnssAntennaInfo;
26 import android.location.GnssAssistance;
27 import android.location.GnssCapabilities;
28 import android.location.GnssMeasurementCorrections;
29 import android.location.GnssMeasurementsEvent;
30 import android.location.GnssNavigationMessage;
31 import android.location.GnssSignalType;
32 import android.location.GnssStatus;
33 import android.location.Location;
34 import android.location.flags.Flags;
35 import android.os.Binder;
36 import android.os.Handler;
37 import android.os.SystemClock;
38 import android.util.Log;
39 
40 import com.android.internal.annotations.GuardedBy;
41 import com.android.internal.annotations.VisibleForTesting;
42 import com.android.internal.util.ArrayUtils;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.FgThread;
45 import com.android.server.location.gnss.GnssConfiguration;
46 import com.android.server.location.gnss.GnssPowerStats;
47 import com.android.server.location.injector.EmergencyHelper;
48 import com.android.server.location.injector.Injector;
49 
50 import java.lang.annotation.ElementType;
51 import java.lang.annotation.Retention;
52 import java.lang.annotation.RetentionPolicy;
53 import java.lang.annotation.Target;
54 import java.util.ArrayList;
55 import java.util.List;
56 import java.util.Objects;
57 import java.util.concurrent.CountDownLatch;
58 import java.util.concurrent.Executor;
59 import java.util.concurrent.TimeUnit;
60 import java.util.concurrent.atomic.AtomicReference;
61 
62 /**
63  * Entry point for most GNSS HAL commands and callbacks.
64  */
65 public class GnssNative {
66 
67     // IMPORTANT - must match GnssPositionMode enum in IGnss.hal
68     public static final int GNSS_POSITION_MODE_STANDALONE = 0;
69     public static final int GNSS_POSITION_MODE_MS_BASED = 1;
70     public static final int GNSS_POSITION_MODE_MS_ASSISTED = 2;
71 
72     @IntDef(prefix = "GNSS_POSITION_MODE_", value = {GNSS_POSITION_MODE_STANDALONE,
73             GNSS_POSITION_MODE_MS_BASED, GNSS_POSITION_MODE_MS_ASSISTED})
74     @Retention(RetentionPolicy.SOURCE)
75     public @interface GnssPositionMode {}
76 
77     // IMPORTANT - must match GnssPositionRecurrence enum in IGnss.hal
78     public static final int GNSS_POSITION_RECURRENCE_PERIODIC = 0;
79     public static final int GNSS_POSITION_RECURRENCE_SINGLE = 1;
80 
81     @IntDef(prefix = "GNSS_POSITION_RECURRENCE_", value = {GNSS_POSITION_RECURRENCE_PERIODIC,
82             GNSS_POSITION_RECURRENCE_SINGLE})
83     @Retention(RetentionPolicy.SOURCE)
84     public @interface GnssPositionRecurrence {}
85 
86     // IMPORTANT - must match the GnssLocationFlags enum in types.hal
87     public static final int GNSS_LOCATION_HAS_LAT_LONG = 1;
88     public static final int GNSS_LOCATION_HAS_ALTITUDE = 2;
89     public static final int GNSS_LOCATION_HAS_SPEED = 4;
90     public static final int GNSS_LOCATION_HAS_BEARING = 8;
91     public static final int GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
92     public static final int GNSS_LOCATION_HAS_VERTICAL_ACCURACY = 32;
93     public static final int GNSS_LOCATION_HAS_SPEED_ACCURACY = 64;
94     public static final int GNSS_LOCATION_HAS_BEARING_ACCURACY = 128;
95 
96     @IntDef(flag = true, prefix = "GNSS_LOCATION_", value = {GNSS_LOCATION_HAS_LAT_LONG,
97             GNSS_LOCATION_HAS_ALTITUDE, GNSS_LOCATION_HAS_SPEED, GNSS_LOCATION_HAS_BEARING,
98             GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY, GNSS_LOCATION_HAS_VERTICAL_ACCURACY,
99             GNSS_LOCATION_HAS_SPEED_ACCURACY, GNSS_LOCATION_HAS_BEARING_ACCURACY})
100     @Retention(RetentionPolicy.SOURCE)
101     public @interface GnssLocationFlags {}
102 
103     // IMPORTANT - must match the ElapsedRealtimeFlags enum in types.hal
104     public static final int GNSS_REALTIME_HAS_TIMESTAMP_NS = 1;
105     public static final int GNSS_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
106 
107     @IntDef(flag = true, value = {GNSS_REALTIME_HAS_TIMESTAMP_NS,
108             GNSS_REALTIME_HAS_TIME_UNCERTAINTY_NS})
109     @Retention(RetentionPolicy.SOURCE)
110     public @interface GnssRealtimeFlags {}
111 
112     // IMPORTANT - must match the GnssAidingData enum in IGnss.hal
113     public static final int GNSS_AIDING_TYPE_EPHEMERIS = 0x0001;
114     public static final int GNSS_AIDING_TYPE_ALMANAC = 0x0002;
115     public static final int GNSS_AIDING_TYPE_POSITION = 0x0004;
116     public static final int GNSS_AIDING_TYPE_TIME = 0x0008;
117     public static final int GNSS_AIDING_TYPE_IONO = 0x0010;
118     public static final int GNSS_AIDING_TYPE_UTC = 0x0020;
119     public static final int GNSS_AIDING_TYPE_HEALTH = 0x0040;
120     public static final int GNSS_AIDING_TYPE_SVDIR = 0x0080;
121     public static final int GNSS_AIDING_TYPE_SVSTEER = 0x0100;
122     public static final int GNSS_AIDING_TYPE_SADATA = 0x0200;
123     public static final int GNSS_AIDING_TYPE_RTI = 0x0400;
124     public static final int GNSS_AIDING_TYPE_CELLDB_INFO = 0x8000;
125     public static final int GNSS_AIDING_TYPE_ALL = 0xFFFF;
126 
127     @IntDef(flag = true, prefix = "GNSS_AIDING_", value = {GNSS_AIDING_TYPE_EPHEMERIS,
128             GNSS_AIDING_TYPE_ALMANAC, GNSS_AIDING_TYPE_POSITION, GNSS_AIDING_TYPE_TIME,
129             GNSS_AIDING_TYPE_IONO, GNSS_AIDING_TYPE_UTC, GNSS_AIDING_TYPE_HEALTH,
130             GNSS_AIDING_TYPE_SVDIR, GNSS_AIDING_TYPE_SVSTEER, GNSS_AIDING_TYPE_SADATA,
131             GNSS_AIDING_TYPE_RTI, GNSS_AIDING_TYPE_CELLDB_INFO, GNSS_AIDING_TYPE_ALL})
132     @Retention(RetentionPolicy.SOURCE)
133     public @interface GnssAidingTypeFlags {}
134 
135     // IMPORTANT - must match OEM definitions, this isn't part of a hal for some reason
136     public static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
137     public static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
138     public static final int AGPS_REF_LOCATION_TYPE_LTE_CELLID = 4;
139     public static final int AGPS_REF_LOCATION_TYPE_NR_CELLID = 8;
140 
141     @IntDef(prefix = "AGPS_REF_LOCATION_TYPE_", value = {AGPS_REF_LOCATION_TYPE_GSM_CELLID,
142             AGPS_REF_LOCATION_TYPE_UMTS_CELLID, AGPS_REF_LOCATION_TYPE_LTE_CELLID,
143             AGPS_REF_LOCATION_TYPE_NR_CELLID})
144     @Retention(RetentionPolicy.SOURCE)
145     public @interface AgpsReferenceLocationType {}
146 
147     // IMPORTANT - must match OEM definitions, this isn't part of a hal for some reason
148     public static final int AGPS_SETID_TYPE_NONE = 0;
149     public static final int AGPS_SETID_TYPE_IMSI = 1;
150     public static final int AGPS_SETID_TYPE_MSISDN = 2;
151 
152     private static final int POWER_STATS_REQUEST_TIMEOUT_MILLIS = 100;
153 
154     @IntDef(prefix = "AGPS_SETID_TYPE_", value = {AGPS_SETID_TYPE_NONE, AGPS_SETID_TYPE_IMSI,
155             AGPS_SETID_TYPE_MSISDN})
156     @Retention(RetentionPolicy.SOURCE)
157     public @interface AgpsSetIdType {}
158 
159     /** Callbacks relevant to the entire HAL. */
160     public interface BaseCallbacks {
onHalStarted()161         default void onHalStarted() {}
onHalRestarted()162         void onHalRestarted();
onCapabilitiesChanged(GnssCapabilities oldCapabilities, GnssCapabilities newCapabilities)163         default void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
164                 GnssCapabilities newCapabilities) {}
165     }
166 
167     /** Callbacks for status events. */
168     public interface StatusCallbacks {
169 
170         // IMPORTANT - must match GnssStatusValue enum in IGnssCallback.hal
171         int GNSS_STATUS_NONE = 0;
172         int GNSS_STATUS_SESSION_BEGIN = 1;
173         int GNSS_STATUS_SESSION_END = 2;
174         int GNSS_STATUS_ENGINE_ON = 3;
175         int GNSS_STATUS_ENGINE_OFF = 4;
176 
177         @IntDef(prefix = "GNSS_STATUS_", value = {GNSS_STATUS_NONE, GNSS_STATUS_SESSION_BEGIN,
178                 GNSS_STATUS_SESSION_END, GNSS_STATUS_ENGINE_ON, GNSS_STATUS_ENGINE_OFF})
179         @Retention(RetentionPolicy.SOURCE)
180         @interface GnssStatusValue {}
181 
onReportStatus(@nssStatusValue int status)182         void onReportStatus(@GnssStatusValue int status);
onReportFirstFix(int ttff)183         void onReportFirstFix(int ttff);
184     }
185 
186     /** Callbacks for SV status events. */
187     public interface SvStatusCallbacks {
onReportSvStatus(GnssStatus gnssStatus)188         void onReportSvStatus(GnssStatus gnssStatus);
189     }
190 
191     /** Callbacks for NMEA events. */
192     public interface NmeaCallbacks {
onReportNmea(long timestamp)193         void onReportNmea(long timestamp);
194     }
195 
196     /** Callbacks for location events. */
197     public interface LocationCallbacks {
onReportLocation(boolean hasLatLong, Location location)198         void onReportLocation(boolean hasLatLong, Location location);
onReportLocations(Location[] locations)199         void onReportLocations(Location[] locations);
200     }
201 
202     /** Callbacks for measurement events. */
203     public interface MeasurementCallbacks {
onReportMeasurements(GnssMeasurementsEvent event)204         void onReportMeasurements(GnssMeasurementsEvent event);
205     }
206 
207     /** Callbacks for antenna info events. */
208     public interface AntennaInfoCallbacks {
onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos)209         void onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos);
210     }
211 
212     /** Callbacks for navigation message events. */
213     public interface NavigationMessageCallbacks {
onReportNavigationMessage(GnssNavigationMessage event)214         void onReportNavigationMessage(GnssNavigationMessage event);
215     }
216 
217     /** Callbacks for geofence events. */
218     public interface GeofenceCallbacks {
219 
220         // IMPORTANT - must match GeofenceTransition enum in IGnssGeofenceCallback.hal
221         int GEOFENCE_TRANSITION_ENTERED = 1 << 0L;
222         int GEOFENCE_TRANSITION_EXITED = 1 << 1L;
223         int GEOFENCE_TRANSITION_UNCERTAIN = 1 << 2L;
224 
225         @IntDef(prefix = "GEOFENCE_TRANSITION_", value = {GEOFENCE_TRANSITION_ENTERED,
226                 GEOFENCE_TRANSITION_EXITED, GEOFENCE_TRANSITION_UNCERTAIN})
227         @Retention(RetentionPolicy.SOURCE)
228         @interface GeofenceTransition {}
229 
230         // IMPORTANT - must match GeofenceAvailability enum in IGnssGeofenceCallback.hal
231         int GEOFENCE_AVAILABILITY_UNAVAILABLE = 1 << 0L;
232         int GEOFENCE_AVAILABILITY_AVAILABLE = 1 << 1L;
233 
234         @IntDef(prefix = "GEOFENCE_AVAILABILITY_", value = {GEOFENCE_AVAILABILITY_UNAVAILABLE,
235                 GEOFENCE_AVAILABILITY_AVAILABLE})
236         @Retention(RetentionPolicy.SOURCE)
237         @interface GeofenceAvailability {}
238 
239         // IMPORTANT - must match GeofenceStatus enum in IGnssGeofenceCallback.hal
240         int GEOFENCE_STATUS_OPERATION_SUCCESS = 0;
241         int GEOFENCE_STATUS_ERROR_TOO_MANY_GEOFENCES = 100;
242         int GEOFENCE_STATUS_ERROR_ID_EXISTS = -101;
243         int GEOFENCE_STATUS_ERROR_ID_UNKNOWN = -102;
244         int GEOFENCE_STATUS_ERROR_INVALID_TRANSITION = -103;
245         int GEOFENCE_STATUS_ERROR_GENERIC = -149;
246 
247         @IntDef(prefix = "GEOFENCE_STATUS_", value = {GEOFENCE_STATUS_OPERATION_SUCCESS,
248                 GEOFENCE_STATUS_ERROR_TOO_MANY_GEOFENCES, GEOFENCE_STATUS_ERROR_ID_EXISTS,
249                 GEOFENCE_STATUS_ERROR_ID_UNKNOWN, GEOFENCE_STATUS_ERROR_INVALID_TRANSITION,
250                 GEOFENCE_STATUS_ERROR_GENERIC})
251         @Retention(RetentionPolicy.SOURCE)
252         @interface GeofenceStatus {}
253 
onReportGeofenceTransition(int geofenceId, Location location, @GeofenceTransition int transition, long timestamp)254         void onReportGeofenceTransition(int geofenceId, Location location,
255                 @GeofenceTransition int transition, long timestamp);
onReportGeofenceStatus(@eofenceAvailability int availabilityStatus, Location location)256         void onReportGeofenceStatus(@GeofenceAvailability int availabilityStatus,
257                 Location location);
onReportGeofenceAddStatus(int geofenceId, @GeofenceStatus int status)258         void onReportGeofenceAddStatus(int geofenceId, @GeofenceStatus int status);
onReportGeofenceRemoveStatus(int geofenceId, @GeofenceStatus int status)259         void onReportGeofenceRemoveStatus(int geofenceId, @GeofenceStatus int status);
onReportGeofencePauseStatus(int geofenceId, @GeofenceStatus int status)260         void onReportGeofencePauseStatus(int geofenceId, @GeofenceStatus int status);
onReportGeofenceResumeStatus(int geofenceId, @GeofenceStatus int status)261         void onReportGeofenceResumeStatus(int geofenceId, @GeofenceStatus int status);
262     }
263 
264     /** Callbacks for the HAL requesting time. */
265     public interface TimeCallbacks {
onRequestUtcTime()266         void onRequestUtcTime();
267     }
268 
269     /** Callbacks for the HAL requesting locations. */
270     public interface LocationRequestCallbacks {
onRequestLocation(boolean independentFromGnss, boolean isUserEmergency)271         void onRequestLocation(boolean independentFromGnss, boolean isUserEmergency);
onRequestRefLocation()272         void onRequestRefLocation();
273     }
274 
275     /** Callbacks for HAL requesting PSDS download. */
276     public interface PsdsCallbacks {
onRequestPsdsDownload(int psdsType)277         void onRequestPsdsDownload(int psdsType);
278     }
279 
280     /** Callbacks for HAL requesting GNSS assistance. */
281     public interface GnssAssistanceCallbacks {
282         /** On request GnssAssistance injection. */
onRequestGnssAssistanceInject()283         void onRequestGnssAssistanceInject();
284     }
285 
286     /** Callbacks for AGPS functionality. */
287     public interface AGpsCallbacks {
288 
289         // IMPORTANT - must match OEM definitions, this isn't part of a hal for some reason
290         int AGPS_REQUEST_SETID_IMSI = 1 << 0L;
291         int AGPS_REQUEST_SETID_MSISDN = 1 << 1L;
292 
293         @IntDef(flag = true, prefix = "AGPS_REQUEST_SETID_", value = {AGPS_REQUEST_SETID_IMSI,
294                 AGPS_REQUEST_SETID_MSISDN})
295         @Retention(RetentionPolicy.SOURCE)
296         @interface AgpsSetIdFlags {}
297 
onReportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr)298         void onReportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr);
onRequestSetID(@gpsSetIdFlags int flags)299         void onRequestSetID(@AgpsSetIdFlags int flags);
300     }
301 
302     /** Callbacks for notifications. */
303     public interface NotificationCallbacks {
onReportNfwNotification(String proxyAppPackageName, byte protocolStack, String otherProtocolStackName, byte requestor, String requestorId, byte responseType, boolean inEmergencyMode, boolean isCachedLocation)304         void onReportNfwNotification(String proxyAppPackageName, byte protocolStack,
305                 String otherProtocolStackName, byte requestor, String requestorId,
306                 byte responseType, boolean inEmergencyMode, boolean isCachedLocation);
307     }
308 
309     /** Callback for reporting {@link GnssPowerStats} */
310     public interface PowerStatsCallback {
311         /**
312          * Called when power stats are reported.
313          * @param powerStats non-null value when power stats are available, {@code null} otherwise.
314          */
onReportPowerStats(@ullable GnssPowerStats powerStats)315         void onReportPowerStats(@Nullable GnssPowerStats powerStats);
316     }
317 
318     // set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
319     // stops output right at 600m/s, depriving this of the information of a device that reaches
320     // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
321     private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0f;
322 
323     /**
324      * Indicates that this method is a native entry point. Useful purely for IDEs which can
325      * understand entry points, and thus eliminate incorrect warnings about methods not used.
326      */
327     @Target(ElementType.METHOD)
328     @Retention(RetentionPolicy.SOURCE)
329     private @interface NativeEntryPoint {}
330 
331     @GuardedBy("GnssNative.class")
332     private static GnssHal sGnssHal;
333 
334     @GuardedBy("GnssNative.class")
335     private static boolean sGnssHalInitialized;
336 
337     @GuardedBy("GnssNative.class")
338     private static GnssNative sInstance;
339 
340     private final Handler mHandler;
341 
342     /**
343      * Sets GnssHal instance to use for testing.
344      */
345     @VisibleForTesting
setGnssHalForTest(GnssHal gnssHal)346     public static synchronized void setGnssHalForTest(GnssHal gnssHal) {
347         sGnssHal = Objects.requireNonNull(gnssHal);
348         sGnssHalInitialized = false;
349         sInstance = null;
350     }
351 
initializeHal()352     private static synchronized void initializeHal() {
353         if (!sGnssHalInitialized) {
354             if (sGnssHal == null) {
355                 sGnssHal = new GnssHal();
356             }
357             sGnssHal.classInitOnce();
358             sGnssHalInitialized = true;
359         }
360     }
361 
362     /**
363      * Returns true if GNSS is supported on this device. If true, then
364      * {@link #create(Injector, GnssConfiguration)} may be invoked.
365      */
isSupported()366     public static synchronized boolean isSupported() {
367         initializeHal();
368         return sGnssHal.isSupported();
369     }
370 
371     /**
372      * Creates a new instance of GnssNative. Should only be invoked if {@link #isSupported()} is
373      * true. May only be invoked once.
374      */
create(Injector injector, GnssConfiguration configuration)375     public static synchronized GnssNative create(Injector injector,
376             GnssConfiguration configuration) {
377         // side effect - ensures initialization
378         Preconditions.checkState(isSupported());
379         Preconditions.checkState(sInstance == null);
380         return (sInstance = new GnssNative(sGnssHal, injector, configuration));
381     }
382 
383     private final GnssHal mGnssHal;
384     private final EmergencyHelper mEmergencyHelper;
385     private final GnssConfiguration mConfiguration;
386 
387     // these callbacks may have multiple implementations
388     private BaseCallbacks[] mBaseCallbacks = new BaseCallbacks[0];
389     private StatusCallbacks[] mStatusCallbacks = new StatusCallbacks[0];
390     private SvStatusCallbacks[] mSvStatusCallbacks = new SvStatusCallbacks[0];
391     private NmeaCallbacks[] mNmeaCallbacks = new NmeaCallbacks[0];
392     private LocationCallbacks[] mLocationCallbacks = new LocationCallbacks[0];
393     private MeasurementCallbacks[] mMeasurementCallbacks = new MeasurementCallbacks[0];
394     private AntennaInfoCallbacks[] mAntennaInfoCallbacks = new AntennaInfoCallbacks[0];
395     private NavigationMessageCallbacks[] mNavigationMessageCallbacks =
396             new NavigationMessageCallbacks[0];
397 
398     private @Nullable GnssPowerStats mLastKnownPowerStats = null;
399     private final Object mPowerStatsLock = new Object();
400     private final Runnable mPowerStatsTimeoutCallback = () -> {
401         Log.d(TAG, "Request for power stats timed out");
402         reportGnssPowerStats(null);
403     };
404     private final List<PowerStatsCallback> mPendingPowerStatsCallbacks = new ArrayList<>();
405 
406     // these callbacks may only have a single implementation
407     private GeofenceCallbacks mGeofenceCallbacks;
408     private TimeCallbacks mTimeCallbacks;
409     private LocationRequestCallbacks mLocationRequestCallbacks;
410     private PsdsCallbacks mPsdsCallbacks;
411     private @Nullable GnssAssistanceCallbacks mGnssAssistanceCallbacks;
412     private AGpsCallbacks mAGpsCallbacks;
413     private NotificationCallbacks mNotificationCallbacks;
414 
415     private boolean mRegistered;
416 
417     private volatile boolean mItarSpeedLimitExceeded;
418 
419     private GnssCapabilities mCapabilities = new GnssCapabilities.Builder().build();
420     private @GnssCapabilities.TopHalCapabilityFlags int mTopFlags;
421     private int mHardwareYear = 0;
422     private @Nullable String mHardwareModelName = null;
423     private long mStartRealtimeMs = 0;
424     private boolean mHasFirstFix = false;
425 
GnssNative(GnssHal gnssHal, Injector injector, GnssConfiguration configuration)426     private GnssNative(GnssHal gnssHal, Injector injector, GnssConfiguration configuration) {
427         mGnssHal = Objects.requireNonNull(gnssHal);
428         mEmergencyHelper = injector.getEmergencyHelper();
429         mConfiguration = configuration;
430         mHandler = FgThread.getHandler();
431     }
432 
addBaseCallbacks(BaseCallbacks callbacks)433     public void addBaseCallbacks(BaseCallbacks callbacks) {
434         Preconditions.checkState(!mRegistered);
435         mBaseCallbacks = ArrayUtils.appendElement(BaseCallbacks.class, mBaseCallbacks, callbacks);
436     }
437 
addStatusCallbacks(StatusCallbacks callbacks)438     public void addStatusCallbacks(StatusCallbacks callbacks) {
439         Preconditions.checkState(!mRegistered);
440         mStatusCallbacks = ArrayUtils.appendElement(StatusCallbacks.class, mStatusCallbacks,
441                 callbacks);
442     }
443 
addSvStatusCallbacks(SvStatusCallbacks callbacks)444     public void addSvStatusCallbacks(SvStatusCallbacks callbacks) {
445         Preconditions.checkState(!mRegistered);
446         mSvStatusCallbacks = ArrayUtils.appendElement(SvStatusCallbacks.class, mSvStatusCallbacks,
447                 callbacks);
448     }
449 
addNmeaCallbacks(NmeaCallbacks callbacks)450     public void addNmeaCallbacks(NmeaCallbacks callbacks) {
451         Preconditions.checkState(!mRegistered);
452         mNmeaCallbacks = ArrayUtils.appendElement(NmeaCallbacks.class, mNmeaCallbacks,
453                 callbacks);
454     }
455 
addLocationCallbacks(LocationCallbacks callbacks)456     public void addLocationCallbacks(LocationCallbacks callbacks) {
457         Preconditions.checkState(!mRegistered);
458         mLocationCallbacks = ArrayUtils.appendElement(LocationCallbacks.class, mLocationCallbacks,
459                 callbacks);
460     }
461 
addMeasurementCallbacks(MeasurementCallbacks callbacks)462     public void addMeasurementCallbacks(MeasurementCallbacks callbacks) {
463         Preconditions.checkState(!mRegistered);
464         mMeasurementCallbacks = ArrayUtils.appendElement(MeasurementCallbacks.class,
465                 mMeasurementCallbacks, callbacks);
466     }
467 
addAntennaInfoCallbacks(AntennaInfoCallbacks callbacks)468     public void addAntennaInfoCallbacks(AntennaInfoCallbacks callbacks) {
469         Preconditions.checkState(!mRegistered);
470         mAntennaInfoCallbacks = ArrayUtils.appendElement(AntennaInfoCallbacks.class,
471                 mAntennaInfoCallbacks, callbacks);
472     }
473 
addNavigationMessageCallbacks(NavigationMessageCallbacks callbacks)474     public void addNavigationMessageCallbacks(NavigationMessageCallbacks callbacks) {
475         Preconditions.checkState(!mRegistered);
476         mNavigationMessageCallbacks = ArrayUtils.appendElement(NavigationMessageCallbacks.class,
477                 mNavigationMessageCallbacks, callbacks);
478     }
479 
setGeofenceCallbacks(GeofenceCallbacks callbacks)480     public void setGeofenceCallbacks(GeofenceCallbacks callbacks) {
481         Preconditions.checkState(!mRegistered);
482         Preconditions.checkState(mGeofenceCallbacks == null);
483         mGeofenceCallbacks = Objects.requireNonNull(callbacks);
484     }
485 
setTimeCallbacks(TimeCallbacks callbacks)486     public void setTimeCallbacks(TimeCallbacks callbacks) {
487         Preconditions.checkState(!mRegistered);
488         Preconditions.checkState(mTimeCallbacks == null);
489         mTimeCallbacks = Objects.requireNonNull(callbacks);
490     }
491 
setLocationRequestCallbacks(LocationRequestCallbacks callbacks)492     public void setLocationRequestCallbacks(LocationRequestCallbacks callbacks) {
493         Preconditions.checkState(!mRegistered);
494         Preconditions.checkState(mLocationRequestCallbacks == null);
495         mLocationRequestCallbacks = Objects.requireNonNull(callbacks);
496     }
497 
setPsdsCallbacks(PsdsCallbacks callbacks)498     public void setPsdsCallbacks(PsdsCallbacks callbacks) {
499         Preconditions.checkState(!mRegistered);
500         Preconditions.checkState(mPsdsCallbacks == null);
501         mPsdsCallbacks = Objects.requireNonNull(callbacks);
502     }
503 
setAGpsCallbacks(AGpsCallbacks callbacks)504     public void setAGpsCallbacks(AGpsCallbacks callbacks) {
505         Preconditions.checkState(!mRegistered);
506         Preconditions.checkState(mAGpsCallbacks == null);
507         mAGpsCallbacks = Objects.requireNonNull(callbacks);
508     }
509 
setNotificationCallbacks(NotificationCallbacks callbacks)510     public void setNotificationCallbacks(NotificationCallbacks callbacks) {
511         Preconditions.checkState(!mRegistered);
512         Preconditions.checkState(mNotificationCallbacks == null);
513         mNotificationCallbacks = Objects.requireNonNull(callbacks);
514     }
515 
516     /** Sets GnssAssistanceCallbacks. */
setGnssAssistanceCallbacks(GnssAssistanceCallbacks callbacks)517     public void setGnssAssistanceCallbacks(GnssAssistanceCallbacks callbacks) {
518         if (!Flags.gnssAssistanceInterfaceJni()) {
519             return;
520         }
521         Preconditions.checkState(mGnssAssistanceCallbacks == null);
522         mGnssAssistanceCallbacks = Objects.requireNonNull(callbacks);
523     }
524 
525     /**
526      * Registers with the HAL and allows callbacks to begin. Once registered with the native HAL,
527      * no more callbacks can be added or set. Must only be called once.
528      */
register()529     public void register() {
530         Preconditions.checkState(!mRegistered);
531         mRegistered = true;
532 
533         initializeGnss(false);
534         Log.i(TAG, "gnss hal started");
535 
536         for (int i = 0; i < mBaseCallbacks.length; i++) {
537             mBaseCallbacks[i].onHalStarted();
538         }
539     }
540 
initializeGnss(boolean restart)541     private void initializeGnss(boolean restart) {
542         Preconditions.checkState(mRegistered);
543         mTopFlags = 0;
544         mGnssHal.initOnce(GnssNative.this, restart);
545 
546         // gnss chipset appears to require an init/cleanup cycle on startup in order to properly
547         // initialize - undocumented and no idea why this is the case
548         if (mGnssHal.init()) {
549             mGnssHal.cleanup();
550             Log.i(TAG, "gnss hal initialized");
551         } else {
552             Log.e(TAG, "gnss hal initialization failed");
553         }
554     }
555 
getConfiguration()556     public GnssConfiguration getConfiguration() {
557         return mConfiguration;
558     }
559 
560     /**
561      * Starts up GNSS HAL, and has undocumented side effect of informing HAL that location is
562      * allowed by settings.
563      */
init()564     public boolean init() {
565         Preconditions.checkState(mRegistered);
566         return mGnssHal.init();
567     }
568 
569     /**
570      * Shuts down GNSS HAL, and has undocumented side effect of informing HAL that location is not
571      * allowed by settings.
572      */
cleanup()573     public void cleanup() {
574         Preconditions.checkState(mRegistered);
575         mGnssHal.cleanup();
576     }
577 
578     /**
579      * Returns the latest power stats from the GNSS HAL.
580      */
getLastKnownPowerStats()581     public @Nullable GnssPowerStats getLastKnownPowerStats() {
582         return mLastKnownPowerStats;
583     }
584 
585     /**
586      * Returns current capabilities of the GNSS HAL.
587      */
getCapabilities()588     public GnssCapabilities getCapabilities() {
589         return mCapabilities;
590     }
591 
592     /**
593      * Returns hardware year of GNSS chipset.
594      */
getHardwareYear()595     public int getHardwareYear() {
596         return mHardwareYear;
597     }
598 
599     /**
600      * Returns hardware model name of GNSS chipset.
601      */
getHardwareModelName()602     public @Nullable String getHardwareModelName() {
603         return mHardwareModelName;
604     }
605 
606     /**
607      * Returns true if the ITAR speed limit is currently being exceeded, and thus location
608      * information may be blocked.
609      */
isItarSpeedLimitExceeded()610     public boolean isItarSpeedLimitExceeded() {
611         return mItarSpeedLimitExceeded;
612     }
613 
614     /**
615      * Starts the GNSS HAL.
616      */
start()617     public boolean start() {
618         Preconditions.checkState(mRegistered);
619         mStartRealtimeMs = SystemClock.elapsedRealtime();
620         mHasFirstFix = false;
621         return mGnssHal.start();
622     }
623 
624     /**
625      * Stops the GNSS HAL.
626      */
stop()627     public boolean stop() {
628         Preconditions.checkState(mRegistered);
629         return mGnssHal.stop();
630     }
631 
632     /**
633      * Sets the position mode.
634      */
setPositionMode(@nssPositionMode int mode, @GnssPositionRecurrence int recurrence, int minInterval, int preferredAccuracy, int preferredTime, boolean lowPowerMode)635     public boolean setPositionMode(@GnssPositionMode int mode,
636             @GnssPositionRecurrence int recurrence, int minInterval, int preferredAccuracy,
637             int preferredTime, boolean lowPowerMode) {
638         Preconditions.checkState(mRegistered);
639         return mGnssHal.setPositionMode(mode, recurrence, minInterval, preferredAccuracy,
640                 preferredTime, lowPowerMode);
641     }
642 
643     /**
644      * Returns a debug string from the GNSS HAL.
645      */
getInternalState()646     public String getInternalState() {
647         Preconditions.checkState(mRegistered);
648         return mGnssHal.getInternalState();
649     }
650 
651     /**
652      * Deletes any aiding data specified by the given flags.
653      */
deleteAidingData(@nssAidingTypeFlags int flags)654     public void deleteAidingData(@GnssAidingTypeFlags int flags) {
655         Preconditions.checkState(mRegistered);
656         mGnssHal.deleteAidingData(flags);
657     }
658 
659     /**
660      * Reads an NMEA message into the given buffer, returning the number of bytes loaded into the
661      * buffer.
662      */
readNmea(byte[] buffer, int bufferSize)663     public int readNmea(byte[] buffer, int bufferSize) {
664         Preconditions.checkState(mRegistered);
665         return mGnssHal.readNmea(buffer, bufferSize);
666     }
667 
668     /**
669      * Injects location information into the GNSS HAL.
670      */
injectLocation(Location location)671     public void injectLocation(Location location) {
672         Preconditions.checkState(mRegistered);
673         if (location.hasAccuracy()) {
674 
675             int gnssLocationFlags = GNSS_LOCATION_HAS_LAT_LONG
676                     | (location.hasAltitude() ? GNSS_LOCATION_HAS_ALTITUDE : 0)
677                     | (location.hasSpeed() ? GNSS_LOCATION_HAS_SPEED : 0)
678                     | (location.hasBearing() ? GNSS_LOCATION_HAS_BEARING : 0)
679                     | (location.hasAccuracy() ? GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY : 0)
680                     | (location.hasVerticalAccuracy() ? GNSS_LOCATION_HAS_VERTICAL_ACCURACY : 0)
681                     | (location.hasSpeedAccuracy() ? GNSS_LOCATION_HAS_SPEED_ACCURACY : 0)
682                     | (location.hasBearingAccuracy() ? GNSS_LOCATION_HAS_BEARING_ACCURACY : 0);
683 
684             double latitudeDegrees = location.getLatitude();
685             double longitudeDegrees = location.getLongitude();
686             double altitudeMeters = location.getAltitude();
687             float speedMetersPerSec = location.getSpeed();
688             float bearingDegrees = location.getBearing();
689             float horizontalAccuracyMeters = location.getAccuracy();
690             float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
691             float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
692             float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
693             long timestamp = location.getTime();
694 
695             int elapsedRealtimeFlags = GNSS_REALTIME_HAS_TIMESTAMP_NS
696                     | (location.hasElapsedRealtimeUncertaintyNanos()
697                     ? GNSS_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
698             long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
699             double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
700 
701             mGnssHal.injectLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
702                     altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
703                     verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
704                     timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos,
705                     elapsedRealtimeUncertaintyNanos);
706         }
707     }
708 
709     /**
710      * Injects a location into the GNSS HAL in response to a HAL request for location.
711      */
injectBestLocation(Location location)712     public void injectBestLocation(Location location) {
713         Preconditions.checkState(mRegistered);
714 
715         int gnssLocationFlags = GNSS_LOCATION_HAS_LAT_LONG
716                 | (location.hasAltitude() ? GNSS_LOCATION_HAS_ALTITUDE : 0)
717                 | (location.hasSpeed() ? GNSS_LOCATION_HAS_SPEED : 0)
718                 | (location.hasBearing() ? GNSS_LOCATION_HAS_BEARING : 0)
719                 | (location.hasAccuracy() ? GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY : 0)
720                 | (location.hasVerticalAccuracy() ? GNSS_LOCATION_HAS_VERTICAL_ACCURACY : 0)
721                 | (location.hasSpeedAccuracy() ? GNSS_LOCATION_HAS_SPEED_ACCURACY : 0)
722                 | (location.hasBearingAccuracy() ? GNSS_LOCATION_HAS_BEARING_ACCURACY : 0);
723 
724         double latitudeDegrees = location.getLatitude();
725         double longitudeDegrees = location.getLongitude();
726         double altitudeMeters = location.getAltitude();
727         float speedMetersPerSec = location.getSpeed();
728         float bearingDegrees = location.getBearing();
729         float horizontalAccuracyMeters = location.getAccuracy();
730         float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
731         float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
732         float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
733         long timestamp = location.getTime();
734 
735         int elapsedRealtimeFlags = GNSS_REALTIME_HAS_TIMESTAMP_NS
736                 | (location.hasElapsedRealtimeUncertaintyNanos()
737                 ? GNSS_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
738         long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
739         double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
740 
741         mGnssHal.injectBestLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
742                 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
743                 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
744                 timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos,
745                 elapsedRealtimeUncertaintyNanos);
746     }
747 
748     /**
749      * Injects time information into the GNSS HAL.
750      */
injectTime(long time, long timeReference, int uncertainty)751     public void injectTime(long time, long timeReference, int uncertainty) {
752         Preconditions.checkState(mRegistered);
753         mGnssHal.injectTime(time, timeReference, uncertainty);
754     }
755 
756     /**
757      * Returns true if navigation message collection is supported.
758      */
isNavigationMessageCollectionSupported()759     public boolean isNavigationMessageCollectionSupported() {
760         Preconditions.checkState(mRegistered);
761         return mGnssHal.isNavigationMessageCollectionSupported();
762     }
763 
764     /**
765      * Starts navigation message collection.
766      */
startNavigationMessageCollection()767     public boolean startNavigationMessageCollection() {
768         Preconditions.checkState(mRegistered);
769         return mGnssHal.startNavigationMessageCollection();
770     }
771 
772     /**
773      * Stops navigation message collection.
774      */
stopNavigationMessageCollection()775     public boolean stopNavigationMessageCollection() {
776         Preconditions.checkState(mRegistered);
777         return mGnssHal.stopNavigationMessageCollection();
778     }
779 
780     /**
781      * Returns true if antenna info is supported.
782      */
isAntennaInfoSupported()783     public boolean isAntennaInfoSupported() {
784         Preconditions.checkState(mRegistered);
785         return mGnssHal.isAntennaInfoSupported();
786     }
787 
788     /**
789      * Starts antenna info listening.
790      */
startAntennaInfoListening()791     public boolean startAntennaInfoListening() {
792         Preconditions.checkState(mRegistered);
793         return mGnssHal.startAntennaInfoListening();
794     }
795 
796     /**
797      * Stops antenna info listening.
798      */
stopAntennaInfoListening()799     public boolean stopAntennaInfoListening() {
800         Preconditions.checkState(mRegistered);
801         return mGnssHal.stopAntennaInfoListening();
802     }
803 
804     /**
805      * Returns true if measurement collection is supported.
806      */
isMeasurementSupported()807     public boolean isMeasurementSupported() {
808         Preconditions.checkState(mRegistered);
809         return mGnssHal.isMeasurementSupported();
810     }
811 
812     /**
813      * Starts measurement collection.
814      */
startMeasurementCollection(boolean enableFullTracking, boolean enableCorrVecOutputs, int intervalMillis)815     public boolean startMeasurementCollection(boolean enableFullTracking,
816             boolean enableCorrVecOutputs, int intervalMillis) {
817         Preconditions.checkState(mRegistered);
818         return mGnssHal.startMeasurementCollection(enableFullTracking, enableCorrVecOutputs,
819                 intervalMillis);
820     }
821 
822     /**
823      * Stops measurement collection.
824      */
stopMeasurementCollection()825     public boolean stopMeasurementCollection() {
826         Preconditions.checkState(mRegistered);
827         return mGnssHal.stopMeasurementCollection();
828     }
829 
830     /**
831      * Starts sv status collection.
832      */
startSvStatusCollection()833     public boolean startSvStatusCollection() {
834         Preconditions.checkState(mRegistered);
835         return mGnssHal.startSvStatusCollection();
836     }
837 
838     /**
839      * Stops sv status collection.
840      */
stopSvStatusCollection()841     public boolean stopSvStatusCollection() {
842         Preconditions.checkState(mRegistered);
843         return mGnssHal.stopSvStatusCollection();
844     }
845 
846     /**
847      * Starts NMEA message collection.
848      */
startNmeaMessageCollection()849     public boolean startNmeaMessageCollection() {
850         Preconditions.checkState(mRegistered);
851         return mGnssHal.startNmeaMessageCollection();
852     }
853 
854     /**
855      * Stops NMEA message collection.
856      */
stopNmeaMessageCollection()857     public boolean stopNmeaMessageCollection() {
858         Preconditions.checkState(mRegistered);
859         return mGnssHal.stopNmeaMessageCollection();
860     }
861 
862     /**
863      * Returns true if measurement corrections are supported.
864      */
isMeasurementCorrectionsSupported()865     public boolean isMeasurementCorrectionsSupported() {
866         Preconditions.checkState(mRegistered);
867         return mGnssHal.isMeasurementCorrectionsSupported();
868     }
869 
870     /**
871      * Injects measurement corrections into the GNSS HAL.
872      */
injectMeasurementCorrections(GnssMeasurementCorrections corrections)873     public boolean injectMeasurementCorrections(GnssMeasurementCorrections corrections) {
874         Preconditions.checkState(mRegistered);
875         return mGnssHal.injectMeasurementCorrections(corrections);
876     }
877 
878     /**
879      * Initialize batching.
880      */
initBatching()881     public boolean initBatching() {
882         Preconditions.checkState(mRegistered);
883         return mGnssHal.initBatching();
884     }
885 
886     /**
887      * Cleanup batching.
888      */
cleanupBatching()889     public void cleanupBatching() {
890         Preconditions.checkState(mRegistered);
891         mGnssHal.cleanupBatching();
892     }
893 
894     /**
895      * Start batching.
896      */
startBatch(long periodNanos, float minUpdateDistanceMeters, boolean wakeOnFifoFull)897     public boolean startBatch(long periodNanos, float minUpdateDistanceMeters,
898             boolean wakeOnFifoFull) {
899         Preconditions.checkState(mRegistered);
900         return mGnssHal.startBatch(periodNanos, minUpdateDistanceMeters, wakeOnFifoFull);
901     }
902 
903     /**
904      * Flush batching.
905      */
flushBatch()906     public void flushBatch() {
907         Preconditions.checkState(mRegistered);
908         mGnssHal.flushBatch();
909     }
910 
911     /**
912      * Stop batching.
913      */
stopBatch()914     public void stopBatch() {
915         Preconditions.checkState(mRegistered);
916         mGnssHal.stopBatch();
917     }
918 
919     /**
920      * Get current batching size.
921      */
getBatchSize()922     public int getBatchSize() {
923         Preconditions.checkState(mRegistered);
924         return mGnssHal.getBatchSize();
925     }
926 
927     /**
928      * Check if GNSS geofencing is supported.
929      */
isGeofencingSupported()930     public boolean isGeofencingSupported() {
931         Preconditions.checkState(mRegistered);
932         return mGnssHal.isGeofencingSupported();
933     }
934 
935     /**
936      * Add geofence.
937      */
addGeofence(int geofenceId, double latitude, double longitude, double radius, int lastTransition, int monitorTransitions, int notificationResponsiveness, int unknownTimer)938     public boolean addGeofence(int geofenceId, double latitude, double longitude, double radius,
939             int lastTransition, int monitorTransitions, int notificationResponsiveness,
940             int unknownTimer) {
941         Preconditions.checkState(mRegistered);
942         return mGnssHal.addGeofence(geofenceId, latitude, longitude, radius, lastTransition,
943                 monitorTransitions, notificationResponsiveness, unknownTimer);
944     }
945 
946     /**
947      * Resume geofence.
948      */
resumeGeofence(int geofenceId, int monitorTransitions)949     public boolean resumeGeofence(int geofenceId, int monitorTransitions) {
950         Preconditions.checkState(mRegistered);
951         return mGnssHal.resumeGeofence(geofenceId, monitorTransitions);
952     }
953 
954     /**
955      * Pause geofence.
956      */
pauseGeofence(int geofenceId)957     public boolean pauseGeofence(int geofenceId) {
958         Preconditions.checkState(mRegistered);
959         return mGnssHal.pauseGeofence(geofenceId);
960     }
961 
962     /**
963      * Remove geofence.
964      */
removeGeofence(int geofenceId)965     public boolean removeGeofence(int geofenceId) {
966         Preconditions.checkState(mRegistered);
967         return mGnssHal.removeGeofence(geofenceId);
968     }
969 
970     /**
971      * Returns true if visibility control is supported.
972      */
isGnssVisibilityControlSupported()973     public boolean isGnssVisibilityControlSupported() {
974         Preconditions.checkState(mRegistered);
975         return mGnssHal.isGnssVisibilityControlSupported();
976     }
977 
978     /**
979      * Request an eventual update of GNSS power statistics.
980      *
981      * @param executor Executor that will run {@code callback}
982      * @param callback Called with non-null power stats if they were obtained in time, called with
983      *                 {@code null} if stats could not be obtained in time.
984      */
requestPowerStats( @onNull @allbackExecutor Executor executor, @NonNull PowerStatsCallback callback)985     public void requestPowerStats(
986             @NonNull @CallbackExecutor Executor executor,
987             @NonNull PowerStatsCallback callback) {
988         Preconditions.checkState(mRegistered);
989         synchronized (mPowerStatsLock) {
990             mPendingPowerStatsCallbacks.add(powerStats -> {
991                 Binder.withCleanCallingIdentity(
992                         () -> executor.execute(() -> callback.onReportPowerStats(powerStats)));
993             });
994             if (mPendingPowerStatsCallbacks.size() == 1) {
995                 mGnssHal.requestPowerStats();
996                 mHandler.postDelayed(mPowerStatsTimeoutCallback,
997                         POWER_STATS_REQUEST_TIMEOUT_MILLIS);
998             }
999         }
1000     }
1001 
1002     /**
1003      * Request GNSS power statistics and blocks for a short time waiting for the result.
1004      *
1005      * @return non-null power stats, or {@code null} if stats could not be obtained in time.
1006      */
requestPowerStatsBlocking()1007     public @Nullable GnssPowerStats requestPowerStatsBlocking() {
1008         AtomicReference<GnssPowerStats> statsWrapper = new AtomicReference<>();
1009         CountDownLatch latch = new CountDownLatch(1);
1010         requestPowerStats(Runnable::run, powerStats -> {
1011             statsWrapper.set(powerStats);
1012             latch.countDown();
1013         });
1014 
1015         try {
1016             latch.await(POWER_STATS_REQUEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
1017         } catch (InterruptedException e) {
1018             Log.d(TAG, "Interrupted while waiting for power stats");
1019             Thread.currentThread().interrupt();
1020         }
1021 
1022         return statsWrapper.get();
1023     }
1024 
1025     /**
1026      * Sets AGPS server information.
1027      */
setAgpsServer(int type, String hostname, int port)1028     public void setAgpsServer(int type, String hostname, int port) {
1029         Preconditions.checkState(mRegistered);
1030         mGnssHal.setAgpsServer(type, hostname, port);
1031     }
1032 
1033     /**
1034      * Sets AGPS set id.
1035      */
setAgpsSetId(@gpsSetIdType int type, String setId)1036     public void setAgpsSetId(@AgpsSetIdType int type, String setId) {
1037         Preconditions.checkState(mRegistered);
1038         mGnssHal.setAgpsSetId(type, setId);
1039     }
1040 
1041     /**
1042      * Sets AGPS reference cell id location.
1043      */
setAgpsReferenceLocationCellId(@gpsReferenceLocationType int type, int mcc, int mnc, int lac, long cid, int tac, int pcid, int arfcn)1044     public void setAgpsReferenceLocationCellId(@AgpsReferenceLocationType int type, int mcc,
1045             int mnc, int lac, long cid, int tac, int pcid, int arfcn) {
1046         Preconditions.checkState(mRegistered);
1047         mGnssHal.setAgpsReferenceLocationCellId(type, mcc, mnc, lac, cid, tac, pcid, arfcn);
1048     }
1049 
1050     /**
1051      * Returns true if Predicted Satellite Data Service APIs are supported.
1052      */
isPsdsSupported()1053     public boolean isPsdsSupported() {
1054         Preconditions.checkState(mRegistered);
1055         return mGnssHal.isPsdsSupported();
1056     }
1057 
1058     /**
1059      * Injects Predicited Satellite Data Service data into the GNSS HAL.
1060      */
injectPsdsData(byte[] data, int length, int psdsType)1061     public void injectPsdsData(byte[] data, int length, int psdsType) {
1062         Preconditions.checkState(mRegistered);
1063         mGnssHal.injectPsdsData(data, length, psdsType);
1064     }
1065 
1066     /**
1067      * Injects NI SUPL message data into the GNSS HAL.
1068      */
injectNiSuplMessageData(byte[] data, int length, int slotIndex)1069     public void injectNiSuplMessageData(byte[] data, int length, int slotIndex) {
1070         Preconditions.checkState(mRegistered);
1071         mGnssHal.injectNiSuplMessageData(data, length, slotIndex);
1072     }
1073 
1074     /**
1075      * Injects GNSS assistance data into the GNSS HAL.
1076      */
injectGnssAssistance(GnssAssistance assistance)1077     public void injectGnssAssistance(GnssAssistance assistance) {
1078         if (!Flags.gnssAssistanceInterfaceJni()) {
1079             return;
1080         }
1081         Preconditions.checkState(mRegistered);
1082         mGnssHal.injectGnssAssistance(assistance);
1083     }
1084 
1085     @NativeEntryPoint
reportGnssServiceDied()1086     void reportGnssServiceDied() {
1087         // Not necessary to clear (and restore) binder identity since it runs on another thread.
1088         Log.e(TAG, "gnss hal died - restarting shortly...");
1089 
1090         // move to another thread just in case there is some awkward gnss thread dependency with
1091         // the death notification. there shouldn't be, but you never know with gnss...
1092         FgThread.getExecutor().execute(this::restartHal);
1093     }
1094 
1095     @VisibleForTesting
restartHal()1096     void restartHal() {
1097         initializeGnss(true);
1098         Log.e(TAG, "gnss hal restarted");
1099 
1100         for (int i = 0; i < mBaseCallbacks.length; i++) {
1101             mBaseCallbacks[i].onHalRestarted();
1102         }
1103     }
1104 
1105     @NativeEntryPoint
reportLocation(boolean hasLatLong, Location location)1106     void reportLocation(boolean hasLatLong, Location location) {
1107         Binder.withCleanCallingIdentity(() -> {
1108             if (hasLatLong && !mHasFirstFix) {
1109                 mHasFirstFix = true;
1110 
1111                 // notify status listeners
1112                 int ttff = (int) (SystemClock.elapsedRealtime() - mStartRealtimeMs);
1113                 for (int i = 0; i < mStatusCallbacks.length; i++) {
1114                     mStatusCallbacks[i].onReportFirstFix(ttff);
1115                 }
1116             }
1117 
1118             if (location.hasSpeed()) {
1119                 boolean exceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
1120                 if (!mItarSpeedLimitExceeded && exceeded) {
1121                     Log.w(TAG, "speed nearing ITAR threshold - blocking further GNSS output");
1122                 } else if (mItarSpeedLimitExceeded && !exceeded) {
1123                     Log.w(TAG, "speed leaving ITAR threshold - allowing further GNSS output");
1124                 }
1125                 mItarSpeedLimitExceeded = exceeded;
1126             }
1127 
1128             if (mItarSpeedLimitExceeded) {
1129                 return;
1130             }
1131 
1132             for (int i = 0; i < mLocationCallbacks.length; i++) {
1133                 mLocationCallbacks[i].onReportLocation(hasLatLong, location);
1134             }
1135         });
1136     }
1137 
1138     @NativeEntryPoint
reportStatus(@tatusCallbacks.GnssStatusValue int gnssStatus)1139     void reportStatus(@StatusCallbacks.GnssStatusValue int gnssStatus) {
1140         Binder.withCleanCallingIdentity(() -> {
1141             for (int i = 0; i < mStatusCallbacks.length; i++) {
1142                 mStatusCallbacks[i].onReportStatus(gnssStatus);
1143             }
1144         });
1145     }
1146 
1147     @NativeEntryPoint
reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs)1148     void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs,
1149             float[] elevations, float[] azimuths, float[] carrierFrequencies,
1150             float[] basebandCn0DbHzs) {
1151         Binder.withCleanCallingIdentity(() -> {
1152             GnssStatus gnssStatus = GnssStatus.wrap(svCount, svidWithFlags, cn0DbHzs, elevations,
1153                     azimuths, carrierFrequencies, basebandCn0DbHzs);
1154             for (int i = 0; i < mSvStatusCallbacks.length; i++) {
1155                 mSvStatusCallbacks[i].onReportSvStatus(gnssStatus);
1156             }
1157         });
1158     }
1159 
1160     @NativeEntryPoint
reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr)1161     void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1162         Binder.withCleanCallingIdentity(
1163                 () -> mAGpsCallbacks.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr));
1164     }
1165 
1166     @NativeEntryPoint
reportNmea(long timestamp)1167     void reportNmea(long timestamp) {
1168         Binder.withCleanCallingIdentity(() -> {
1169             if (mItarSpeedLimitExceeded) {
1170                 return;
1171             }
1172 
1173             for (int i = 0; i < mNmeaCallbacks.length; i++) {
1174                 mNmeaCallbacks[i].onReportNmea(timestamp);
1175             }
1176         });
1177     }
1178 
1179     @NativeEntryPoint
reportMeasurementData(GnssMeasurementsEvent event)1180     void reportMeasurementData(GnssMeasurementsEvent event) {
1181         Binder.withCleanCallingIdentity(() -> {
1182             if (mItarSpeedLimitExceeded) {
1183                 return;
1184             }
1185 
1186             for (int i = 0; i < mMeasurementCallbacks.length; i++) {
1187                 mMeasurementCallbacks[i].onReportMeasurements(event);
1188             }
1189         });
1190     }
1191 
1192     @NativeEntryPoint
reportAntennaInfo(List<GnssAntennaInfo> antennaInfos)1193     void reportAntennaInfo(List<GnssAntennaInfo> antennaInfos) {
1194         Binder.withCleanCallingIdentity(() -> {
1195             for (int i = 0; i < mAntennaInfoCallbacks.length; i++) {
1196                 mAntennaInfoCallbacks[i].onReportAntennaInfo(antennaInfos);
1197             }
1198         });
1199     }
1200 
1201     @NativeEntryPoint
reportNavigationMessage(GnssNavigationMessage event)1202     void reportNavigationMessage(GnssNavigationMessage event) {
1203         Binder.withCleanCallingIdentity(() -> {
1204             if (mItarSpeedLimitExceeded) {
1205                 return;
1206             }
1207 
1208             for (int i = 0; i < mNavigationMessageCallbacks.length; i++) {
1209                 mNavigationMessageCallbacks[i].onReportNavigationMessage(event);
1210             }
1211         });
1212     }
1213 
1214     @NativeEntryPoint
setTopHalCapabilities(@nssCapabilities.TopHalCapabilityFlags int capabilities, boolean isAdrCapabilityKnown)1215     void setTopHalCapabilities(@GnssCapabilities.TopHalCapabilityFlags int capabilities,
1216             boolean isAdrCapabilityKnown) {
1217         // Here the bits specified by 'capabilities' are turned on. It is handled differently from
1218         // sub hal because top hal capabilities could be set by HIDL HAL and/or AIDL HAL. Each of
1219         // them possesses a different set of capabilities.
1220         mTopFlags |= capabilities;
1221         GnssCapabilities oldCapabilities = mCapabilities;
1222         mCapabilities = oldCapabilities.withTopHalFlags(mTopFlags, isAdrCapabilityKnown);
1223         onCapabilitiesChanged(oldCapabilities, mCapabilities);
1224     }
1225 
1226     @NativeEntryPoint
setSubHalMeasurementCorrectionsCapabilities( @nssCapabilities.SubHalMeasurementCorrectionsCapabilityFlags int capabilities)1227     void setSubHalMeasurementCorrectionsCapabilities(
1228             @GnssCapabilities.SubHalMeasurementCorrectionsCapabilityFlags int capabilities) {
1229         GnssCapabilities oldCapabilities = mCapabilities;
1230         mCapabilities = oldCapabilities.withSubHalMeasurementCorrectionsFlags(capabilities);
1231         onCapabilitiesChanged(oldCapabilities, mCapabilities);
1232     }
1233 
1234     @NativeEntryPoint
setSubHalPowerIndicationCapabilities( @nssCapabilities.SubHalPowerCapabilityFlags int capabilities)1235     void setSubHalPowerIndicationCapabilities(
1236             @GnssCapabilities.SubHalPowerCapabilityFlags int capabilities) {
1237         GnssCapabilities oldCapabilities = mCapabilities;
1238         mCapabilities = oldCapabilities.withSubHalPowerFlags(capabilities);
1239         onCapabilitiesChanged(oldCapabilities, mCapabilities);
1240     }
1241 
1242     @NativeEntryPoint
setSignalTypeCapabilities(List<GnssSignalType> signalTypes)1243     void setSignalTypeCapabilities(List<GnssSignalType> signalTypes) {
1244         GnssCapabilities oldCapabilities = mCapabilities;
1245         mCapabilities = oldCapabilities.withSignalTypes(signalTypes);
1246         onCapabilitiesChanged(oldCapabilities, mCapabilities);
1247     }
1248 
onCapabilitiesChanged(GnssCapabilities oldCapabilities, GnssCapabilities newCapabilities)1249     private void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
1250             GnssCapabilities newCapabilities) {
1251         Binder.withCleanCallingIdentity(() -> {
1252             if (newCapabilities.equals(oldCapabilities)) {
1253                 return;
1254             }
1255 
1256             Log.i(TAG, "gnss capabilities changed to " + newCapabilities);
1257 
1258             for (int i = 0; i < mBaseCallbacks.length; i++) {
1259                 mBaseCallbacks[i].onCapabilitiesChanged(oldCapabilities, newCapabilities);
1260             }
1261         });
1262     }
1263 
1264     @NativeEntryPoint
reportGnssPowerStats(GnssPowerStats powerStats)1265     void reportGnssPowerStats(GnssPowerStats powerStats) {
1266         synchronized (mPowerStatsLock) {
1267             mHandler.removeCallbacks(mPowerStatsTimeoutCallback);
1268             if (powerStats != null) {
1269                 mLastKnownPowerStats = powerStats;
1270             }
1271             mPendingPowerStatsCallbacks.forEach(cb -> cb.onReportPowerStats(powerStats));
1272             mPendingPowerStatsCallbacks.clear();
1273         }
1274     }
1275 
1276     @NativeEntryPoint
setGnssYearOfHardware(int year)1277     void setGnssYearOfHardware(int year) {
1278         mHardwareYear = year;
1279     }
1280 
1281     @NativeEntryPoint
setGnssHardwareModelName(String modelName)1282     private void setGnssHardwareModelName(String modelName) {
1283         mHardwareModelName = modelName;
1284     }
1285 
1286     @NativeEntryPoint
reportLocationBatch(Location[] locations)1287     void reportLocationBatch(Location[] locations) {
1288         Binder.withCleanCallingIdentity(() -> {
1289             for (int i = 0; i < mLocationCallbacks.length; i++) {
1290                 mLocationCallbacks[i].onReportLocations(locations);
1291             }
1292         });
1293     }
1294 
1295     @NativeEntryPoint
psdsDownloadRequest(int psdsType)1296     void psdsDownloadRequest(int psdsType) {
1297         Binder.withCleanCallingIdentity(() -> mPsdsCallbacks.onRequestPsdsDownload(psdsType));
1298     }
1299 
1300     @NativeEntryPoint
gnssAssistanceInjectRequest()1301     void gnssAssistanceInjectRequest() {
1302         if (!Flags.gnssAssistanceInterfaceJni() || mGnssAssistanceCallbacks == null) {
1303             return;
1304         }
1305         Binder.withCleanCallingIdentity(
1306                 () -> mGnssAssistanceCallbacks.onRequestGnssAssistanceInject());
1307     }
1308 
1309     @NativeEntryPoint
reportGeofenceTransition(int geofenceId, Location location, int transition, long transitionTimestamp)1310     void reportGeofenceTransition(int geofenceId, Location location, int transition,
1311             long transitionTimestamp) {
1312         Binder.withCleanCallingIdentity(
1313                 () -> mGeofenceCallbacks.onReportGeofenceTransition(geofenceId, location,
1314                         transition, transitionTimestamp));
1315     }
1316 
1317     @NativeEntryPoint
reportGeofenceStatus(int status, Location location)1318     void reportGeofenceStatus(int status, Location location) {
1319         Binder.withCleanCallingIdentity(
1320                 () -> mGeofenceCallbacks.onReportGeofenceStatus(status, location));
1321     }
1322 
1323     @NativeEntryPoint
reportGeofenceAddStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status)1324     void reportGeofenceAddStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status) {
1325         Binder.withCleanCallingIdentity(
1326                 () -> mGeofenceCallbacks.onReportGeofenceAddStatus(geofenceId, status));
1327     }
1328 
1329     @NativeEntryPoint
reportGeofenceRemoveStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status)1330     void reportGeofenceRemoveStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status) {
1331         Binder.withCleanCallingIdentity(
1332                 () -> mGeofenceCallbacks.onReportGeofenceRemoveStatus(geofenceId, status));
1333     }
1334 
1335     @NativeEntryPoint
reportGeofencePauseStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status)1336     void reportGeofencePauseStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status) {
1337         Binder.withCleanCallingIdentity(
1338                 () -> mGeofenceCallbacks.onReportGeofencePauseStatus(geofenceId, status));
1339     }
1340 
1341     @NativeEntryPoint
reportGeofenceResumeStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status)1342     void reportGeofenceResumeStatus(int geofenceId, @GeofenceCallbacks.GeofenceStatus int status) {
1343         Binder.withCleanCallingIdentity(
1344                 () -> mGeofenceCallbacks.onReportGeofenceResumeStatus(geofenceId, status));
1345     }
1346 
1347     @NativeEntryPoint
requestSetID(int flags)1348     void requestSetID(int flags) {
1349         Binder.withCleanCallingIdentity(() -> mAGpsCallbacks.onRequestSetID(flags));
1350     }
1351 
1352     @NativeEntryPoint
requestLocation(boolean independentFromGnss, boolean isUserEmergency)1353     void requestLocation(boolean independentFromGnss, boolean isUserEmergency) {
1354         Binder.withCleanCallingIdentity(
1355                 () -> mLocationRequestCallbacks.onRequestLocation(independentFromGnss,
1356                         isUserEmergency));
1357     }
1358 
1359     @NativeEntryPoint
requestUtcTime()1360     void requestUtcTime() {
1361         Binder.withCleanCallingIdentity(() -> mTimeCallbacks.onRequestUtcTime());
1362     }
1363 
1364     @NativeEntryPoint
requestRefLocation()1365     void requestRefLocation() {
1366         Binder.withCleanCallingIdentity(
1367                 () -> mLocationRequestCallbacks.onRequestRefLocation());
1368     }
1369 
1370     @NativeEntryPoint
reportNfwNotification(String proxyAppPackageName, byte protocolStack, String otherProtocolStackName, byte requestor, String requestorId, byte responseType, boolean inEmergencyMode, boolean isCachedLocation)1371     void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
1372             String otherProtocolStackName, byte requestor, String requestorId,
1373             byte responseType, boolean inEmergencyMode, boolean isCachedLocation) {
1374         Binder.withCleanCallingIdentity(
1375                 () -> mNotificationCallbacks.onReportNfwNotification(proxyAppPackageName,
1376                         protocolStack, otherProtocolStackName, requestor, requestorId, responseType,
1377                         inEmergencyMode, isCachedLocation));
1378     }
1379 
1380     @NativeEntryPoint
isInEmergencySession()1381     public boolean isInEmergencySession() {
1382         return Binder.withCleanCallingIdentity(
1383                 () -> mEmergencyHelper.isInEmergency(
1384                         TimeUnit.SECONDS.toMillis(mConfiguration.getEsExtensionSec())));
1385     }
1386 
1387     /**
1388      * Encapsulates actual HAL methods for testing purposes.
1389      */
1390     @VisibleForTesting
1391     public static class GnssHal {
1392 
GnssHal()1393         protected GnssHal() {}
1394 
classInitOnce()1395         protected void classInitOnce() {
1396             native_class_init_once();
1397         }
1398 
isSupported()1399         protected boolean isSupported() {
1400             return native_is_supported();
1401         }
1402 
initOnce(GnssNative gnssNative, boolean reinitializeGnssServiceHandle)1403         protected void initOnce(GnssNative gnssNative, boolean reinitializeGnssServiceHandle) {
1404             gnssNative.native_init_once(reinitializeGnssServiceHandle);
1405         }
1406 
init()1407         protected boolean init() {
1408             return native_init();
1409         }
1410 
cleanup()1411         protected void cleanup() {
1412             native_cleanup();
1413         }
1414 
start()1415         protected boolean start() {
1416             return native_start();
1417         }
1418 
stop()1419         protected boolean stop() {
1420             return native_stop();
1421         }
1422 
setPositionMode(@nssPositionMode int mode, @GnssPositionRecurrence int recurrence, int minInterval, int preferredAccuracy, int preferredTime, boolean lowPowerMode)1423         protected boolean setPositionMode(@GnssPositionMode int mode,
1424                 @GnssPositionRecurrence int recurrence, int minInterval, int preferredAccuracy,
1425                 int preferredTime, boolean lowPowerMode) {
1426             return native_set_position_mode(mode, recurrence, minInterval, preferredAccuracy,
1427                     preferredTime, lowPowerMode);
1428         }
1429 
getInternalState()1430         protected String getInternalState() {
1431             return native_get_internal_state();
1432         }
1433 
deleteAidingData(@nssAidingTypeFlags int flags)1434         protected void deleteAidingData(@GnssAidingTypeFlags int flags) {
1435             native_delete_aiding_data(flags);
1436         }
1437 
readNmea(byte[] buffer, int bufferSize)1438         protected int readNmea(byte[] buffer, int bufferSize) {
1439             return native_read_nmea(buffer, bufferSize);
1440         }
1441 
injectLocation(@nssLocationFlags int gnssLocationFlags, double latitude, double longitude, double altitude, float speed, float bearing, float horizontalAccuracy, float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp, @GnssRealtimeFlags int elapsedRealtimeFlags, long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos)1442         protected void injectLocation(@GnssLocationFlags int gnssLocationFlags, double latitude,
1443                 double longitude, double altitude, float speed, float bearing,
1444                 float horizontalAccuracy, float verticalAccuracy, float speedAccuracy,
1445                 float bearingAccuracy, long timestamp, @GnssRealtimeFlags int elapsedRealtimeFlags,
1446                 long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos) {
1447             native_inject_location(gnssLocationFlags, latitude, longitude, altitude, speed,
1448                     bearing, horizontalAccuracy, verticalAccuracy, speedAccuracy, bearingAccuracy,
1449                     timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos,
1450                     elapsedRealtimeUncertaintyNanos);
1451         }
1452 
injectBestLocation(@nssLocationFlags int gnssLocationFlags, double latitude, double longitude, double altitude, float speed, float bearing, float horizontalAccuracy, float verticalAccuracy, float speedAccuracy, float bearingAccuracy, long timestamp, @GnssRealtimeFlags int elapsedRealtimeFlags, long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos)1453         protected void injectBestLocation(@GnssLocationFlags int gnssLocationFlags, double latitude,
1454                 double longitude, double altitude, float speed, float bearing,
1455                 float horizontalAccuracy, float verticalAccuracy, float speedAccuracy,
1456                 float bearingAccuracy, long timestamp, @GnssRealtimeFlags int elapsedRealtimeFlags,
1457                 long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos) {
1458             native_inject_best_location(gnssLocationFlags, latitude, longitude, altitude, speed,
1459                     bearing, horizontalAccuracy, verticalAccuracy, speedAccuracy, bearingAccuracy,
1460                     timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos,
1461                     elapsedRealtimeUncertaintyNanos);
1462         }
1463 
injectTime(long time, long timeReference, int uncertainty)1464         protected void injectTime(long time, long timeReference, int uncertainty) {
1465             native_inject_time(time, timeReference, uncertainty);
1466         }
1467 
isNavigationMessageCollectionSupported()1468         protected boolean isNavigationMessageCollectionSupported() {
1469             return native_is_navigation_message_supported();
1470         }
1471 
startNavigationMessageCollection()1472         protected boolean startNavigationMessageCollection() {
1473             return native_start_navigation_message_collection();
1474         }
1475 
stopNavigationMessageCollection()1476         protected boolean stopNavigationMessageCollection() {
1477             return native_stop_navigation_message_collection();
1478         }
1479 
isAntennaInfoSupported()1480         protected boolean isAntennaInfoSupported() {
1481             return native_is_antenna_info_supported();
1482         }
1483 
startAntennaInfoListening()1484         protected boolean startAntennaInfoListening() {
1485             return native_start_antenna_info_listening();
1486         }
1487 
stopAntennaInfoListening()1488         protected boolean stopAntennaInfoListening() {
1489             return native_stop_antenna_info_listening();
1490         }
1491 
isMeasurementSupported()1492         protected boolean isMeasurementSupported() {
1493             return native_is_measurement_supported();
1494         }
1495 
startMeasurementCollection(boolean enableFullTracking, boolean enableCorrVecOutputs, int intervalMillis)1496         protected boolean startMeasurementCollection(boolean enableFullTracking,
1497                 boolean enableCorrVecOutputs, int intervalMillis) {
1498             return native_start_measurement_collection(enableFullTracking, enableCorrVecOutputs,
1499                     intervalMillis);
1500         }
1501 
stopMeasurementCollection()1502         protected boolean stopMeasurementCollection() {
1503             return native_stop_measurement_collection();
1504         }
1505 
isMeasurementCorrectionsSupported()1506         protected boolean isMeasurementCorrectionsSupported() {
1507             return native_is_measurement_corrections_supported();
1508         }
1509 
injectMeasurementCorrections(GnssMeasurementCorrections corrections)1510         protected boolean injectMeasurementCorrections(GnssMeasurementCorrections corrections) {
1511             return native_inject_measurement_corrections(corrections);
1512         }
1513 
startSvStatusCollection()1514         protected boolean startSvStatusCollection() {
1515             return native_start_sv_status_collection();
1516         }
1517 
stopSvStatusCollection()1518         protected boolean stopSvStatusCollection() {
1519             return native_stop_sv_status_collection();
1520         }
1521 
startNmeaMessageCollection()1522         protected boolean startNmeaMessageCollection() {
1523             return native_start_nmea_message_collection();
1524         }
1525 
stopNmeaMessageCollection()1526         protected boolean stopNmeaMessageCollection() {
1527             return native_stop_nmea_message_collection();
1528         }
1529 
getBatchSize()1530         protected int getBatchSize() {
1531             return native_get_batch_size();
1532         }
1533 
initBatching()1534         protected boolean initBatching() {
1535             return native_init_batching();
1536         }
1537 
cleanupBatching()1538         protected void cleanupBatching() {
1539             native_cleanup_batching();
1540         }
1541 
startBatch(long periodNanos, float minUpdateDistanceMeters, boolean wakeOnFifoFull)1542         protected boolean startBatch(long periodNanos, float minUpdateDistanceMeters,
1543                 boolean wakeOnFifoFull) {
1544             return native_start_batch(periodNanos, minUpdateDistanceMeters, wakeOnFifoFull);
1545         }
1546 
flushBatch()1547         protected void flushBatch() {
1548             native_flush_batch();
1549         }
1550 
stopBatch()1551         protected void stopBatch() {
1552             native_stop_batch();
1553         }
1554 
isGeofencingSupported()1555         protected boolean isGeofencingSupported() {
1556             return native_is_geofence_supported();
1557         }
1558 
addGeofence(int geofenceId, double latitude, double longitude, double radius, int lastTransition, int monitorTransitions, int notificationResponsiveness, int unknownTimer)1559         protected boolean addGeofence(int geofenceId, double latitude, double longitude,
1560                 double radius, int lastTransition, int monitorTransitions,
1561                 int notificationResponsiveness, int unknownTimer) {
1562             return native_add_geofence(geofenceId, latitude, longitude, radius, lastTransition,
1563                     monitorTransitions, notificationResponsiveness, unknownTimer);
1564         }
1565 
resumeGeofence(int geofenceId, int monitorTransitions)1566         protected boolean resumeGeofence(int geofenceId, int monitorTransitions) {
1567             return native_resume_geofence(geofenceId, monitorTransitions);
1568         }
1569 
pauseGeofence(int geofenceId)1570         protected boolean pauseGeofence(int geofenceId) {
1571             return native_pause_geofence(geofenceId);
1572         }
1573 
removeGeofence(int geofenceId)1574         protected boolean removeGeofence(int geofenceId) {
1575             return native_remove_geofence(geofenceId);
1576         }
1577 
isGnssVisibilityControlSupported()1578         protected boolean isGnssVisibilityControlSupported() {
1579             return native_is_gnss_visibility_control_supported();
1580         }
1581 
requestPowerStats()1582         protected void requestPowerStats() {
1583             native_request_power_stats();
1584         }
1585 
setAgpsServer(int type, String hostname, int port)1586         protected void setAgpsServer(int type, String hostname, int port) {
1587             native_set_agps_server(type, hostname, port);
1588         }
1589 
setAgpsSetId(@gpsSetIdType int type, String setId)1590         protected void setAgpsSetId(@AgpsSetIdType int type, String setId) {
1591             native_agps_set_id(type, setId);
1592         }
1593 
setAgpsReferenceLocationCellId(@gpsReferenceLocationType int type, int mcc, int mnc, int lac, long cid, int tac, int pcid, int arfcn)1594         protected void setAgpsReferenceLocationCellId(@AgpsReferenceLocationType int type, int mcc,
1595                 int mnc, int lac, long cid, int tac, int pcid, int arfcn) {
1596             native_agps_set_ref_location_cellid(type, mcc, mnc, lac, cid, tac, pcid, arfcn);
1597         }
1598 
isPsdsSupported()1599         protected boolean isPsdsSupported() {
1600             return native_supports_psds();
1601         }
1602 
injectPsdsData(byte[] data, int length, int psdsType)1603         protected void injectPsdsData(byte[] data, int length, int psdsType) {
1604             native_inject_psds_data(data, length, psdsType);
1605         }
1606 
injectNiSuplMessageData(byte[] data, int length, int slotIndex)1607         protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) {
1608             native_inject_ni_supl_message_data(data, length, slotIndex);
1609         }
1610 
injectGnssAssistance(GnssAssistance gnssAssistance)1611         protected void injectGnssAssistance(GnssAssistance gnssAssistance) {
1612             native_inject_gnss_assistance(gnssAssistance);
1613         }
1614     }
1615 
1616     // basic APIs
1617 
native_class_init_once()1618     private static native void native_class_init_once();
1619 
native_is_supported()1620     private static native boolean native_is_supported();
1621 
native_init_once(boolean reinitializeGnssServiceHandle)1622     private native void native_init_once(boolean reinitializeGnssServiceHandle);
1623 
native_init()1624     private static native boolean native_init();
1625 
native_cleanup()1626     private static native void native_cleanup();
1627 
native_start()1628     private static native boolean native_start();
1629 
native_stop()1630     private static native boolean native_stop();
1631 
native_set_position_mode(int mode, int recurrence, int minInterval, int preferredAccuracy, int preferredTime, boolean lowPowerMode)1632     private static native boolean native_set_position_mode(int mode, int recurrence,
1633             int minInterval, int preferredAccuracy, int preferredTime, boolean lowPowerMode);
1634 
native_get_internal_state()1635     private static native String native_get_internal_state();
1636 
native_delete_aiding_data(int flags)1637     private static native void native_delete_aiding_data(int flags);
1638 
1639     // NMEA APIs
1640 
native_read_nmea(byte[] buffer, int bufferSize)1641     private static native int native_read_nmea(byte[] buffer, int bufferSize);
1642 
native_start_nmea_message_collection()1643     private static native boolean native_start_nmea_message_collection();
1644 
native_stop_nmea_message_collection()1645     private static native boolean native_stop_nmea_message_collection();
1646 
1647     // location injection APIs
1648 
native_inject_location( int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees, double altitudeMeters, float speedMetersPerSec, float bearingDegrees, float horizontalAccuracyMeters, float verticalAccuracyMeters, float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees, long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos)1649     private static native void native_inject_location(
1650             int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
1651             double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
1652             float horizontalAccuracyMeters, float verticalAccuracyMeters,
1653             float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
1654             long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
1655             double elapsedRealtimeUncertaintyNanos);
1656 
1657 
native_inject_best_location( int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees, double altitudeMeters, float speedMetersPerSec, float bearingDegrees, float horizontalAccuracyMeters, float verticalAccuracyMeters, float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees, long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos, double elapsedRealtimeUncertaintyNanos)1658     private static native void native_inject_best_location(
1659             int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
1660             double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
1661             float horizontalAccuracyMeters, float verticalAccuracyMeters,
1662             float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
1663             long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
1664             double elapsedRealtimeUncertaintyNanos);
1665 
1666     // time injection APIs
1667 
native_inject_time(long time, long timeReference, int uncertainty)1668     private static native void native_inject_time(long time, long timeReference, int uncertainty);
1669 
1670     // sv status APIs
native_start_sv_status_collection()1671     private static native boolean native_start_sv_status_collection();
1672 
native_stop_sv_status_collection()1673     private static native boolean native_stop_sv_status_collection();
1674 
1675     // navigation message APIs
1676 
native_is_navigation_message_supported()1677     private static native boolean native_is_navigation_message_supported();
1678 
native_start_navigation_message_collection()1679     private static native boolean native_start_navigation_message_collection();
1680 
native_stop_navigation_message_collection()1681     private static native boolean native_stop_navigation_message_collection();
1682 
1683     // antenna info APIS
1684     // TODO: in a next version of the HAL, consider removing the necessity for listening to antenna
1685     //   info changes, and simply report them always, same as capabilities.
1686 
native_is_antenna_info_supported()1687     private static native boolean native_is_antenna_info_supported();
1688 
native_start_antenna_info_listening()1689     private static native boolean native_start_antenna_info_listening();
1690 
native_stop_antenna_info_listening()1691     private static native boolean native_stop_antenna_info_listening();
1692 
1693     // measurement APIs
1694 
native_is_measurement_supported()1695     private static native boolean native_is_measurement_supported();
1696 
native_start_measurement_collection(boolean enableFullTracking, boolean enableCorrVecOutputs, int intervalMillis)1697     private static native boolean native_start_measurement_collection(boolean enableFullTracking,
1698             boolean enableCorrVecOutputs, int intervalMillis);
1699 
native_stop_measurement_collection()1700     private static native boolean native_stop_measurement_collection();
1701 
1702     // measurement corrections APIs
1703 
native_is_measurement_corrections_supported()1704     private static native boolean native_is_measurement_corrections_supported();
1705 
native_inject_measurement_corrections( GnssMeasurementCorrections corrections)1706     private static native boolean native_inject_measurement_corrections(
1707             GnssMeasurementCorrections corrections);
1708 
1709     // batching APIs
1710 
native_init_batching()1711     private static native boolean native_init_batching();
1712 
native_cleanup_batching()1713     private static native void native_cleanup_batching();
1714 
native_start_batch(long periodNanos, float minUpdateDistanceMeters, boolean wakeOnFifoFull)1715     private static native boolean native_start_batch(long periodNanos,
1716             float minUpdateDistanceMeters, boolean wakeOnFifoFull);
1717 
native_flush_batch()1718     private static native void native_flush_batch();
1719 
native_stop_batch()1720     private static native boolean native_stop_batch();
1721 
native_get_batch_size()1722     private static native int native_get_batch_size();
1723 
1724     // geofence APIs
1725 
native_is_geofence_supported()1726     private static native boolean native_is_geofence_supported();
1727 
native_add_geofence(int geofenceId, double latitude, double longitude, double radius, int lastTransition, int monitorTransitions, int notificationResponsivenes, int unknownTimer)1728     private static native boolean native_add_geofence(int geofenceId, double latitude,
1729             double longitude, double radius, int lastTransition, int monitorTransitions,
1730             int notificationResponsivenes, int unknownTimer);
1731 
native_resume_geofence(int geofenceId, int monitorTransitions)1732     private static native boolean native_resume_geofence(int geofenceId, int monitorTransitions);
1733 
native_pause_geofence(int geofenceId)1734     private static native boolean native_pause_geofence(int geofenceId);
1735 
native_remove_geofence(int geofenceId)1736     private static native boolean native_remove_geofence(int geofenceId);
1737 
1738     // network initiated (NI) APIs
1739 
native_is_gnss_visibility_control_supported()1740     private static native boolean native_is_gnss_visibility_control_supported();
1741 
1742     // power stats APIs
1743 
native_request_power_stats()1744     private static native void native_request_power_stats();
1745 
1746     // AGPS APIs
1747 
native_set_agps_server(int type, String hostname, int port)1748     private static native void native_set_agps_server(int type, String hostname, int port);
1749 
native_agps_set_id(int type, String setid)1750     private static native void native_agps_set_id(int type, String setid);
1751 
native_agps_set_ref_location_cellid(int type, int mcc, int mnc, int lac, long cid, int tac, int pcid, int arfcn)1752     private static native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
1753             int lac, long cid, int tac, int pcid, int arfcn);
1754 
native_inject_ni_supl_message_data(byte[] data, int length, int slotIndex)1755     private static native void native_inject_ni_supl_message_data(byte[] data, int length,
1756             int slotIndex);
1757 
1758     // PSDS APIs
1759 
native_supports_psds()1760     private static native boolean native_supports_psds();
1761 
native_inject_psds_data(byte[] data, int length, int psdsType)1762     private static native void native_inject_psds_data(byte[] data, int length, int psdsType);
1763 
1764     // GNSS Assistance APIs
native_inject_gnss_assistance(GnssAssistance gnssAssistance)1765     private static native void native_inject_gnss_assistance(GnssAssistance gnssAssistance);
1766 }
1767