| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License |
| */ |
| |
| package android.location; |
| |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| /** |
| * A class containing a GPS clock timestamp. |
| * It represents a measurement of the GPS receiver's clock. |
| * |
| * @deprecated use {@link GnssClock} instead. |
| * |
| * @hide |
| */ |
| @Deprecated |
| @SystemApi |
| public class GpsClock implements Parcelable { |
| |
| // The following enumerations must be in sync with the values declared in gps.h |
| |
| /** |
| * The type of the time stored is not available or it is unknown. |
| */ |
| public static final byte TYPE_UNKNOWN = 0; |
| |
| /** |
| * The source of the time value reported by this class is the 'Local Hardware Clock'. |
| */ |
| public static final byte TYPE_LOCAL_HW_TIME = 1; |
| |
| /** |
| * The source of the time value reported by this class is the 'GPS time' derived from |
| * satellites (epoch = Jan 6, 1980). |
| */ |
| public static final byte TYPE_GPS_TIME = 2; |
| |
| private static final short HAS_NO_FLAGS = 0; |
| private static final short HAS_LEAP_SECOND = (1<<0); |
| private static final short HAS_TIME_UNCERTAINTY = (1<<1); |
| private static final short HAS_FULL_BIAS = (1<<2); |
| private static final short HAS_BIAS = (1<<3); |
| private static final short HAS_BIAS_UNCERTAINTY = (1<<4); |
| private static final short HAS_DRIFT = (1<<5); |
| private static final short HAS_DRIFT_UNCERTAINTY = (1<<6); |
| |
| // End enumerations in sync with gps.h |
| |
| private short mFlags; |
| private short mLeapSecond; |
| private byte mType; |
| private long mTimeInNs; |
| private double mTimeUncertaintyInNs; |
| private long mFullBiasInNs; |
| private double mBiasInNs; |
| private double mBiasUncertaintyInNs; |
| private double mDriftInNsPerSec; |
| private double mDriftUncertaintyInNsPerSec; |
| |
| GpsClock() { |
| initialize(); |
| } |
| |
| /** |
| * Sets all contents to the values stored in the provided object. |
| */ |
| public void set(GpsClock clock) { |
| mFlags = clock.mFlags; |
| mLeapSecond = clock.mLeapSecond; |
| mType = clock.mType; |
| mTimeInNs = clock.mTimeInNs; |
| mTimeUncertaintyInNs = clock.mTimeUncertaintyInNs; |
| mFullBiasInNs = clock.mFullBiasInNs; |
| mBiasInNs = clock.mBiasInNs; |
| mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs; |
| mDriftInNsPerSec = clock.mDriftInNsPerSec; |
| mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec; |
| } |
| |
| /** |
| * Resets all the contents to its original state. |
| */ |
| public void reset() { |
| initialize(); |
| } |
| |
| /** |
| * Gets the type of time reported by {@link #getTimeInNs()}. |
| */ |
| public byte getType() { |
| return mType; |
| } |
| |
| /** |
| * Sets the type of time reported. |
| */ |
| public void setType(byte value) { |
| mType = value; |
| } |
| |
| /** |
| * Gets a string representation of the 'type'. |
| * For internal and logging use only. |
| */ |
| private String getTypeString() { |
| switch (mType) { |
| case TYPE_UNKNOWN: |
| return "Unknown"; |
| case TYPE_GPS_TIME: |
| return "GpsTime"; |
| case TYPE_LOCAL_HW_TIME: |
| return "LocalHwClock"; |
| default: |
| return "<Invalid:" + mType + ">"; |
| } |
| } |
| |
| /** |
| * Returns true if {@link #getLeapSecond()} is available, false otherwise. |
| */ |
| public boolean hasLeapSecond() { |
| return isFlagSet(HAS_LEAP_SECOND); |
| } |
| |
| /** |
| * Gets the leap second associated with the clock's time. |
| * The sign of the value is defined by the following equation: |
| * utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000 |
| * |
| * The value is only available if {@link #hasLeapSecond()} is true. |
| */ |
| public short getLeapSecond() { |
| return mLeapSecond; |
| } |
| |
| /** |
| * Sets the leap second associated with the clock's time. |
| */ |
| public void setLeapSecond(short leapSecond) { |
| setFlag(HAS_LEAP_SECOND); |
| mLeapSecond = leapSecond; |
| } |
| |
| /** |
| * Resets the leap second associated with the clock's time. |
| */ |
| public void resetLeapSecond() { |
| resetFlag(HAS_LEAP_SECOND); |
| mLeapSecond = Short.MIN_VALUE; |
| } |
| |
| /** |
| * Gets the GPS receiver internal clock value in nanoseconds. |
| * This can be either the 'local hardware clock' value ({@link #TYPE_LOCAL_HW_TIME}), or the |
| * current GPS time derived inside GPS receiver ({@link #TYPE_GPS_TIME}). |
| * {@link #getType()} defines the time reported. |
| * |
| * For 'local hardware clock' this value is expected to be monotonically increasing during the |
| * reporting session. The real GPS time can be derived by compensating |
| * {@link #getFullBiasInNs()} (when it is available) from this value. |
| * |
| * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS |
| * receiver can achieve. {@link #getTimeUncertaintyInNs()} should be available when GPS time is |
| * specified. |
| * |
| * Sub-nanosecond accuracy can be provided by means of {@link #getBiasInNs()}. |
| * The reported time includes {@link #getTimeUncertaintyInNs()}. |
| */ |
| public long getTimeInNs() { |
| return mTimeInNs; |
| } |
| |
| /** |
| * Sets the GPS receiver internal clock in nanoseconds. |
| */ |
| public void setTimeInNs(long timeInNs) { |
| mTimeInNs = timeInNs; |
| } |
| |
| /** |
| * Returns true if {@link #getTimeUncertaintyInNs()} is available, false otherwise. |
| */ |
| public boolean hasTimeUncertaintyInNs() { |
| return isFlagSet(HAS_TIME_UNCERTAINTY); |
| } |
| |
| /** |
| * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds. |
| * The uncertainty is represented as an absolute (single sided) value. |
| * |
| * The value is only available if {@link #hasTimeUncertaintyInNs()} is true. |
| */ |
| public double getTimeUncertaintyInNs() { |
| return mTimeUncertaintyInNs; |
| } |
| |
| /** |
| * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds. |
| */ |
| public void setTimeUncertaintyInNs(double timeUncertaintyInNs) { |
| setFlag(HAS_TIME_UNCERTAINTY); |
| mTimeUncertaintyInNs = timeUncertaintyInNs; |
| } |
| |
| /** |
| * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds. |
| */ |
| public void resetTimeUncertaintyInNs() { |
| resetFlag(HAS_TIME_UNCERTAINTY); |
| mTimeUncertaintyInNs = Double.NaN; |
| } |
| |
| /** |
| * Returns true if {@link @getFullBiasInNs()} is available, false otherwise. |
| */ |
| public boolean hasFullBiasInNs() { |
| return isFlagSet(HAS_FULL_BIAS); |
| } |
| |
| /** |
| * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and |
| * the true GPS time since 0000Z, January 6, 1980, in nanoseconds. |
| * |
| * This value is available if {@link #TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved |
| * the clock for GPS time. |
| * {@link #getBiasUncertaintyInNs()} should be used for quality check. |
| * |
| * The sign of the value is defined by the following equation: |
| * true time (GPS time) = time_ns + (full_bias_ns + bias_ns) |
| * |
| * The reported full bias includes {@link #getBiasUncertaintyInNs()}. |
| * The value is onl available if {@link #hasFullBiasInNs()} is true. |
| */ |
| public long getFullBiasInNs() { |
| return mFullBiasInNs; |
| } |
| |
| /** |
| * Sets the full bias in nanoseconds. |
| */ |
| public void setFullBiasInNs(long value) { |
| setFlag(HAS_FULL_BIAS); |
| mFullBiasInNs = value; |
| } |
| |
| /** |
| * Resets the full bias in nanoseconds. |
| */ |
| public void resetFullBiasInNs() { |
| resetFlag(HAS_FULL_BIAS); |
| mFullBiasInNs = Long.MIN_VALUE; |
| } |
| |
| /** |
| * Returns true if {@link #getBiasInNs()} is available, false otherwise. |
| */ |
| public boolean hasBiasInNs() { |
| return isFlagSet(HAS_BIAS); |
| } |
| |
| /** |
| * Gets the clock's sub-nanosecond bias. |
| * The reported bias includes {@link #getBiasUncertaintyInNs()}. |
| * |
| * The value is only available if {@link #hasBiasInNs()} is true. |
| */ |
| public double getBiasInNs() { |
| return mBiasInNs; |
| } |
| |
| /** |
| * Sets the sub-nanosecond bias. |
| */ |
| public void setBiasInNs(double biasInNs) { |
| setFlag(HAS_BIAS); |
| mBiasInNs = biasInNs; |
| } |
| |
| /** |
| * Resets the clock's Bias in nanoseconds. |
| */ |
| public void resetBiasInNs() { |
| resetFlag(HAS_BIAS); |
| mBiasInNs = Double.NaN; |
| } |
| |
| /** |
| * Returns true if {@link #getBiasUncertaintyInNs()} is available, false otherwise. |
| */ |
| public boolean hasBiasUncertaintyInNs() { |
| return isFlagSet(HAS_BIAS_UNCERTAINTY); |
| } |
| |
| /** |
| * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. |
| * |
| * The value is only available if {@link #hasBiasUncertaintyInNs()} is true. |
| */ |
| public double getBiasUncertaintyInNs() { |
| return mBiasUncertaintyInNs; |
| } |
| |
| /** |
| * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. |
| */ |
| public void setBiasUncertaintyInNs(double biasUncertaintyInNs) { |
| setFlag(HAS_BIAS_UNCERTAINTY); |
| mBiasUncertaintyInNs = biasUncertaintyInNs; |
| } |
| |
| /** |
| * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. |
| */ |
| public void resetBiasUncertaintyInNs() { |
| resetFlag(HAS_BIAS_UNCERTAINTY); |
| mBiasUncertaintyInNs = Double.NaN; |
| } |
| |
| /** |
| * Returns true if {@link #getDriftInNsPerSec()} is available, false otherwise. |
| */ |
| public boolean hasDriftInNsPerSec() { |
| return isFlagSet(HAS_DRIFT); |
| } |
| |
| /** |
| * Gets the clock's Drift in nanoseconds per second. |
| * A positive value indicates that the frequency is higher than the nominal frequency. |
| * The reported drift includes {@link #getDriftUncertaintyInNsPerSec()}. |
| * |
| * The value is only available if {@link #hasDriftInNsPerSec()} is true. |
| */ |
| public double getDriftInNsPerSec() { |
| return mDriftInNsPerSec; |
| } |
| |
| /** |
| * Sets the clock's Drift in nanoseconds per second. |
| */ |
| public void setDriftInNsPerSec(double driftInNsPerSec) { |
| setFlag(HAS_DRIFT); |
| mDriftInNsPerSec = driftInNsPerSec; |
| } |
| |
| /** |
| * Resets the clock's Drift in nanoseconds per second. |
| */ |
| public void resetDriftInNsPerSec() { |
| resetFlag(HAS_DRIFT); |
| mDriftInNsPerSec = Double.NaN; |
| } |
| |
| /** |
| * Returns true if {@link #getDriftUncertaintyInNsPerSec()} is available, false otherwise. |
| */ |
| public boolean hasDriftUncertaintyInNsPerSec() { |
| return isFlagSet(HAS_DRIFT_UNCERTAINTY); |
| } |
| |
| /** |
| * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. |
| * |
| * The value is only available if {@link #hasDriftUncertaintyInNsPerSec()} is true. |
| */ |
| public double getDriftUncertaintyInNsPerSec() { |
| return mDriftUncertaintyInNsPerSec; |
| } |
| |
| /** |
| * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. |
| */ |
| public void setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec) { |
| setFlag(HAS_DRIFT_UNCERTAINTY); |
| mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec; |
| } |
| |
| /** |
| * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. |
| */ |
| public void resetDriftUncertaintyInNsPerSec() { |
| resetFlag(HAS_DRIFT_UNCERTAINTY); |
| mDriftUncertaintyInNsPerSec = Double.NaN; |
| } |
| |
| public static final @android.annotation.NonNull Creator<GpsClock> CREATOR = new Creator<GpsClock>() { |
| @Override |
| public GpsClock createFromParcel(Parcel parcel) { |
| GpsClock gpsClock = new GpsClock(); |
| |
| gpsClock.mFlags = (short) parcel.readInt(); |
| gpsClock.mLeapSecond = (short) parcel.readInt(); |
| gpsClock.mType = parcel.readByte(); |
| gpsClock.mTimeInNs = parcel.readLong(); |
| gpsClock.mTimeUncertaintyInNs = parcel.readDouble(); |
| gpsClock.mFullBiasInNs = parcel.readLong(); |
| gpsClock.mBiasInNs = parcel.readDouble(); |
| gpsClock.mBiasUncertaintyInNs = parcel.readDouble(); |
| gpsClock.mDriftInNsPerSec = parcel.readDouble(); |
| gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble(); |
| |
| return gpsClock; |
| } |
| |
| @Override |
| public GpsClock[] newArray(int size) { |
| return new GpsClock[size]; |
| } |
| }; |
| |
| public void writeToParcel(Parcel parcel, int flags) { |
| parcel.writeInt(mFlags); |
| parcel.writeInt(mLeapSecond); |
| parcel.writeByte(mType); |
| parcel.writeLong(mTimeInNs); |
| parcel.writeDouble(mTimeUncertaintyInNs); |
| parcel.writeLong(mFullBiasInNs); |
| parcel.writeDouble(mBiasInNs); |
| parcel.writeDouble(mBiasUncertaintyInNs); |
| parcel.writeDouble(mDriftInNsPerSec); |
| parcel.writeDouble(mDriftUncertaintyInNsPerSec); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @NonNull |
| @Override |
| public String toString() { |
| final String format = " %-15s = %s\n"; |
| final String formatWithUncertainty = " %-15s = %-25s %-26s = %s\n"; |
| StringBuilder builder = new StringBuilder("GpsClock:\n"); |
| |
| builder.append(String.format(format, "Type", getTypeString())); |
| |
| builder.append(String.format(format, "LeapSecond", hasLeapSecond() ? mLeapSecond : null)); |
| |
| builder.append(String.format( |
| formatWithUncertainty, |
| "TimeInNs", |
| mTimeInNs, |
| "TimeUncertaintyInNs", |
| hasTimeUncertaintyInNs() ? mTimeUncertaintyInNs : null)); |
| |
| builder.append(String.format( |
| format, |
| "FullBiasInNs", |
| hasFullBiasInNs() ? mFullBiasInNs : null)); |
| |
| builder.append(String.format( |
| formatWithUncertainty, |
| "BiasInNs", |
| hasBiasInNs() ? mBiasInNs : null, |
| "BiasUncertaintyInNs", |
| hasBiasUncertaintyInNs() ? mBiasUncertaintyInNs : null)); |
| |
| builder.append(String.format( |
| formatWithUncertainty, |
| "DriftInNsPerSec", |
| hasDriftInNsPerSec() ? mDriftInNsPerSec : null, |
| "DriftUncertaintyInNsPerSec", |
| hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null)); |
| |
| return builder.toString(); |
| } |
| |
| private void initialize() { |
| mFlags = HAS_NO_FLAGS; |
| resetLeapSecond(); |
| setType(TYPE_UNKNOWN); |
| setTimeInNs(Long.MIN_VALUE); |
| resetTimeUncertaintyInNs(); |
| resetFullBiasInNs(); |
| resetBiasInNs(); |
| resetBiasUncertaintyInNs(); |
| resetDriftInNsPerSec(); |
| resetDriftUncertaintyInNsPerSec(); |
| } |
| |
| private void setFlag(short flag) { |
| mFlags |= flag; |
| } |
| |
| private void resetFlag(short flag) { |
| mFlags &= ~flag; |
| } |
| |
| private boolean isFlagSet(short flag) { |
| return (mFlags & flag) == flag; |
| } |
| } |