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