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