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