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