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.TestApi;
20 import android.annotation.IntDef;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.lang.annotation.Retention;
25 import java.lang.annotation.RetentionPolicy;
26 
27 /**
28  * A class representing a GNSS satellite measurement, containing raw and computed information.
29  */
30 public final class GnssMeasurement implements Parcelable {
31     private int mFlags;
32     private int mSvid;
33     private int mConstellationType;
34     private double mTimeOffsetNanos;
35     private int mState;
36     private long mReceivedSvTimeNanos;
37     private long mReceivedSvTimeUncertaintyNanos;
38     private double mCn0DbHz;
39     private double mPseudorangeRateMetersPerSecond;
40     private double mPseudorangeRateUncertaintyMetersPerSecond;
41     private int mAccumulatedDeltaRangeState;
42     private double mAccumulatedDeltaRangeMeters;
43     private double mAccumulatedDeltaRangeUncertaintyMeters;
44     private float mCarrierFrequencyHz;
45     private long mCarrierCycles;
46     private double mCarrierPhase;
47     private double mCarrierPhaseUncertainty;
48     private int mMultipathIndicator;
49     private double mSnrInDb;
50     private double mAutomaticGainControlLevelInDb;
51 
52     // The following enumerations must be in sync with the values declared in gps.h
53 
54     private static final int HAS_NO_FLAGS = 0;
55     private static final int HAS_SNR = (1<<0);
56     private static final int HAS_CARRIER_FREQUENCY = (1<<9);
57     private static final int HAS_CARRIER_CYCLES = (1<<10);
58     private static final int HAS_CARRIER_PHASE = (1<<11);
59     private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
60     private static final int HAS_AUTOMATIC_GAIN_CONTROL = (1<<13);
61 
62     /**
63      * The status of the multipath indicator.
64      * @hide
65      */
66     @Retention(RetentionPolicy.SOURCE)
67     @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
68             MULTIPATH_INDICATOR_NOT_DETECTED})
69     public @interface MultipathIndicator {}
70 
71     /**
72      * The indicator is not available or the presence or absence of multipath is unknown.
73      */
74     public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
75 
76     /**
77      * The measurement shows signs of multi-path.
78      */
79     public static final int MULTIPATH_INDICATOR_DETECTED = 1;
80 
81     /**
82      * The measurement shows no signs of multi-path.
83      */
84     public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
85 
86     /**
87      * GNSS measurement tracking loop state
88      * @hide
89      */
90     @IntDef(flag = true, prefix = { "STATE_" }, value = {
91             STATE_CODE_LOCK, STATE_BIT_SYNC, STATE_SUBFRAME_SYNC,
92             STATE_TOW_DECODED, STATE_MSEC_AMBIGUOUS, STATE_SYMBOL_SYNC, STATE_GLO_STRING_SYNC,
93             STATE_GLO_TOD_DECODED, STATE_BDS_D2_BIT_SYNC, STATE_BDS_D2_SUBFRAME_SYNC,
94             STATE_GAL_E1BC_CODE_LOCK, STATE_GAL_E1C_2ND_CODE_LOCK, STATE_GAL_E1B_PAGE_SYNC,
95             STATE_SBAS_SYNC, STATE_TOW_KNOWN, STATE_GLO_TOD_KNOWN
96     })
97     @Retention(RetentionPolicy.SOURCE)
98     public @interface State {}
99 
100     /** This GNSS measurement's tracking state is invalid or unknown. */
101     public static final int STATE_UNKNOWN = 0;
102     /** This GNSS measurement's tracking state has code lock. */
103     public static final int STATE_CODE_LOCK = (1<<0);
104     /** This GNSS measurement's tracking state has bit sync. */
105     public static final int STATE_BIT_SYNC = (1<<1);
106     /** This GNSS measurement's tracking state has sub-frame sync. */
107     public static final int STATE_SUBFRAME_SYNC = (1<<2);
108     /** This GNSS measurement's tracking state has time-of-week decoded. */
109     public static final int STATE_TOW_DECODED = (1<<3);
110     /** This GNSS measurement's tracking state contains millisecond ambiguity. */
111     public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
112     /** This GNSS measurement's tracking state has symbol sync. */
113     public static final int STATE_SYMBOL_SYNC = (1<<5);
114     /** This Glonass measurement's tracking state has string sync. */
115     public static final int STATE_GLO_STRING_SYNC = (1<<6);
116     /** This Glonass measurement's tracking state has time-of-day decoded. */
117     public static final int STATE_GLO_TOD_DECODED = (1<<7);
118     /** This Beidou measurement's tracking state has D2 bit sync. */
119     public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
120     /** This Beidou measurement's tracking state has D2 sub-frame sync. */
121     public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
122     /** This Galileo measurement's tracking state has E1B/C code lock. */
123     public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
124     /** This Galileo measurement's tracking state has E1C secondary code lock. */
125     public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
126     /** This Galileo measurement's tracking state has E1B page sync. */
127     public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
128     /** This SBAS measurement's tracking state has whole second level sync. */
129     public static final int STATE_SBAS_SYNC = (1<<13);
130     /**
131      * This GNSS measurement's tracking state has time-of-week known, possibly not decoded
132      * over the air but has been determined from other sources. If TOW decoded is set then TOW Known
133      * will also be set.
134      */
135     public static final int STATE_TOW_KNOWN = (1<<14);
136     /**
137      * This Glonass measurement's tracking state has time-of-day known, possibly not decoded
138      * over the air but has been determined from other sources. If TOD decoded is set then TOD Known
139      * will also be set.
140      */
141     public static final int STATE_GLO_TOD_KNOWN = (1<<15);
142 
143     /**
144      * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
145      * individual measurement.)
146      */
147     private static final int STATE_ALL = 0x3fff;  // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
148 
149     /**
150      * GNSS measurement accumulated delta range state
151      * @hide
152      */
153     @IntDef(flag = true, prefix = { "ADR_STATE_" }, value = {
154             ADR_STATE_VALID, ADR_STATE_RESET, ADR_STATE_CYCLE_SLIP, ADR_STATE_HALF_CYCLE_RESOLVED,
155             ADR_STATE_HALF_CYCLE_REPORTED
156     })
157     @Retention(RetentionPolicy.SOURCE)
158     public @interface AdrState {}
159 
160     /**
161      * The state of the value {@link #getAccumulatedDeltaRangeMeters()} is invalid or unknown.
162      */
163     public static final int ADR_STATE_UNKNOWN = 0;
164 
165     /**
166      * The state of the {@link #getAccumulatedDeltaRangeMeters()} is valid.
167      */
168     public static final int ADR_STATE_VALID = (1<<0);
169 
170     /**
171      * The state of the {@link #getAccumulatedDeltaRangeMeters()} has detected a reset.
172      */
173     public static final int ADR_STATE_RESET = (1<<1);
174 
175     /**
176      * The state of the {@link #getAccumulatedDeltaRangeMeters()} has a cycle slip detected.
177      */
178     public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
179 
180     /**
181      * Reports whether the value {@link #getAccumulatedDeltaRangeMeters()} has resolved the half
182      * cycle ambiguity.
183      *
184      * <p> When this bit is set, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
185      * carrier phase measurement plus an accumulated integer number of carrier full cycles.
186      *
187      * <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
188      * carrier phase measurement plus an accumulated integer number of carrier half cycles.
189      */
190     public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
191 
192     /**
193      * Reports whether the flag {@link #ADR_STATE_HALF_CYCLE_RESOLVED} has been reported by the
194      * GNSS hardware.
195      *
196      * <p> When this bit is set, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
197      * can be low (centimeter level) whether or not the half cycle ambiguity is resolved.
198      *
199      * <p> When this bit is unset, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
200      * is larger, to cover the potential error due to half cycle ambiguity being unresolved.
201      */
202     public static final int ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
203 
204     /**
205      * All the 'Accumulated Delta Range' flags.
206      * @hide
207      */
208     @TestApi
209     public static final int ADR_STATE_ALL =
210             ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP |
211             ADR_STATE_HALF_CYCLE_RESOLVED | ADR_STATE_HALF_CYCLE_REPORTED;
212 
213     // End enumerations in sync with gps.h
214 
215     /**
216      * @hide
217      */
218     @TestApi
GnssMeasurement()219     public GnssMeasurement() {
220         initialize();
221     }
222 
223     /**
224      * Sets all contents to the values stored in the provided object.
225      * @hide
226      */
227     @TestApi
set(GnssMeasurement measurement)228     public void set(GnssMeasurement measurement) {
229         mFlags = measurement.mFlags;
230         mSvid = measurement.mSvid;
231         mConstellationType = measurement.mConstellationType;
232         mTimeOffsetNanos = measurement.mTimeOffsetNanos;
233         mState = measurement.mState;
234         mReceivedSvTimeNanos = measurement.mReceivedSvTimeNanos;
235         mReceivedSvTimeUncertaintyNanos = measurement.mReceivedSvTimeUncertaintyNanos;
236         mCn0DbHz = measurement.mCn0DbHz;
237         mPseudorangeRateMetersPerSecond = measurement.mPseudorangeRateMetersPerSecond;
238         mPseudorangeRateUncertaintyMetersPerSecond =
239                 measurement.mPseudorangeRateUncertaintyMetersPerSecond;
240         mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
241         mAccumulatedDeltaRangeMeters = measurement.mAccumulatedDeltaRangeMeters;
242         mAccumulatedDeltaRangeUncertaintyMeters =
243                 measurement.mAccumulatedDeltaRangeUncertaintyMeters;
244         mCarrierFrequencyHz = measurement.mCarrierFrequencyHz;
245         mCarrierCycles = measurement.mCarrierCycles;
246         mCarrierPhase = measurement.mCarrierPhase;
247         mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
248         mMultipathIndicator = measurement.mMultipathIndicator;
249         mSnrInDb = measurement.mSnrInDb;
250         mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
251     }
252 
253     /**
254      * Resets all the contents to its original state.
255      * @hide
256      */
257     @TestApi
reset()258     public void reset() {
259         initialize();
260     }
261 
262     /**
263      * Gets the satellite ID.
264      *
265      * <p>Interpretation depends on {@link #getConstellationType()}.
266      * See {@link GnssStatus#getSvid(int)}.
267      */
getSvid()268     public int getSvid() {
269         return mSvid;
270     }
271 
272     /**
273      * Sets the Satellite ID.
274      * @hide
275      */
276     @TestApi
setSvid(int value)277     public void setSvid(int value) {
278         mSvid = value;
279     }
280 
281     /**
282      * Gets the constellation type.
283      *
284      * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
285      * {@link GnssStatus}.
286      */
287     @GnssStatus.ConstellationType
getConstellationType()288     public int getConstellationType() {
289         return mConstellationType;
290     }
291 
292     /**
293      * Sets the constellation type.
294      * @hide
295      */
296     @TestApi
setConstellationType(@nssStatus.ConstellationType int value)297     public void setConstellationType(@GnssStatus.ConstellationType int value) {
298         mConstellationType = value;
299     }
300 
301     /**
302      * Gets the time offset at which the measurement was taken in nanoseconds.
303      *
304      * <p>The reference receiver's time from which this is offset is specified by
305      * {@link GnssClock#getTimeNanos()}.
306      *
307      * <p>The sign of this value is given by the following equation:
308      * <pre>
309      *      measurement time = TimeNanos + TimeOffsetNanos</pre>
310      *
311      * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
312      * accuracy.
313      */
getTimeOffsetNanos()314     public double getTimeOffsetNanos() {
315         return mTimeOffsetNanos;
316     }
317 
318     /**
319      * Sets the time offset at which the measurement was taken in nanoseconds.
320      * @hide
321      */
322     @TestApi
setTimeOffsetNanos(double value)323     public void setTimeOffsetNanos(double value) {
324         mTimeOffsetNanos = value;
325     }
326 
327     /**
328      * Gets per-satellite sync state.
329      *
330      * <p>It represents the current sync state for the associated satellite.
331      *
332      * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
333      */
334     @State
getState()335     public int getState() {
336         return mState;
337     }
338 
339     /**
340      * Sets the sync state.
341      * @hide
342      */
343     @TestApi
setState(@tate int value)344     public void setState(@State int value) {
345         mState = value;
346     }
347 
348     /**
349      * Gets a string representation of the 'sync state'.
350      *
351      * <p>For internal and logging use only.
352      */
getStateString()353     private String getStateString() {
354         if (mState == STATE_UNKNOWN) {
355             return "Unknown";
356         }
357 
358         StringBuilder builder = new StringBuilder();
359         if ((mState & STATE_CODE_LOCK) != 0) {
360             builder.append("CodeLock|");
361         }
362         if ((mState & STATE_BIT_SYNC) != 0) {
363             builder.append("BitSync|");
364         }
365         if ((mState & STATE_SUBFRAME_SYNC) != 0) {
366             builder.append("SubframeSync|");
367         }
368         if ((mState & STATE_TOW_DECODED) != 0) {
369             builder.append("TowDecoded|");
370         }
371         if ((mState & STATE_TOW_KNOWN) != 0) {
372           builder.append("TowKnown|");
373         }
374         if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
375             builder.append("MsecAmbiguous|");
376         }
377         if ((mState & STATE_SYMBOL_SYNC) != 0) {
378             builder.append("SymbolSync|");
379         }
380         if ((mState & STATE_GLO_STRING_SYNC) != 0) {
381             builder.append("GloStringSync|");
382         }
383         if ((mState & STATE_GLO_TOD_DECODED) != 0) {
384             builder.append("GloTodDecoded|");
385         }
386         if ((mState & STATE_GLO_TOD_KNOWN) != 0) {
387           builder.append("GloTodKnown|");
388         }
389         if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
390             builder.append("BdsD2BitSync|");
391         }
392         if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
393             builder.append("BdsD2SubframeSync|");
394         }
395         if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
396             builder.append("GalE1bcCodeLock|");
397         }
398         if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
399             builder.append("E1c2ndCodeLock|");
400         }
401         if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
402             builder.append("GalE1bPageSync|");
403         }
404         if ((mState & STATE_SBAS_SYNC) != 0) {
405             builder.append("SbasSync|");
406         }
407 
408         int remainingStates = mState & ~STATE_ALL;
409         if (remainingStates > 0) {
410             builder.append("Other(");
411             builder.append(Integer.toBinaryString(remainingStates));
412             builder.append(")|");
413         }
414         builder.setLength(builder.length() - 1);
415         return builder.toString();
416     }
417 
418     /**
419      * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
420      *
421      * <p>For GPS &amp; QZSS, this is:
422      * <ul>
423      * <li>Received GPS Time-of-Week at the measurement time, in nanoseconds.</li>
424      * <li>The value is relative to the beginning of the current GPS week.</li>
425      * </ul>
426      *
427      * <p>Given the highest sync state that can be achieved, per each satellite, valid range
428      * for this field can be:
429      * <pre>
430      *     Searching       : [ 0       ]   : STATE_UNKNOWN
431      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
432      *     Bit sync        : [ 0  20ms ]   : STATE_BIT_SYNC is set
433      *     Subframe sync   : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
434      *     TOW decoded     : [ 0 1week ]   : STATE_TOW_DECODED is set
435      *     TOW Known       : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
436      *
437      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
438      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
439      *
440      * <p>Note well: if there is any ambiguity in integer millisecond, {@code STATE_MSEC_AMBIGUOUS}
441      * must be set accordingly, in the 'state' field.
442      *
443      * <p>This value must be populated if 'state' != {@code STATE_UNKNOWN}.
444      *
445      * <p>For Glonass, this is:
446      * <ul>
447      * <li>Received Glonass time of day, at the measurement time in nanoseconds.</li>
448      * </ul>
449      *
450      * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
451      * this field can be:
452      * <pre>
453      *     Searching           : [ 0       ]   : STATE_UNKNOWN
454      *     C/A code lock       : [ 0   1ms ]   : STATE_CODE_LOCK is set
455      *     Symbol sync         : [ 0  10ms ]   : STATE_SYMBOL_SYNC is set
456      *     Bit sync            : [ 0  20ms ]   : STATE_BIT_SYNC is set
457      *     String sync         : [ 0    2s ]   : STATE_GLO_STRING_SYNC is set
458      *     Time of day decoded : [ 0  1day ]   : STATE_GLO_TOD_DECODED is set
459      *     Time of day known   : [ 0  1day ]   : STATE_GLO_TOD_KNOWN set</pre>
460      *
461      * Note: Time of day known refers to the case where it is possibly not decoded over the air but
462      * has been determined from other sources. If Time of day decoded is set then Time of day known
463      * must also be set.
464      *
465      * <p>For Beidou, this is:
466      * <ul>
467      * <li>Received Beidou time of week, at the measurement time in nanoseconds.</li>
468      * </ul>
469      *
470      * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
471      * this field can be:
472      * <pre>
473      *     Searching              : [ 0       ]   : STATE_UNKNOWN
474      *     C/A code lock          : [ 0   1ms ]   : STATE_CODE_LOCK is set
475      *     Bit sync (D2)          : [ 0   2ms ]   : STATE_BDS_D2_BIT_SYNC is set
476      *     Bit sync (D1)          : [ 0  20ms ]   : STATE_BIT_SYNC is set
477      *     Subframe (D2)          : [ 0  0.6s ]   : STATE_BDS_D2_SUBFRAME_SYNC is set
478      *     Subframe (D1)          : [ 0    6s ]   : STATE_SUBFRAME_SYNC is set
479      *     Time of week decoded   : [ 0 1week ]   : STATE_TOW_DECODED is set
480      *     Time of week known     : [ 0 1week ]   : STATE_TOW_KNOWN set</pre>
481      *
482      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
483      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
484      *
485      * <p>For Galileo, this is:
486      * <ul>
487      * <li>Received Galileo time of week, at the measurement time in nanoseconds.</li>
488      * </ul>
489      * <pre>
490      *     E1BC code lock       : [ 0   4ms ]  : STATE_GAL_E1BC_CODE_LOCK is set
491      *     E1C 2nd code lock    : [ 0 100ms ]  : STATE_GAL_E1C_2ND_CODE_LOCK is set
492      *     E1B page             : [ 0    2s ]  : STATE_GAL_E1B_PAGE_SYNC is set
493      *     Time of week decoded : [ 0 1week ]  : STATE_TOW_DECODED is set
494      *     Time of week known   : [ 0 1week ]  : STATE_TOW_KNOWN set</pre>
495      *
496      * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
497      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
498      *
499      * <p>For SBAS, this is:
500      * <ul>
501      * <li>Received SBAS time, at the measurement time in nanoseconds.</li>
502      * </ul>
503      *
504      * <p>Given the highest sync state that can be achieved, per each satellite, valid range for
505      * this field can be:
506      * <pre>
507      *     Searching       : [ 0       ]   : STATE_UNKNOWN
508      *     C/A code lock   : [ 0   1ms ]   : STATE_CODE_LOCK is set
509      *     Symbol sync     : [ 0   2ms ]   : STATE_SYMBOL_SYNC is set
510      *     Message         : [ 0    1s ]   : STATE_SBAS_SYNC is set</pre>
511      */
getReceivedSvTimeNanos()512     public long getReceivedSvTimeNanos() {
513         return mReceivedSvTimeNanos;
514     }
515 
516     /**
517      * Sets the received GNSS time in nanoseconds.
518      * @hide
519      */
520     @TestApi
setReceivedSvTimeNanos(long value)521     public void setReceivedSvTimeNanos(long value) {
522         mReceivedSvTimeNanos = value;
523     }
524 
525     /**
526      * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
527      */
getReceivedSvTimeUncertaintyNanos()528     public long getReceivedSvTimeUncertaintyNanos() {
529         return mReceivedSvTimeUncertaintyNanos;
530     }
531 
532     /**
533      * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
534      * @hide
535      */
536     @TestApi
setReceivedSvTimeUncertaintyNanos(long value)537     public void setReceivedSvTimeUncertaintyNanos(long value) {
538         mReceivedSvTimeUncertaintyNanos = value;
539     }
540 
541     /**
542      * Gets the Carrier-to-noise density in dB-Hz.
543      *
544      * <p>Typical range: 10-50 db-Hz.
545      *
546      * <p>The value contains the measured C/N0 for the signal at the antenna input.
547      */
getCn0DbHz()548     public double getCn0DbHz() {
549         return mCn0DbHz;
550     }
551 
552     /**
553      * Sets the carrier-to-noise density in dB-Hz.
554      * @hide
555      */
556     @TestApi
setCn0DbHz(double value)557     public void setCn0DbHz(double value) {
558         mCn0DbHz = value;
559     }
560 
561     /**
562      * Gets the Pseudorange rate at the timestamp in m/s.
563      *
564      * <p>The error estimate for this value is
565      * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
566      *
567      * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
568      * errors are not included.
569      *
570      * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
571      * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
572      * is given by the equation:
573      *
574      * <pre>
575      *      pseudorange rate = -k * doppler shift   (where k is a constant)</pre>
576      */
getPseudorangeRateMetersPerSecond()577     public double getPseudorangeRateMetersPerSecond() {
578         return mPseudorangeRateMetersPerSecond;
579     }
580 
581     /**
582      * Sets the pseudorange rate at the timestamp in m/s.
583      * @hide
584      */
585     @TestApi
setPseudorangeRateMetersPerSecond(double value)586     public void setPseudorangeRateMetersPerSecond(double value) {
587         mPseudorangeRateMetersPerSecond = value;
588     }
589 
590     /**
591      * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
592      *
593      * <p>The uncertainty is represented as an absolute (single sided) value.
594      */
getPseudorangeRateUncertaintyMetersPerSecond()595     public double getPseudorangeRateUncertaintyMetersPerSecond() {
596         return mPseudorangeRateUncertaintyMetersPerSecond;
597     }
598 
599     /**
600      * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
601      * @hide
602      */
603     @TestApi
setPseudorangeRateUncertaintyMetersPerSecond(double value)604     public void setPseudorangeRateUncertaintyMetersPerSecond(double value) {
605         mPseudorangeRateUncertaintyMetersPerSecond = value;
606     }
607 
608     /**
609      * Gets 'Accumulated Delta Range' state.
610      *
611      * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
612      * cycle slip (indicating 'loss of lock').
613      */
614     @AdrState
getAccumulatedDeltaRangeState()615     public int getAccumulatedDeltaRangeState() {
616         return mAccumulatedDeltaRangeState;
617     }
618 
619     /**
620      * Sets the 'Accumulated Delta Range' state.
621      * @hide
622      */
623     @TestApi
setAccumulatedDeltaRangeState(@drState int value)624     public void setAccumulatedDeltaRangeState(@AdrState int value) {
625         mAccumulatedDeltaRangeState = value;
626     }
627 
628     /**
629      * Gets a string representation of the 'Accumulated Delta Range state'.
630      *
631      * <p>For internal and logging use only.
632      */
getAccumulatedDeltaRangeStateString()633     private String getAccumulatedDeltaRangeStateString() {
634         if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
635             return "Unknown";
636         }
637         StringBuilder builder = new StringBuilder();
638         if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
639             builder.append("Valid|");
640         }
641         if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
642             builder.append("Reset|");
643         }
644         if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
645             builder.append("CycleSlip|");
646         }
647         if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_RESOLVED) ==
648                 ADR_STATE_HALF_CYCLE_RESOLVED) {
649             builder.append("HalfCycleResolved|");
650         }
651         if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_REPORTED)
652                 == ADR_STATE_HALF_CYCLE_REPORTED) {
653             builder.append("HalfCycleReported|");
654         }
655         int remainingStates = mAccumulatedDeltaRangeState & ~ADR_STATE_ALL;
656         if (remainingStates > 0) {
657             builder.append("Other(");
658             builder.append(Integer.toBinaryString(remainingStates));
659             builder.append(")|");
660         }
661         builder.deleteCharAt(builder.length() - 1);
662         return builder.toString();
663     }
664 
665     /**
666      * Gets the accumulated delta range since the last channel reset, in meters.
667      *
668      * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
669      *
670      * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
671      *
672      * <p>A positive value indicates that the SV is moving away from the receiver.
673      * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
674      * {@link #getCarrierPhase()} is given by the equation:
675      *
676      * <pre>
677      *          accumulated delta range = -k * carrier phase    (where k is a constant)</pre>
678      *
679      * <p>Similar to the concept of an RTCM "Phaserange", when the accumulated delta range is
680      * initially chosen, and whenever it is reset, it will retain the integer nature
681      * of the relative carrier phase offset between satellites observed by this receiver, such that
682      * the double difference of this value between receivers and satellites may be used, together
683      * with integer ambiguity resolution, to determine highly precise relative location between
684      * receivers.
685      *
686      * <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
687      * reported as {@link #ADR_STATE_VALID}.
688      */
getAccumulatedDeltaRangeMeters()689     public double getAccumulatedDeltaRangeMeters() {
690         return mAccumulatedDeltaRangeMeters;
691     }
692 
693     /**
694      * Sets the accumulated delta range in meters.
695      * @hide
696      */
697     @TestApi
setAccumulatedDeltaRangeMeters(double value)698     public void setAccumulatedDeltaRangeMeters(double value) {
699         mAccumulatedDeltaRangeMeters = value;
700     }
701 
702     /**
703      * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
704      *
705      * <p>The uncertainty is represented as an absolute (single sided) value.
706      *
707      * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
708      */
getAccumulatedDeltaRangeUncertaintyMeters()709     public double getAccumulatedDeltaRangeUncertaintyMeters() {
710         return mAccumulatedDeltaRangeUncertaintyMeters;
711     }
712 
713     /**
714      * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
715      *
716      * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
717      *
718      * @hide
719      */
720     @TestApi
setAccumulatedDeltaRangeUncertaintyMeters(double value)721     public void setAccumulatedDeltaRangeUncertaintyMeters(double value) {
722         mAccumulatedDeltaRangeUncertaintyMeters = value;
723     }
724 
725     /**
726      * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
727      * otherwise.
728      */
hasCarrierFrequencyHz()729     public boolean hasCarrierFrequencyHz() {
730         return isFlagSet(HAS_CARRIER_FREQUENCY);
731     }
732 
733     /**
734      * Gets the carrier frequency of the tracked signal.
735      *
736      * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
737      * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
738      * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
739      *
740      * <p> For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
741      * measurement objects will be reported for this same satellite, in one of the measurement
742      * objects, all the values related to L1 will be filled, and in the other all of the values
743      * related to L5 will be filled.
744      *
745      * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
746      *
747      * @return the carrier frequency of the signal tracked in Hz.
748      */
getCarrierFrequencyHz()749     public float getCarrierFrequencyHz() {
750         return mCarrierFrequencyHz;
751     }
752 
753     /**
754      * Sets the Carrier frequency in Hz.
755      * @hide
756      */
757     @TestApi
setCarrierFrequencyHz(float carrierFrequencyHz)758     public void setCarrierFrequencyHz(float carrierFrequencyHz) {
759         setFlag(HAS_CARRIER_FREQUENCY);
760         mCarrierFrequencyHz = carrierFrequencyHz;
761     }
762 
763     /**
764      * Resets the Carrier frequency in Hz.
765      * @hide
766      */
767     @TestApi
resetCarrierFrequencyHz()768     public void resetCarrierFrequencyHz() {
769         resetFlag(HAS_CARRIER_FREQUENCY);
770         mCarrierFrequencyHz = Float.NaN;
771     }
772 
773     /**
774      * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
775      *
776      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
777      */
778     @Deprecated
hasCarrierCycles()779     public boolean hasCarrierCycles() {
780         return isFlagSet(HAS_CARRIER_CYCLES);
781     }
782 
783     /**
784      * The number of full carrier cycles between the satellite and the receiver.
785      *
786      * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
787      *
788      * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
789      *
790      * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
791      */
792     @Deprecated
getCarrierCycles()793     public long getCarrierCycles() {
794         return mCarrierCycles;
795     }
796 
797     /**
798      * Sets the number of full carrier cycles between the satellite and the receiver.
799      *
800      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
801      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
802      *
803      * @hide
804      */
805     @TestApi
806     @Deprecated
setCarrierCycles(long value)807     public void setCarrierCycles(long value) {
808         setFlag(HAS_CARRIER_CYCLES);
809         mCarrierCycles = value;
810     }
811 
812     /**
813      * Resets the number of full carrier cycles between the satellite and the receiver.
814      *
815      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
816      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
817      * @hide
818      */
819     @TestApi
820     @Deprecated
resetCarrierCycles()821     public void resetCarrierCycles() {
822         resetFlag(HAS_CARRIER_CYCLES);
823         mCarrierCycles = Long.MIN_VALUE;
824     }
825 
826     /**
827      * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
828      *
829      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
830      */
831     @Deprecated
hasCarrierPhase()832     public boolean hasCarrierPhase() {
833         return isFlagSet(HAS_CARRIER_PHASE);
834     }
835 
836     /**
837      * Gets the RF phase detected by the receiver.
838      *
839      * <p>Range: [0.0, 1.0].
840      *
841      * <p>This is the fractional part of the complete carrier phase measurement.
842      *
843      * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
844      *
845      * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
846      *
847      * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
848      *
849      * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
850      */
851     @Deprecated
getCarrierPhase()852     public double getCarrierPhase() {
853         return mCarrierPhase;
854     }
855 
856     /**
857      * Sets the RF phase detected by the receiver.
858      *
859      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
860      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
861      *
862      * @hide
863      */
864     @TestApi
865     @Deprecated
setCarrierPhase(double value)866     public void setCarrierPhase(double value) {
867         setFlag(HAS_CARRIER_PHASE);
868         mCarrierPhase = value;
869     }
870 
871     /**
872      * Resets the RF phase detected by the receiver.
873      *
874      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
875      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
876      *
877      * @hide
878      */
879     @TestApi
880     @Deprecated
resetCarrierPhase()881     public void resetCarrierPhase() {
882         resetFlag(HAS_CARRIER_PHASE);
883         mCarrierPhase = Double.NaN;
884     }
885 
886     /**
887      * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
888      * otherwise.
889      *
890      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
891      */
892     @Deprecated
hasCarrierPhaseUncertainty()893     public boolean hasCarrierPhaseUncertainty() {
894         return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
895     }
896 
897     /**
898      * Gets the carrier-phase's uncertainty (1-Sigma).
899      *
900      * <p>The uncertainty is represented as an absolute (single sided) value.
901      *
902      * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
903      *
904      * @deprecated use {@link #getAccumulatedDeltaRangeUncertaintyMeters()} instead.
905      */
906     @Deprecated
getCarrierPhaseUncertainty()907     public double getCarrierPhaseUncertainty() {
908         return mCarrierPhaseUncertainty;
909     }
910 
911     /**
912      * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
913      *
914      * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
915      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
916      *
917      * @hide
918      */
919     @TestApi
920     @Deprecated
setCarrierPhaseUncertainty(double value)921     public void setCarrierPhaseUncertainty(double value) {
922         setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
923         mCarrierPhaseUncertainty = value;
924     }
925 
926     /**
927      * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
928      *
929      * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
930      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
931      *
932      * @hide
933      */
934     @TestApi
935     @Deprecated
resetCarrierPhaseUncertainty()936     public void resetCarrierPhaseUncertainty() {
937         resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
938         mCarrierPhaseUncertainty = Double.NaN;
939     }
940 
941     /**
942      * Gets a value indicating the 'multipath' state of the event.
943      */
944     @MultipathIndicator
getMultipathIndicator()945     public int getMultipathIndicator() {
946         return mMultipathIndicator;
947     }
948 
949     /**
950      * Sets the 'multi-path' indicator.
951      * @hide
952      */
953     @TestApi
setMultipathIndicator(@ultipathIndicator int value)954     public void setMultipathIndicator(@MultipathIndicator int value) {
955         mMultipathIndicator = value;
956     }
957 
958     /**
959      * Gets a string representation of the 'multi-path indicator'.
960      *
961      * <p>For internal and logging use only.
962      */
getMultipathIndicatorString()963     private String getMultipathIndicatorString() {
964         switch(mMultipathIndicator) {
965             case MULTIPATH_INDICATOR_UNKNOWN:
966                 return "Unknown";
967             case MULTIPATH_INDICATOR_DETECTED:
968                 return "Detected";
969             case MULTIPATH_INDICATOR_NOT_DETECTED:
970                 return "NotDetected";
971             default:
972                 return "<Invalid: " + mMultipathIndicator + ">";
973         }
974     }
975 
976     /**
977      * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
978      */
hasSnrInDb()979     public boolean hasSnrInDb() {
980         return isFlagSet(HAS_SNR);
981     }
982 
983     /**
984      * Gets the (post-correlation & integration) Signal-to-Noise ratio (SNR) in dB.
985      *
986      * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
987      */
getSnrInDb()988     public double getSnrInDb() {
989         return mSnrInDb;
990     }
991 
992     /**
993      * Sets the Signal-to-noise ratio (SNR) in dB.
994      * @hide
995      */
996     @TestApi
setSnrInDb(double snrInDb)997     public void setSnrInDb(double snrInDb) {
998         setFlag(HAS_SNR);
999         mSnrInDb = snrInDb;
1000     }
1001 
1002     /**
1003      * Resets the Signal-to-noise ratio (SNR) in dB.
1004      * @hide
1005      */
1006     @TestApi
resetSnrInDb()1007     public void resetSnrInDb() {
1008         resetFlag(HAS_SNR);
1009         mSnrInDb = Double.NaN;
1010     }
1011 
1012     /**
1013      * Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
1014      * {@code false} otherwise.
1015      */
hasAutomaticGainControlLevelDb()1016     public boolean hasAutomaticGainControlLevelDb() {
1017         return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
1018     }
1019 
1020     /**
1021      * Gets the Automatic Gain Control level in dB.
1022      *
1023      * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal. The AGC
1024      * level may be used to indicate potential interference. When AGC is at a nominal level, this
1025      * value must be set as 0. Higher gain (and/or lower input power) shall be output as a positive
1026      * number. Hence in cases of strong jamming, in the band of this signal, this value will go more
1027      * negative.
1028      *
1029      * <p> Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
1030      * components) may also affect the typical output of of this value on any given hardware design
1031      * in an open sky test - the important aspect of this output is that changes in this value are
1032      * indicative of changes on input signal power in the frequency band for this measurement.
1033      *
1034      * <p> The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
1035      */
getAutomaticGainControlLevelDb()1036     public double getAutomaticGainControlLevelDb() {
1037         return mAutomaticGainControlLevelInDb;
1038     }
1039 
1040     /**
1041      * Sets the Automatic Gain Control level in dB.
1042      * @hide
1043      */
1044     @TestApi
setAutomaticGainControlLevelInDb(double agcLevelDb)1045     public void setAutomaticGainControlLevelInDb(double agcLevelDb) {
1046         setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
1047         mAutomaticGainControlLevelInDb = agcLevelDb;
1048     }
1049 
1050     /**
1051      * Resets the Automatic Gain Control level.
1052      * @hide
1053      */
1054     @TestApi
resetAutomaticGainControlLevel()1055     public void resetAutomaticGainControlLevel() {
1056         resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
1057         mAutomaticGainControlLevelInDb = Double.NaN;
1058     }
1059 
1060     public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
1061         @Override
1062         public GnssMeasurement createFromParcel(Parcel parcel) {
1063             GnssMeasurement gnssMeasurement = new GnssMeasurement();
1064 
1065             gnssMeasurement.mFlags = parcel.readInt();
1066             gnssMeasurement.mSvid = parcel.readInt();
1067             gnssMeasurement.mConstellationType = parcel.readInt();
1068             gnssMeasurement.mTimeOffsetNanos = parcel.readDouble();
1069             gnssMeasurement.mState = parcel.readInt();
1070             gnssMeasurement.mReceivedSvTimeNanos = parcel.readLong();
1071             gnssMeasurement.mReceivedSvTimeUncertaintyNanos = parcel.readLong();
1072             gnssMeasurement.mCn0DbHz = parcel.readDouble();
1073             gnssMeasurement.mPseudorangeRateMetersPerSecond = parcel.readDouble();
1074             gnssMeasurement.mPseudorangeRateUncertaintyMetersPerSecond = parcel.readDouble();
1075             gnssMeasurement.mAccumulatedDeltaRangeState = parcel.readInt();
1076             gnssMeasurement.mAccumulatedDeltaRangeMeters = parcel.readDouble();
1077             gnssMeasurement.mAccumulatedDeltaRangeUncertaintyMeters = parcel.readDouble();
1078             gnssMeasurement.mCarrierFrequencyHz = parcel.readFloat();
1079             gnssMeasurement.mCarrierCycles = parcel.readLong();
1080             gnssMeasurement.mCarrierPhase = parcel.readDouble();
1081             gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
1082             gnssMeasurement.mMultipathIndicator = parcel.readInt();
1083             gnssMeasurement.mSnrInDb = parcel.readDouble();
1084             gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
1085 
1086             return gnssMeasurement;
1087         }
1088 
1089         @Override
1090         public GnssMeasurement[] newArray(int i) {
1091             return new GnssMeasurement[i];
1092         }
1093     };
1094 
1095     @Override
writeToParcel(Parcel parcel, int flags)1096     public void writeToParcel(Parcel parcel, int flags) {
1097         parcel.writeInt(mFlags);
1098         parcel.writeInt(mSvid);
1099         parcel.writeInt(mConstellationType);
1100         parcel.writeDouble(mTimeOffsetNanos);
1101         parcel.writeInt(mState);
1102         parcel.writeLong(mReceivedSvTimeNanos);
1103         parcel.writeLong(mReceivedSvTimeUncertaintyNanos);
1104         parcel.writeDouble(mCn0DbHz);
1105         parcel.writeDouble(mPseudorangeRateMetersPerSecond);
1106         parcel.writeDouble(mPseudorangeRateUncertaintyMetersPerSecond);
1107         parcel.writeInt(mAccumulatedDeltaRangeState);
1108         parcel.writeDouble(mAccumulatedDeltaRangeMeters);
1109         parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyMeters);
1110         parcel.writeFloat(mCarrierFrequencyHz);
1111         parcel.writeLong(mCarrierCycles);
1112         parcel.writeDouble(mCarrierPhase);
1113         parcel.writeDouble(mCarrierPhaseUncertainty);
1114         parcel.writeInt(mMultipathIndicator);
1115         parcel.writeDouble(mSnrInDb);
1116         parcel.writeDouble(mAutomaticGainControlLevelInDb);
1117     }
1118 
1119     @Override
describeContents()1120     public int describeContents() {
1121         return 0;
1122     }
1123 
1124     @Override
toString()1125     public String toString() {
1126         final String format = "   %-29s = %s\n";
1127         final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
1128         StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
1129 
1130         builder.append(String.format(format, "Svid", mSvid));
1131         builder.append(String.format(format, "ConstellationType", mConstellationType));
1132         builder.append(String.format(format, "TimeOffsetNanos", mTimeOffsetNanos));
1133 
1134         builder.append(String.format(format, "State", getStateString()));
1135 
1136         builder.append(String.format(
1137                 formatWithUncertainty,
1138                 "ReceivedSvTimeNanos",
1139                 mReceivedSvTimeNanos,
1140                 "ReceivedSvTimeUncertaintyNanos",
1141                 mReceivedSvTimeUncertaintyNanos));
1142 
1143         builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
1144 
1145         builder.append(String.format(
1146                 formatWithUncertainty,
1147                 "PseudorangeRateMetersPerSecond",
1148                 mPseudorangeRateMetersPerSecond,
1149                 "PseudorangeRateUncertaintyMetersPerSecond",
1150                 mPseudorangeRateUncertaintyMetersPerSecond));
1151 
1152         builder.append(String.format(
1153                 format,
1154                 "AccumulatedDeltaRangeState",
1155                 getAccumulatedDeltaRangeStateString()));
1156 
1157         builder.append(String.format(
1158                 formatWithUncertainty,
1159                 "AccumulatedDeltaRangeMeters",
1160                 mAccumulatedDeltaRangeMeters,
1161                 "AccumulatedDeltaRangeUncertaintyMeters",
1162                 mAccumulatedDeltaRangeUncertaintyMeters));
1163 
1164         builder.append(String.format(
1165                 format,
1166                 "CarrierFrequencyHz",
1167                 hasCarrierFrequencyHz() ? mCarrierFrequencyHz : null));
1168 
1169         builder.append(String.format(
1170                 format,
1171                 "CarrierCycles",
1172                 hasCarrierCycles() ? mCarrierCycles : null));
1173 
1174         builder.append(String.format(
1175                 formatWithUncertainty,
1176                 "CarrierPhase",
1177                 hasCarrierPhase() ? mCarrierPhase : null,
1178                 "CarrierPhaseUncertainty",
1179                 hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
1180 
1181         builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
1182 
1183         builder.append(String.format(
1184                 format,
1185                 "SnrInDb",
1186                 hasSnrInDb() ? mSnrInDb : null));
1187         builder.append(String.format(
1188             format,
1189             "AgcLevelDb",
1190             hasAutomaticGainControlLevelDb() ? mAutomaticGainControlLevelInDb : null));
1191 
1192         return builder.toString();
1193     }
1194 
initialize()1195     private void initialize() {
1196         mFlags = HAS_NO_FLAGS;
1197         setSvid(0);
1198         setTimeOffsetNanos(Long.MIN_VALUE);
1199         setState(STATE_UNKNOWN);
1200         setReceivedSvTimeNanos(Long.MIN_VALUE);
1201         setReceivedSvTimeUncertaintyNanos(Long.MAX_VALUE);
1202         setCn0DbHz(Double.MIN_VALUE);
1203         setPseudorangeRateMetersPerSecond(Double.MIN_VALUE);
1204         setPseudorangeRateUncertaintyMetersPerSecond(Double.MIN_VALUE);
1205         setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
1206         setAccumulatedDeltaRangeMeters(Double.MIN_VALUE);
1207         setAccumulatedDeltaRangeUncertaintyMeters(Double.MIN_VALUE);
1208         resetCarrierFrequencyHz();
1209         resetCarrierCycles();
1210         resetCarrierPhase();
1211         resetCarrierPhaseUncertainty();
1212         setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
1213         resetSnrInDb();
1214         resetAutomaticGainControlLevel();
1215     }
1216 
setFlag(int flag)1217     private void setFlag(int flag) {
1218         mFlags |= flag;
1219     }
1220 
resetFlag(int flag)1221     private void resetFlag(int flag) {
1222         mFlags &= ~flag;
1223     }
1224 
isFlagSet(int flag)1225     private boolean isFlagSet(int flag) {
1226         return (mFlags & flag) == flag;
1227     }
1228 }
1229