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