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