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