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