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