1 /* 2 * Copyright (C) 2014 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 android.location; 18 19 import android.annotation.FloatRange; 20 import android.annotation.NonNull; 21 import android.annotation.TestApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 /** 26 * A class containing a GNSS clock timestamp. 27 * 28 * <p>It represents a measurement of the GNSS receiver's clock. 29 */ 30 public final class GnssClock implements Parcelable { 31 // The following enumerations must be in sync with the values declared in gps.h 32 33 private static final int HAS_NO_FLAGS = 0; 34 private static final int HAS_LEAP_SECOND = (1<<0); 35 private static final int HAS_TIME_UNCERTAINTY = (1<<1); 36 private static final int HAS_FULL_BIAS = (1<<2); 37 private static final int HAS_BIAS = (1<<3); 38 private static final int HAS_BIAS_UNCERTAINTY = (1<<4); 39 private static final int HAS_DRIFT = (1<<5); 40 private static final int HAS_DRIFT_UNCERTAINTY = (1<<6); 41 private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7); 42 private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8); 43 private static final int HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB = (1 << 9); 44 private static final int HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB = (1 << 10); 45 private static final int HAS_REFERENCE_CODE_TYPE_FOR_ISB = (1 << 11); 46 47 // End enumerations in sync with gps.h 48 49 private int mFlags; 50 private int mLeapSecond; 51 private long mTimeNanos; 52 private double mTimeUncertaintyNanos; 53 private long mFullBiasNanos; 54 private double mBiasNanos; 55 private double mBiasUncertaintyNanos; 56 private double mDriftNanosPerSecond; 57 private double mDriftUncertaintyNanosPerSecond; 58 private int mHardwareClockDiscontinuityCount; 59 private long mElapsedRealtimeNanos; 60 private double mElapsedRealtimeUncertaintyNanos; 61 private int mReferenceConstellationTypeForIsb; 62 private double mReferenceCarrierFrequencyHzForIsb; 63 private String mReferenceCodeTypeForIsb; 64 65 /** 66 * @hide 67 */ 68 @TestApi GnssClock()69 public GnssClock() { 70 initialize(); 71 } 72 73 /** 74 * Sets all contents to the values stored in the provided object. 75 * @hide 76 */ 77 @TestApi set(GnssClock clock)78 public void set(GnssClock clock) { 79 mFlags = clock.mFlags; 80 mLeapSecond = clock.mLeapSecond; 81 mTimeNanos = clock.mTimeNanos; 82 mTimeUncertaintyNanos = clock.mTimeUncertaintyNanos; 83 mFullBiasNanos = clock.mFullBiasNanos; 84 mBiasNanos = clock.mBiasNanos; 85 mBiasUncertaintyNanos = clock.mBiasUncertaintyNanos; 86 mDriftNanosPerSecond = clock.mDriftNanosPerSecond; 87 mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond; 88 mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount; 89 mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos; 90 mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos; 91 mReferenceConstellationTypeForIsb = clock.mReferenceConstellationTypeForIsb; 92 mReferenceCarrierFrequencyHzForIsb = clock.mReferenceCarrierFrequencyHzForIsb; 93 mReferenceCodeTypeForIsb = clock.mReferenceCodeTypeForIsb; 94 } 95 96 /** 97 * Resets all the contents to its original state. 98 * @hide 99 */ 100 @TestApi reset()101 public void reset() { 102 initialize(); 103 } 104 105 /** 106 * Returns {@code true} if {@link #getLeapSecond()} is available, {@code false} otherwise. 107 */ hasLeapSecond()108 public boolean hasLeapSecond() { 109 return isFlagSet(HAS_LEAP_SECOND); 110 } 111 112 /** 113 * Gets the leap second associated with the clock's time. 114 * 115 * <p>The sign of the value is defined by the following equation: 116 * <pre> 117 * UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000</pre> 118 * 119 * <p>The value is only available if {@link #hasLeapSecond()} is {@code true}. 120 */ getLeapSecond()121 public int getLeapSecond() { 122 return mLeapSecond; 123 } 124 125 /** 126 * Sets the leap second associated with the clock's time. 127 * @hide 128 */ 129 @TestApi setLeapSecond(int leapSecond)130 public void setLeapSecond(int leapSecond) { 131 setFlag(HAS_LEAP_SECOND); 132 mLeapSecond = leapSecond; 133 } 134 135 /** 136 * Resets the leap second associated with the clock's time. 137 * @hide 138 */ 139 @TestApi resetLeapSecond()140 public void resetLeapSecond() { 141 resetFlag(HAS_LEAP_SECOND); 142 mLeapSecond = Integer.MIN_VALUE; 143 } 144 145 /** 146 * Gets the GNSS receiver internal hardware clock value in nanoseconds. 147 * 148 * <p>This value is expected to be monotonically increasing while the hardware clock remains 149 * powered on. For the case of a hardware clock that is not continuously on, see the 150 * {@link #getHardwareClockDiscontinuityCount} field. The GPS time can be derived by subtracting 151 * the sum of {@link #getFullBiasNanos()} and {@link #getBiasNanos()} (when they are available) 152 * from this value. Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}. 153 * 154 * <p>The error estimate for this value (if applicable) is {@link #getTimeUncertaintyNanos()}. 155 */ getTimeNanos()156 public long getTimeNanos() { 157 return mTimeNanos; 158 } 159 160 /** 161 * Sets the GNSS receiver internal clock in nanoseconds. 162 * @hide 163 */ 164 @TestApi setTimeNanos(long timeNanos)165 public void setTimeNanos(long timeNanos) { 166 mTimeNanos = timeNanos; 167 } 168 169 /** 170 * Returns {@code true} if {@link #getTimeUncertaintyNanos()} is available, {@code false} 171 * otherwise. 172 */ hasTimeUncertaintyNanos()173 public boolean hasTimeUncertaintyNanos() { 174 return isFlagSet(HAS_TIME_UNCERTAINTY); 175 } 176 177 /** 178 * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds. 179 * 180 * <p>The uncertainty is represented as an absolute (single sided) value. 181 * 182 * <p>The value is only available if {@link #hasTimeUncertaintyNanos()} is {@code true}. 183 * 184 * <p>This value is often effectively zero (it is the reference clock by which all other times 185 * and time uncertainties are measured), and thus this field may often be 0, or not provided. 186 */ 187 @FloatRange(from = 0.0f) getTimeUncertaintyNanos()188 public double getTimeUncertaintyNanos() { 189 return mTimeUncertaintyNanos; 190 } 191 192 /** 193 * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds. 194 * @hide 195 */ 196 @TestApi setTimeUncertaintyNanos(@loatRangefrom = 0.0f) double timeUncertaintyNanos)197 public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) { 198 setFlag(HAS_TIME_UNCERTAINTY); 199 mTimeUncertaintyNanos = timeUncertaintyNanos; 200 } 201 202 /** 203 * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds. 204 * @hide 205 */ 206 @TestApi resetTimeUncertaintyNanos()207 public void resetTimeUncertaintyNanos() { 208 resetFlag(HAS_TIME_UNCERTAINTY); 209 } 210 211 /** 212 * Returns {@code true} if {@link #getFullBiasNanos()} is available, {@code false} otherwise. 213 */ hasFullBiasNanos()214 public boolean hasFullBiasNanos() { 215 return isFlagSet(HAS_FULL_BIAS); 216 } 217 218 /** 219 * Gets the difference between hardware clock ({@link #getTimeNanos()}) inside GPS receiver and 220 * the true GPS time since 0000Z, January 6, 1980, in nanoseconds. 221 * 222 * <p>This value is available if the receiver has estimated GPS time. If the computed time is 223 * for a non-GPS constellation, the time offset of that constellation to GPS has to be applied 224 * to fill this value. The value is only available if {@link #hasFullBiasNanos()} is 225 * {@code true}. 226 * 227 * <p>The error estimate for the sum of this field and {@link #getBiasNanos} is 228 * {@link #getBiasUncertaintyNanos()}. 229 * 230 * <p>The sign of the value is defined by the following equation: 231 * 232 * <pre> 233 * local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)</pre> 234 */ getFullBiasNanos()235 public long getFullBiasNanos() { 236 return mFullBiasNanos; 237 } 238 239 /** 240 * Sets the full bias in nanoseconds. 241 * @hide 242 */ 243 @TestApi setFullBiasNanos(long value)244 public void setFullBiasNanos(long value) { 245 setFlag(HAS_FULL_BIAS); 246 mFullBiasNanos = value; 247 } 248 249 /** 250 * Resets the full bias in nanoseconds. 251 * @hide 252 */ 253 @TestApi resetFullBiasNanos()254 public void resetFullBiasNanos() { 255 resetFlag(HAS_FULL_BIAS); 256 mFullBiasNanos = Long.MIN_VALUE; 257 } 258 259 /** 260 * Returns {@code true} if {@link #getBiasNanos()} is available, {@code false} otherwise. 261 */ hasBiasNanos()262 public boolean hasBiasNanos() { 263 return isFlagSet(HAS_BIAS); 264 } 265 266 /** 267 * Gets the clock's sub-nanosecond bias. 268 * 269 * <p>See the description of how this field is part of converting from hardware clock time, to 270 * GPS time, in {@link #getFullBiasNanos()}. 271 * 272 * <p>The error estimate for the sum of this field and {@link #getFullBiasNanos} is 273 * {@link #getBiasUncertaintyNanos()}. 274 * 275 * <p>The value is only available if {@link #hasBiasNanos()} is {@code true}. 276 */ getBiasNanos()277 public double getBiasNanos() { 278 return mBiasNanos; 279 } 280 281 /** 282 * Sets the sub-nanosecond bias. 283 * @hide 284 */ 285 @TestApi setBiasNanos(double biasNanos)286 public void setBiasNanos(double biasNanos) { 287 setFlag(HAS_BIAS); 288 mBiasNanos = biasNanos; 289 } 290 291 /** 292 * Resets the clock's Bias in nanoseconds. 293 * @hide 294 */ 295 @TestApi resetBiasNanos()296 public void resetBiasNanos() { 297 resetFlag(HAS_BIAS); 298 } 299 300 /** 301 * Returns {@code true} if {@link #getBiasUncertaintyNanos()} is available, {@code false} 302 * otherwise. 303 */ hasBiasUncertaintyNanos()304 public boolean hasBiasUncertaintyNanos() { 305 return isFlagSet(HAS_BIAS_UNCERTAINTY); 306 } 307 308 /** 309 * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 310 * 311 * <p>See the description of how this field provides the error estimate in the conversion from 312 * hardware clock time, to GPS time, in {@link #getFullBiasNanos()}. 313 * 314 * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}. 315 */ 316 @FloatRange(from = 0.0f) getBiasUncertaintyNanos()317 public double getBiasUncertaintyNanos() { 318 return mBiasUncertaintyNanos; 319 } 320 321 /** 322 * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 323 * @hide 324 */ 325 @TestApi setBiasUncertaintyNanos(@loatRangefrom = 0.0f) double biasUncertaintyNanos)326 public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) { 327 setFlag(HAS_BIAS_UNCERTAINTY); 328 mBiasUncertaintyNanos = biasUncertaintyNanos; 329 } 330 331 /** 332 * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 333 * @hide 334 */ 335 @TestApi resetBiasUncertaintyNanos()336 public void resetBiasUncertaintyNanos() { 337 resetFlag(HAS_BIAS_UNCERTAINTY); 338 } 339 340 /** 341 * Returns {@code true} if {@link #getDriftNanosPerSecond()} is available, {@code false} 342 * otherwise. 343 */ hasDriftNanosPerSecond()344 public boolean hasDriftNanosPerSecond() { 345 return isFlagSet(HAS_DRIFT); 346 } 347 348 /** 349 * Gets the clock's Drift in nanoseconds per second. 350 * 351 * <p>This value is the instantaneous time-derivative of the value provided by 352 * {@link #getBiasNanos()}. 353 * 354 * <p>A positive value indicates that the frequency is higher than the nominal (e.g. GPS master 355 * clock) frequency. The error estimate for this reported drift is 356 * {@link #getDriftUncertaintyNanosPerSecond()}. 357 * 358 * <p>The value is only available if {@link #hasDriftNanosPerSecond()} is {@code true}. 359 */ getDriftNanosPerSecond()360 public double getDriftNanosPerSecond() { 361 return mDriftNanosPerSecond; 362 } 363 364 /** 365 * Sets the clock's Drift in nanoseconds per second. 366 * @hide 367 */ 368 @TestApi setDriftNanosPerSecond(double driftNanosPerSecond)369 public void setDriftNanosPerSecond(double driftNanosPerSecond) { 370 setFlag(HAS_DRIFT); 371 mDriftNanosPerSecond = driftNanosPerSecond; 372 } 373 374 /** 375 * Resets the clock's Drift in nanoseconds per second. 376 * @hide 377 */ 378 @TestApi resetDriftNanosPerSecond()379 public void resetDriftNanosPerSecond() { 380 resetFlag(HAS_DRIFT); 381 } 382 383 /** 384 * Returns {@code true} if {@link #getDriftUncertaintyNanosPerSecond()} is available, 385 * {@code false} otherwise. 386 */ hasDriftUncertaintyNanosPerSecond()387 public boolean hasDriftUncertaintyNanosPerSecond() { 388 return isFlagSet(HAS_DRIFT_UNCERTAINTY); 389 } 390 391 /** 392 * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 393 * 394 * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is 395 * {@code true}. 396 */ 397 @FloatRange(from = 0.0f) getDriftUncertaintyNanosPerSecond()398 public double getDriftUncertaintyNanosPerSecond() { 399 return mDriftUncertaintyNanosPerSecond; 400 } 401 402 /** 403 * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 404 * @hide 405 */ 406 @TestApi setDriftUncertaintyNanosPerSecond( @loatRangefrom = 0.0f) double driftUncertaintyNanosPerSecond)407 public void setDriftUncertaintyNanosPerSecond( 408 @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) { 409 setFlag(HAS_DRIFT_UNCERTAINTY); 410 mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond; 411 } 412 413 /** 414 * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 415 * @hide 416 */ 417 @TestApi resetDriftUncertaintyNanosPerSecond()418 public void resetDriftUncertaintyNanosPerSecond() { 419 resetFlag(HAS_DRIFT_UNCERTAINTY); 420 } 421 422 /** 423 * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false} 424 * otherwise. 425 */ hasElapsedRealtimeNanos()426 public boolean hasElapsedRealtimeNanos() { 427 return isFlagSet(HAS_ELAPSED_REALTIME_NANOS); 428 } 429 430 /** 431 * Returns the elapsed real-time of this clock since system boot, in nanoseconds. 432 * 433 * <p>The value is only available if {@link #hasElapsedRealtimeNanos()} is 434 * {@code true}. 435 */ getElapsedRealtimeNanos()436 public long getElapsedRealtimeNanos() { 437 return mElapsedRealtimeNanos; 438 } 439 440 /** 441 * Sets the elapsed real-time of this clock since system boot, in nanoseconds. 442 * @hide 443 */ 444 @TestApi setElapsedRealtimeNanos(long elapsedRealtimeNanos)445 public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) { 446 setFlag(HAS_ELAPSED_REALTIME_NANOS); 447 mElapsedRealtimeNanos = elapsedRealtimeNanos; 448 } 449 450 /** 451 * Resets the elapsed real-time of this clock since system boot, in nanoseconds. 452 * @hide 453 */ 454 @TestApi resetElapsedRealtimeNanos()455 public void resetElapsedRealtimeNanos() { 456 resetFlag(HAS_ELAPSED_REALTIME_NANOS); 457 mElapsedRealtimeNanos = 0; 458 } 459 460 /** 461 * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code 462 * false} otherwise. 463 */ hasElapsedRealtimeUncertaintyNanos()464 public boolean hasElapsedRealtimeUncertaintyNanos() { 465 return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); 466 } 467 468 /** 469 * Gets the estimate of the relative precision of the alignment of the 470 * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in 471 * nanoseconds (68% confidence). 472 * 473 * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is 474 * {@code true}. 475 */ 476 @FloatRange(from = 0.0f) getElapsedRealtimeUncertaintyNanos()477 public double getElapsedRealtimeUncertaintyNanos() { 478 return mElapsedRealtimeUncertaintyNanos; 479 } 480 481 /** 482 * Sets the estimate of the relative precision of the alignment of the 483 * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in 484 * nanoseconds (68% confidence). 485 * @hide 486 */ 487 @TestApi setElapsedRealtimeUncertaintyNanos( @loatRangefrom = 0.0f) double elapsedRealtimeUncertaintyNanos)488 public void setElapsedRealtimeUncertaintyNanos( 489 @FloatRange(from = 0.0f) double elapsedRealtimeUncertaintyNanos) { 490 setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); 491 mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos; 492 } 493 494 /** 495 * Resets the estimate of the relative precision of the alignment of the 496 * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in 497 * nanoseconds (68% confidence). 498 * @hide 499 */ 500 @TestApi resetElapsedRealtimeUncertaintyNanos()501 public void resetElapsedRealtimeUncertaintyNanos() { 502 resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS); 503 } 504 505 /** 506 * Returns {@code true} if {@link #getReferenceConstellationTypeForIsb()} is available, 507 * {@code false} otherwise. 508 */ hasReferenceConstellationTypeForIsb()509 public boolean hasReferenceConstellationTypeForIsb() { 510 return isFlagSet(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB); 511 } 512 513 /** 514 * Returns the reference constellation type for inter-signal bias. 515 * 516 * <p>The value is only available if {@link #hasReferenceConstellationTypeForIsb()} is 517 * {@code true}. 518 * 519 * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in 520 * {@link GnssStatus}. 521 */ 522 @GnssStatus.ConstellationType getReferenceConstellationTypeForIsb()523 public int getReferenceConstellationTypeForIsb() { 524 return mReferenceConstellationTypeForIsb; 525 } 526 527 /** 528 * Sets the reference constellation type for inter-signal bias. 529 * @hide 530 */ 531 @TestApi setReferenceConstellationTypeForIsb(@nssStatus.ConstellationType int value)532 public void setReferenceConstellationTypeForIsb(@GnssStatus.ConstellationType int value) { 533 setFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB); 534 mReferenceConstellationTypeForIsb = value; 535 } 536 537 /** 538 * Resets the reference constellation type for inter-signal bias. 539 * @hide 540 */ 541 @TestApi resetReferenceConstellationTypeForIsb()542 public void resetReferenceConstellationTypeForIsb() { 543 resetFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB); 544 mReferenceConstellationTypeForIsb = GnssStatus.CONSTELLATION_UNKNOWN; 545 } 546 547 /** 548 * Returns {@code true} if {@link #getReferenceCarrierFrequencyHzForIsb()} is available, {@code 549 * false} otherwise. 550 */ hasReferenceCarrierFrequencyHzForIsb()551 public boolean hasReferenceCarrierFrequencyHzForIsb() { 552 return isFlagSet(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB); 553 } 554 555 /** 556 * Returns the reference carrier frequency in Hz for inter-signal bias. 557 * 558 * <p>The value is only available if {@link #hasReferenceCarrierFrequencyHzForIsb()} is 559 * {@code true}. 560 */ 561 @FloatRange(from = 0.0) getReferenceCarrierFrequencyHzForIsb()562 public double getReferenceCarrierFrequencyHzForIsb() { 563 return mReferenceCarrierFrequencyHzForIsb; 564 } 565 566 /** 567 * Sets the reference carrier frequency in Hz for inter-signal bias. 568 * @hide 569 */ 570 @TestApi setReferenceCarrierFrequencyHzForIsb(@loatRangefrom = 0.0) double value)571 public void setReferenceCarrierFrequencyHzForIsb(@FloatRange(from = 0.0) double value) { 572 setFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB); 573 mReferenceCarrierFrequencyHzForIsb = value; 574 } 575 576 /** 577 * Resets the reference carrier frequency in Hz for inter-signal bias. 578 * @hide 579 */ 580 @TestApi resetReferenceCarrierFrequencyHzForIsb()581 public void resetReferenceCarrierFrequencyHzForIsb() { 582 resetFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB); 583 } 584 585 /** 586 * Returns {@code true} if {@link #getReferenceCodeTypeForIsb()} is available, {@code 587 * false} otherwise. 588 */ hasReferenceCodeTypeForIsb()589 public boolean hasReferenceCodeTypeForIsb() { 590 return isFlagSet(HAS_REFERENCE_CODE_TYPE_FOR_ISB); 591 } 592 593 /** 594 * Returns the reference code type for inter-signal bias. 595 * 596 * <p>The value is only available if {@link #hasReferenceCodeTypeForIsb()} is 597 * {@code true}. 598 * 599 * <p>The return value is one of those constants defined in 600 * {@link GnssMeasurement#getCodeType()}. 601 */ 602 @NonNull getReferenceCodeTypeForIsb()603 public String getReferenceCodeTypeForIsb() { 604 return mReferenceCodeTypeForIsb; 605 } 606 607 /** 608 * Sets the reference code type for inter-signal bias. 609 * @hide 610 */ 611 @TestApi setReferenceCodeTypeForIsb(@onNull String codeType)612 public void setReferenceCodeTypeForIsb(@NonNull String codeType) { 613 setFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB); 614 mReferenceCodeTypeForIsb = codeType; 615 } 616 617 /** 618 * Resets the reference code type for inter-signal bias. 619 * @hide 620 */ 621 @TestApi resetReferenceCodeTypeForIsb()622 public void resetReferenceCodeTypeForIsb() { 623 resetFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB); 624 mReferenceCodeTypeForIsb = "UNKNOWN"; 625 } 626 627 /** 628 * Gets count of hardware clock discontinuities. 629 * 630 * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it 631 * can be safely assumed that the {@code TimeNanos} value has been derived from a clock that has 632 * been running continuously - e.g. a single continuously powered crystal oscillator, and thus 633 * the {@code (FullBiasNanos + BiasNanos)} offset can be modelled with traditional clock bias 634 * & drift models. 635 * 636 * <p>Each time this value changes, vs. the value in a previously reported {@link GnssClock}, 637 * that suggests the hardware clock may have experienced a discontinuity (e.g. a power cycle or 638 * other anomaly), so that any assumptions about modelling a smoothly changing 639 * {@code (FullBiasNanos + BiasNanos)} offset, and a smoothly growing {@code (TimeNanos)} 640 * between this and the previously reported {@code GnssClock}, should be reset. 641 */ getHardwareClockDiscontinuityCount()642 public int getHardwareClockDiscontinuityCount() { 643 return mHardwareClockDiscontinuityCount; 644 } 645 646 /** 647 * Sets count of last hardware clock discontinuity. 648 * @hide 649 */ 650 @TestApi setHardwareClockDiscontinuityCount(int value)651 public void setHardwareClockDiscontinuityCount(int value) { 652 mHardwareClockDiscontinuityCount = value; 653 } 654 655 public static final @android.annotation.NonNull Creator<GnssClock> CREATOR = new Creator<GnssClock>() { 656 @Override 657 public GnssClock createFromParcel(Parcel parcel) { 658 GnssClock gpsClock = new GnssClock(); 659 660 gpsClock.mFlags = parcel.readInt(); 661 gpsClock.mLeapSecond = parcel.readInt(); 662 gpsClock.mTimeNanos = parcel.readLong(); 663 gpsClock.mTimeUncertaintyNanos = parcel.readDouble(); 664 gpsClock.mFullBiasNanos = parcel.readLong(); 665 gpsClock.mBiasNanos = parcel.readDouble(); 666 gpsClock.mBiasUncertaintyNanos = parcel.readDouble(); 667 gpsClock.mDriftNanosPerSecond = parcel.readDouble(); 668 gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble(); 669 gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt(); 670 gpsClock.mElapsedRealtimeNanos = parcel.readLong(); 671 gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readDouble(); 672 gpsClock.mReferenceConstellationTypeForIsb = parcel.readInt(); 673 gpsClock.mReferenceCarrierFrequencyHzForIsb = parcel.readDouble(); 674 gpsClock.mReferenceCodeTypeForIsb = parcel.readString(); 675 676 return gpsClock; 677 } 678 679 @Override 680 public GnssClock[] newArray(int size) { 681 return new GnssClock[size]; 682 } 683 }; 684 685 @Override writeToParcel(Parcel parcel, int flags)686 public void writeToParcel(Parcel parcel, int flags) { 687 parcel.writeInt(mFlags); 688 parcel.writeInt(mLeapSecond); 689 parcel.writeLong(mTimeNanos); 690 parcel.writeDouble(mTimeUncertaintyNanos); 691 parcel.writeLong(mFullBiasNanos); 692 parcel.writeDouble(mBiasNanos); 693 parcel.writeDouble(mBiasUncertaintyNanos); 694 parcel.writeDouble(mDriftNanosPerSecond); 695 parcel.writeDouble(mDriftUncertaintyNanosPerSecond); 696 parcel.writeInt(mHardwareClockDiscontinuityCount); 697 parcel.writeLong(mElapsedRealtimeNanos); 698 parcel.writeDouble(mElapsedRealtimeUncertaintyNanos); 699 parcel.writeInt(mReferenceConstellationTypeForIsb); 700 parcel.writeDouble(mReferenceCarrierFrequencyHzForIsb); 701 parcel.writeString(mReferenceCodeTypeForIsb); 702 } 703 704 @Override describeContents()705 public int describeContents() { 706 return 0; 707 } 708 709 @Override toString()710 public String toString() { 711 final String format = " %-15s = %s\n"; 712 final String formatWithUncertainty = " %-15s = %-25s %-26s = %s\n"; 713 StringBuilder builder = new StringBuilder("GnssClock:\n"); 714 715 if (hasLeapSecond()) { 716 builder.append(String.format(format, "LeapSecond", mLeapSecond)); 717 } 718 719 builder.append(String.format( 720 formatWithUncertainty, 721 "TimeNanos", 722 mTimeNanos, 723 "TimeUncertaintyNanos", 724 hasTimeUncertaintyNanos() ? mTimeUncertaintyNanos : null)); 725 726 if (hasFullBiasNanos()) { 727 builder.append(String.format(format, "FullBiasNanos", mFullBiasNanos)); 728 } 729 730 if (hasBiasNanos() || hasBiasUncertaintyNanos()) { 731 builder.append(String.format( 732 formatWithUncertainty, 733 "BiasNanos", 734 hasBiasNanos() ? mBiasNanos : null, 735 "BiasUncertaintyNanos", 736 hasBiasUncertaintyNanos() ? mBiasUncertaintyNanos : null)); 737 } 738 739 if (hasDriftNanosPerSecond() || hasDriftUncertaintyNanosPerSecond()) { 740 builder.append(String.format( 741 formatWithUncertainty, 742 "DriftNanosPerSecond", 743 hasDriftNanosPerSecond() ? mDriftNanosPerSecond : null, 744 "DriftUncertaintyNanosPerSecond", 745 hasDriftUncertaintyNanosPerSecond() ? mDriftUncertaintyNanosPerSecond : null)); 746 } 747 748 builder.append(String.format( 749 format, 750 "HardwareClockDiscontinuityCount", 751 mHardwareClockDiscontinuityCount)); 752 753 if (hasElapsedRealtimeNanos() || hasElapsedRealtimeUncertaintyNanos()) { 754 builder.append(String.format( 755 formatWithUncertainty, 756 "ElapsedRealtimeNanos", 757 hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null, 758 "ElapsedRealtimeUncertaintyNanos", 759 hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos 760 : null)); 761 } 762 763 if (hasReferenceConstellationTypeForIsb()) { 764 builder.append(String.format(format, "ReferenceConstellationTypeForIsb", 765 mReferenceConstellationTypeForIsb)); 766 } 767 768 if (hasReferenceCarrierFrequencyHzForIsb()) { 769 builder.append(String.format(format, "ReferenceCarrierFrequencyHzForIsb", 770 mReferenceCarrierFrequencyHzForIsb)); 771 } 772 773 if (hasReferenceCodeTypeForIsb()) { 774 builder.append( 775 String.format(format, "ReferenceCodeTypeForIsb", mReferenceCodeTypeForIsb)); 776 } 777 778 return builder.toString(); 779 } 780 initialize()781 private void initialize() { 782 mFlags = HAS_NO_FLAGS; 783 resetLeapSecond(); 784 setTimeNanos(Long.MIN_VALUE); 785 resetTimeUncertaintyNanos(); 786 resetFullBiasNanos(); 787 resetBiasNanos(); 788 resetBiasUncertaintyNanos(); 789 resetDriftNanosPerSecond(); 790 resetDriftUncertaintyNanosPerSecond(); 791 setHardwareClockDiscontinuityCount(Integer.MIN_VALUE); 792 resetElapsedRealtimeNanos(); 793 resetElapsedRealtimeUncertaintyNanos(); 794 resetReferenceConstellationTypeForIsb(); 795 resetReferenceCarrierFrequencyHzForIsb(); 796 resetReferenceCodeTypeForIsb(); 797 } 798 setFlag(int flag)799 private void setFlag(int flag) { 800 mFlags |= flag; 801 } 802 resetFlag(int flag)803 private void resetFlag(int flag) { 804 mFlags &= ~flag; 805 } 806 isFlagSet(int flag)807 private boolean isFlagSet(int flag) { 808 return (mFlags & flag) == flag; 809 } 810 } 811