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.NonNull; 20 import android.annotation.SystemApi; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 24 /** 25 * A class containing a GPS clock timestamp. 26 * It represents a measurement of the GPS receiver's clock. 27 * 28 * @deprecated use {@link GnssClock} instead. 29 * 30 * @hide 31 */ 32 @Deprecated 33 @SystemApi 34 public class GpsClock implements Parcelable { 35 36 // The following enumerations must be in sync with the values declared in gps.h 37 38 /** 39 * The type of the time stored is not available or it is unknown. 40 */ 41 public static final byte TYPE_UNKNOWN = 0; 42 43 /** 44 * The source of the time value reported by this class is the 'Local Hardware Clock'. 45 */ 46 public static final byte TYPE_LOCAL_HW_TIME = 1; 47 48 /** 49 * The source of the time value reported by this class is the 'GPS time' derived from 50 * satellites (epoch = Jan 6, 1980). 51 */ 52 public static final byte TYPE_GPS_TIME = 2; 53 54 private static final short HAS_NO_FLAGS = 0; 55 private static final short HAS_LEAP_SECOND = (1<<0); 56 private static final short HAS_TIME_UNCERTAINTY = (1<<1); 57 private static final short HAS_FULL_BIAS = (1<<2); 58 private static final short HAS_BIAS = (1<<3); 59 private static final short HAS_BIAS_UNCERTAINTY = (1<<4); 60 private static final short HAS_DRIFT = (1<<5); 61 private static final short HAS_DRIFT_UNCERTAINTY = (1<<6); 62 63 // End enumerations in sync with gps.h 64 65 private short mFlags; 66 private short mLeapSecond; 67 private byte mType; 68 private long mTimeInNs; 69 private double mTimeUncertaintyInNs; 70 private long mFullBiasInNs; 71 private double mBiasInNs; 72 private double mBiasUncertaintyInNs; 73 private double mDriftInNsPerSec; 74 private double mDriftUncertaintyInNsPerSec; 75 GpsClock()76 GpsClock() { 77 initialize(); 78 } 79 80 /** 81 * Sets all contents to the values stored in the provided object. 82 */ set(GpsClock clock)83 public void set(GpsClock clock) { 84 mFlags = clock.mFlags; 85 mLeapSecond = clock.mLeapSecond; 86 mType = clock.mType; 87 mTimeInNs = clock.mTimeInNs; 88 mTimeUncertaintyInNs = clock.mTimeUncertaintyInNs; 89 mFullBiasInNs = clock.mFullBiasInNs; 90 mBiasInNs = clock.mBiasInNs; 91 mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs; 92 mDriftInNsPerSec = clock.mDriftInNsPerSec; 93 mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec; 94 } 95 96 /** 97 * Resets all the contents to its original state. 98 */ reset()99 public void reset() { 100 initialize(); 101 } 102 103 /** 104 * Gets the type of time reported by {@link #getTimeInNs()}. 105 */ getType()106 public byte getType() { 107 return mType; 108 } 109 110 /** 111 * Sets the type of time reported. 112 */ setType(byte value)113 public void setType(byte value) { 114 mType = value; 115 } 116 117 /** 118 * Gets a string representation of the 'type'. 119 * For internal and logging use only. 120 */ getTypeString()121 private String getTypeString() { 122 switch (mType) { 123 case TYPE_UNKNOWN: 124 return "Unknown"; 125 case TYPE_GPS_TIME: 126 return "GpsTime"; 127 case TYPE_LOCAL_HW_TIME: 128 return "LocalHwClock"; 129 default: 130 return "<Invalid:" + mType + ">"; 131 } 132 } 133 134 /** 135 * Returns true if {@link #getLeapSecond()} is available, false otherwise. 136 */ hasLeapSecond()137 public boolean hasLeapSecond() { 138 return isFlagSet(HAS_LEAP_SECOND); 139 } 140 141 /** 142 * Gets the leap second associated with the clock's time. 143 * The sign of the value is defined by the following equation: 144 * utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000 145 * 146 * The value is only available if {@link #hasLeapSecond()} is true. 147 */ getLeapSecond()148 public short getLeapSecond() { 149 return mLeapSecond; 150 } 151 152 /** 153 * Sets the leap second associated with the clock's time. 154 */ setLeapSecond(short leapSecond)155 public void setLeapSecond(short leapSecond) { 156 setFlag(HAS_LEAP_SECOND); 157 mLeapSecond = leapSecond; 158 } 159 160 /** 161 * Resets the leap second associated with the clock's time. 162 */ resetLeapSecond()163 public void resetLeapSecond() { 164 resetFlag(HAS_LEAP_SECOND); 165 mLeapSecond = Short.MIN_VALUE; 166 } 167 168 /** 169 * Gets the GPS receiver internal clock value in nanoseconds. 170 * This can be either the 'local hardware clock' value ({@link #TYPE_LOCAL_HW_TIME}), or the 171 * current GPS time derived inside GPS receiver ({@link #TYPE_GPS_TIME}). 172 * {@link #getType()} defines the time reported. 173 * 174 * For 'local hardware clock' this value is expected to be monotonically increasing during the 175 * reporting session. The real GPS time can be derived by compensating 176 * {@link #getFullBiasInNs()} (when it is available) from this value. 177 * 178 * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS 179 * receiver can achieve. {@link #getTimeUncertaintyInNs()} should be available when GPS time is 180 * specified. 181 * 182 * Sub-nanosecond accuracy can be provided by means of {@link #getBiasInNs()}. 183 * The reported time includes {@link #getTimeUncertaintyInNs()}. 184 */ getTimeInNs()185 public long getTimeInNs() { 186 return mTimeInNs; 187 } 188 189 /** 190 * Sets the GPS receiver internal clock in nanoseconds. 191 */ setTimeInNs(long timeInNs)192 public void setTimeInNs(long timeInNs) { 193 mTimeInNs = timeInNs; 194 } 195 196 /** 197 * Returns true if {@link #getTimeUncertaintyInNs()} is available, false otherwise. 198 */ hasTimeUncertaintyInNs()199 public boolean hasTimeUncertaintyInNs() { 200 return isFlagSet(HAS_TIME_UNCERTAINTY); 201 } 202 203 /** 204 * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds. 205 * The uncertainty is represented as an absolute (single sided) value. 206 * 207 * The value is only available if {@link #hasTimeUncertaintyInNs()} is true. 208 */ getTimeUncertaintyInNs()209 public double getTimeUncertaintyInNs() { 210 return mTimeUncertaintyInNs; 211 } 212 213 /** 214 * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds. 215 */ setTimeUncertaintyInNs(double timeUncertaintyInNs)216 public void setTimeUncertaintyInNs(double timeUncertaintyInNs) { 217 setFlag(HAS_TIME_UNCERTAINTY); 218 mTimeUncertaintyInNs = timeUncertaintyInNs; 219 } 220 221 /** 222 * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds. 223 */ resetTimeUncertaintyInNs()224 public void resetTimeUncertaintyInNs() { 225 resetFlag(HAS_TIME_UNCERTAINTY); 226 mTimeUncertaintyInNs = Double.NaN; 227 } 228 229 /** 230 * Returns true if {@link @getFullBiasInNs()} is available, false otherwise. 231 */ hasFullBiasInNs()232 public boolean hasFullBiasInNs() { 233 return isFlagSet(HAS_FULL_BIAS); 234 } 235 236 /** 237 * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and 238 * the true GPS time since 0000Z, January 6, 1980, in nanoseconds. 239 * 240 * This value is available if {@link #TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved 241 * the clock for GPS time. 242 * {@link #getBiasUncertaintyInNs()} should be used for quality check. 243 * 244 * The sign of the value is defined by the following equation: 245 * true time (GPS time) = time_ns + (full_bias_ns + bias_ns) 246 * 247 * The reported full bias includes {@link #getBiasUncertaintyInNs()}. 248 * The value is onl available if {@link #hasFullBiasInNs()} is true. 249 */ getFullBiasInNs()250 public long getFullBiasInNs() { 251 return mFullBiasInNs; 252 } 253 254 /** 255 * Sets the full bias in nanoseconds. 256 */ setFullBiasInNs(long value)257 public void setFullBiasInNs(long value) { 258 setFlag(HAS_FULL_BIAS); 259 mFullBiasInNs = value; 260 } 261 262 /** 263 * Resets the full bias in nanoseconds. 264 */ resetFullBiasInNs()265 public void resetFullBiasInNs() { 266 resetFlag(HAS_FULL_BIAS); 267 mFullBiasInNs = Long.MIN_VALUE; 268 } 269 270 /** 271 * Returns true if {@link #getBiasInNs()} is available, false otherwise. 272 */ hasBiasInNs()273 public boolean hasBiasInNs() { 274 return isFlagSet(HAS_BIAS); 275 } 276 277 /** 278 * Gets the clock's sub-nanosecond bias. 279 * The reported bias includes {@link #getBiasUncertaintyInNs()}. 280 * 281 * The value is only available if {@link #hasBiasInNs()} is true. 282 */ getBiasInNs()283 public double getBiasInNs() { 284 return mBiasInNs; 285 } 286 287 /** 288 * Sets the sub-nanosecond bias. 289 */ setBiasInNs(double biasInNs)290 public void setBiasInNs(double biasInNs) { 291 setFlag(HAS_BIAS); 292 mBiasInNs = biasInNs; 293 } 294 295 /** 296 * Resets the clock's Bias in nanoseconds. 297 */ resetBiasInNs()298 public void resetBiasInNs() { 299 resetFlag(HAS_BIAS); 300 mBiasInNs = Double.NaN; 301 } 302 303 /** 304 * Returns true if {@link #getBiasUncertaintyInNs()} is available, false otherwise. 305 */ hasBiasUncertaintyInNs()306 public boolean hasBiasUncertaintyInNs() { 307 return isFlagSet(HAS_BIAS_UNCERTAINTY); 308 } 309 310 /** 311 * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 312 * 313 * The value is only available if {@link #hasBiasUncertaintyInNs()} is true. 314 */ getBiasUncertaintyInNs()315 public double getBiasUncertaintyInNs() { 316 return mBiasUncertaintyInNs; 317 } 318 319 /** 320 * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 321 */ setBiasUncertaintyInNs(double biasUncertaintyInNs)322 public void setBiasUncertaintyInNs(double biasUncertaintyInNs) { 323 setFlag(HAS_BIAS_UNCERTAINTY); 324 mBiasUncertaintyInNs = biasUncertaintyInNs; 325 } 326 327 /** 328 * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. 329 */ resetBiasUncertaintyInNs()330 public void resetBiasUncertaintyInNs() { 331 resetFlag(HAS_BIAS_UNCERTAINTY); 332 mBiasUncertaintyInNs = Double.NaN; 333 } 334 335 /** 336 * Returns true if {@link #getDriftInNsPerSec()} is available, false otherwise. 337 */ hasDriftInNsPerSec()338 public boolean hasDriftInNsPerSec() { 339 return isFlagSet(HAS_DRIFT); 340 } 341 342 /** 343 * Gets the clock's Drift in nanoseconds per second. 344 * A positive value indicates that the frequency is higher than the nominal frequency. 345 * The reported drift includes {@link #getDriftUncertaintyInNsPerSec()}. 346 * 347 * The value is only available if {@link #hasDriftInNsPerSec()} is true. 348 */ getDriftInNsPerSec()349 public double getDriftInNsPerSec() { 350 return mDriftInNsPerSec; 351 } 352 353 /** 354 * Sets the clock's Drift in nanoseconds per second. 355 */ setDriftInNsPerSec(double driftInNsPerSec)356 public void setDriftInNsPerSec(double driftInNsPerSec) { 357 setFlag(HAS_DRIFT); 358 mDriftInNsPerSec = driftInNsPerSec; 359 } 360 361 /** 362 * Resets the clock's Drift in nanoseconds per second. 363 */ resetDriftInNsPerSec()364 public void resetDriftInNsPerSec() { 365 resetFlag(HAS_DRIFT); 366 mDriftInNsPerSec = Double.NaN; 367 } 368 369 /** 370 * Returns true if {@link #getDriftUncertaintyInNsPerSec()} is available, false otherwise. 371 */ hasDriftUncertaintyInNsPerSec()372 public boolean hasDriftUncertaintyInNsPerSec() { 373 return isFlagSet(HAS_DRIFT_UNCERTAINTY); 374 } 375 376 /** 377 * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 378 * 379 * The value is only available if {@link #hasDriftUncertaintyInNsPerSec()} is true. 380 */ getDriftUncertaintyInNsPerSec()381 public double getDriftUncertaintyInNsPerSec() { 382 return mDriftUncertaintyInNsPerSec; 383 } 384 385 /** 386 * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 387 */ setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec)388 public void setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec) { 389 setFlag(HAS_DRIFT_UNCERTAINTY); 390 mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec; 391 } 392 393 /** 394 * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. 395 */ resetDriftUncertaintyInNsPerSec()396 public void resetDriftUncertaintyInNsPerSec() { 397 resetFlag(HAS_DRIFT_UNCERTAINTY); 398 mDriftUncertaintyInNsPerSec = Double.NaN; 399 } 400 401 public static final @android.annotation.NonNull Creator<GpsClock> CREATOR = new Creator<GpsClock>() { 402 @Override 403 public GpsClock createFromParcel(Parcel parcel) { 404 GpsClock gpsClock = new GpsClock(); 405 406 gpsClock.mFlags = (short) parcel.readInt(); 407 gpsClock.mLeapSecond = (short) parcel.readInt(); 408 gpsClock.mType = parcel.readByte(); 409 gpsClock.mTimeInNs = parcel.readLong(); 410 gpsClock.mTimeUncertaintyInNs = parcel.readDouble(); 411 gpsClock.mFullBiasInNs = parcel.readLong(); 412 gpsClock.mBiasInNs = parcel.readDouble(); 413 gpsClock.mBiasUncertaintyInNs = parcel.readDouble(); 414 gpsClock.mDriftInNsPerSec = parcel.readDouble(); 415 gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble(); 416 417 return gpsClock; 418 } 419 420 @Override 421 public GpsClock[] newArray(int size) { 422 return new GpsClock[size]; 423 } 424 }; 425 writeToParcel(Parcel parcel, int flags)426 public void writeToParcel(Parcel parcel, int flags) { 427 parcel.writeInt(mFlags); 428 parcel.writeInt(mLeapSecond); 429 parcel.writeByte(mType); 430 parcel.writeLong(mTimeInNs); 431 parcel.writeDouble(mTimeUncertaintyInNs); 432 parcel.writeLong(mFullBiasInNs); 433 parcel.writeDouble(mBiasInNs); 434 parcel.writeDouble(mBiasUncertaintyInNs); 435 parcel.writeDouble(mDriftInNsPerSec); 436 parcel.writeDouble(mDriftUncertaintyInNsPerSec); 437 } 438 439 @Override describeContents()440 public int describeContents() { 441 return 0; 442 } 443 444 @NonNull 445 @Override toString()446 public String toString() { 447 final String format = " %-15s = %s\n"; 448 final String formatWithUncertainty = " %-15s = %-25s %-26s = %s\n"; 449 StringBuilder builder = new StringBuilder("GpsClock:\n"); 450 451 builder.append(String.format(format, "Type", getTypeString())); 452 453 builder.append(String.format(format, "LeapSecond", hasLeapSecond() ? mLeapSecond : null)); 454 455 builder.append(String.format( 456 formatWithUncertainty, 457 "TimeInNs", 458 mTimeInNs, 459 "TimeUncertaintyInNs", 460 hasTimeUncertaintyInNs() ? mTimeUncertaintyInNs : null)); 461 462 builder.append(String.format( 463 format, 464 "FullBiasInNs", 465 hasFullBiasInNs() ? mFullBiasInNs : null)); 466 467 builder.append(String.format( 468 formatWithUncertainty, 469 "BiasInNs", 470 hasBiasInNs() ? mBiasInNs : null, 471 "BiasUncertaintyInNs", 472 hasBiasUncertaintyInNs() ? mBiasUncertaintyInNs : null)); 473 474 builder.append(String.format( 475 formatWithUncertainty, 476 "DriftInNsPerSec", 477 hasDriftInNsPerSec() ? mDriftInNsPerSec : null, 478 "DriftUncertaintyInNsPerSec", 479 hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null)); 480 481 return builder.toString(); 482 } 483 initialize()484 private void initialize() { 485 mFlags = HAS_NO_FLAGS; 486 resetLeapSecond(); 487 setType(TYPE_UNKNOWN); 488 setTimeInNs(Long.MIN_VALUE); 489 resetTimeUncertaintyInNs(); 490 resetFullBiasInNs(); 491 resetBiasInNs(); 492 resetBiasUncertaintyInNs(); 493 resetDriftInNsPerSec(); 494 resetDriftUncertaintyInNsPerSec(); 495 } 496 setFlag(short flag)497 private void setFlag(short flag) { 498 mFlags |= flag; 499 } 500 resetFlag(short flag)501 private void resetFlag(short flag) { 502 mFlags &= ~flag; 503 } 504 isFlagSet(short flag)505 private boolean isFlagSet(short flag) { 506 return (mFlags & flag) == flag; 507 } 508 } 509