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.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.TestApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 
28 /**
29  * A class representing a GNSS satellite measurement, containing raw and computed information.
30  */
31 public final class GnssMeasurement implements Parcelable {
32     private int mFlags;
33     private int mSvid;
34     private int mConstellationType;
35     private double mTimeOffsetNanos;
36     private int mState;
37     private long mReceivedSvTimeNanos;
38     private long mReceivedSvTimeUncertaintyNanos;
39     private double mCn0DbHz;
40     private double mPseudorangeRateMetersPerSecond;
41     private double mPseudorangeRateUncertaintyMetersPerSecond;
42     private int mAccumulatedDeltaRangeState;
43     private double mAccumulatedDeltaRangeMeters;
44     private double mAccumulatedDeltaRangeUncertaintyMeters;
45     private float mCarrierFrequencyHz;
46     private long mCarrierCycles;
47     private double mCarrierPhase;
48     private double mCarrierPhaseUncertainty;
49     private int mMultipathIndicator;
50     private double mSnrInDb;
51     private double mAutomaticGainControlLevelInDb;
52     @NonNull private String mCodeType;
53 
54     // The following enumerations must be in sync with the values declared in gps.h
55 
56     private static final int HAS_NO_FLAGS = 0;
57     private static final int HAS_SNR = (1<<0);
58     private static final int HAS_CARRIER_FREQUENCY = (1<<9);
59     private static final int HAS_CARRIER_CYCLES = (1<<10);
60     private static final int HAS_CARRIER_PHASE = (1<<11);
61     private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
62     private static final int HAS_AUTOMATIC_GAIN_CONTROL = (1<<13);
63     private static final int HAS_CODE_TYPE = (1 << 14);
64 
65     /**
66      * The status of the multipath indicator.
67      * @hide
68      */
69     @Retention(RetentionPolicy.SOURCE)
70     @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
71             MULTIPATH_INDICATOR_NOT_DETECTED})
72     public @interface MultipathIndicator {}
73 
74     /**
75      * The indicator is not available or the presence or absence of multipath is unknown.
76      */
77     public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
78 
79     /**
80      * The measurement shows signs of multi-path.
81      */
82     public static final int MULTIPATH_INDICATOR_DETECTED = 1;
83 
84     /**
85      * The measurement shows no signs of multi-path.
86      */
87     public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
88 
89     /**
90      * GNSS measurement tracking loop state
91      * @hide
92      */
93     @IntDef(flag = true, prefix = { "STATE_" }, value = {
94             STATE_CODE_LOCK, STATE_BIT_SYNC, STATE_SUBFRAME_SYNC,
95             STATE_TOW_DECODED, STATE_MSEC_AMBIGUOUS, STATE_SYMBOL_SYNC, STATE_GLO_STRING_SYNC,
96             STATE_GLO_TOD_DECODED, STATE_BDS_D2_BIT_SYNC, STATE_BDS_D2_SUBFRAME_SYNC,
97             STATE_GAL_E1BC_CODE_LOCK, STATE_GAL_E1C_2ND_CODE_LOCK, STATE_GAL_E1B_PAGE_SYNC,
98             STATE_SBAS_SYNC, STATE_TOW_KNOWN, STATE_GLO_TOD_KNOWN, STATE_2ND_CODE_LOCK
99     })
100     @Retention(RetentionPolicy.SOURCE)
101     public @interface State {}
102 
103     /** This GNSS measurement's tracking state is invalid or unknown. */
104     public static final int STATE_UNKNOWN = 0;
105     /** This GNSS measurement's tracking state has code lock. */
106     public static final int STATE_CODE_LOCK = (1<<0);
107     /** This GNSS measurement's tracking state has bit sync. */
108     public static final int STATE_BIT_SYNC = (1<<1);
109     /** This GNSS measurement's tracking state has sub-frame sync. */
110     public static final int STATE_SUBFRAME_SYNC = (1<<2);
111     /** This GNSS measurement's tracking state has time-of-week decoded. */
112     public static final int STATE_TOW_DECODED = (1<<3);
113     /** This GNSS measurement's tracking state contains millisecond ambiguity. */
114     public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
115     /** This GNSS measurement's tracking state has symbol sync. */
116     public static final int STATE_SYMBOL_SYNC = (1<<5);
117     /** This Glonass measurement's tracking state has string sync. */
118     public static final int STATE_GLO_STRING_SYNC = (1<<6);
119     /** This Glonass measurement's tracking state has time-of-day decoded. */
120     public static final int STATE_GLO_TOD_DECODED = (1<<7);
121     /** This Beidou measurement's tracking state has D2 bit sync. */
122     public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
123     /** This Beidou measurement's tracking state has D2 sub-frame sync. */
124     public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
125     /** This Galileo measurement's tracking state has E1B/C code lock. */
126     public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
127     /** This Galileo measurement's tracking state has E1C secondary code lock. */
128     public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
129     /** This Galileo measurement's tracking state has E1B page sync. */
130     public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
131     /** This SBAS measurement's tracking state has whole second level sync. */
132     public static final int STATE_SBAS_SYNC = (1<<13);
133     /**
134      * This GNSS measurement's tracking state has time-of-week known, possibly not decoded
135      * over the air but has been determined from other sources. If TOW decoded is set then TOW Known
136      * will also be set.
137      */
138     public static final int STATE_TOW_KNOWN = (1<<14);
139     /**
140      * This Glonass measurement's tracking state has time-of-day known, possibly not decoded
141      * over the air but has been determined from other sources. If TOD decoded is set then TOD Known
142      * will also be set.
143      */
144     public static final int STATE_GLO_TOD_KNOWN = (1<<15);
145 
146     /** This GNSS measurement's tracking state has secondary code lock. */
147     public static final int STATE_2ND_CODE_LOCK  = (1 << 16);
148 
149     /**
150      * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
151      * individual measurement.)
152      */
153     private static final int STATE_ALL = 0x3fff;  // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
154 
155     /**
156      * GNSS measurement accumulated delta range state
157      * @hide
158      */
159     @IntDef(flag = true, prefix = { "ADR_STATE_" }, value = {
160             ADR_STATE_VALID, ADR_STATE_RESET, ADR_STATE_CYCLE_SLIP, ADR_STATE_HALF_CYCLE_RESOLVED,
161             ADR_STATE_HALF_CYCLE_REPORTED
162     })
163     @Retention(RetentionPolicy.SOURCE)
164     public @interface AdrState {}
165 
166     /**
167      * The state of the value {@link #getAccumulatedDeltaRangeMeters()} is invalid or unknown.
168      */
169     public static final int ADR_STATE_UNKNOWN = 0;
170 
171     /**
172      * The state of the {@link #getAccumulatedDeltaRangeMeters()} is valid.
173      */
174     public static final int ADR_STATE_VALID = (1<<0);
175 
176     /**
177      * The state of the {@link #getAccumulatedDeltaRangeMeters()} has detected a reset.
178      */
179     public static final int ADR_STATE_RESET = (1<<1);
180 
181     /**
182      * The state of the {@link #getAccumulatedDeltaRangeMeters()} has a cycle slip detected.
183      */
184     public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
185 
186     /**
187      * Reports whether the value {@link #getAccumulatedDeltaRangeMeters()} has resolved the half
188      * cycle ambiguity.
189      *
190      * <p> When this bit is set, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
191      * carrier phase measurement plus an accumulated integer number of carrier full cycles.
192      *
193      * <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
194      * carrier phase measurement plus an accumulated integer number of carrier half cycles.
195      */
196     public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
197 
198     /**
199      * Reports whether the flag {@link #ADR_STATE_HALF_CYCLE_RESOLVED} has been reported by the
200      * GNSS hardware.
201      *
202      * <p> When this bit is set, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
203      * can be low (centimeter level) whether or not the half cycle ambiguity is resolved.
204      *
205      * <p> When this bit is unset, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
206      * is larger, to cover the potential error due to half cycle ambiguity being unresolved.
207      */
208     public static final int ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
209 
210     /**
211      * All the 'Accumulated Delta Range' flags.
212      * @hide
213      */
214     @TestApi
215     public static final int ADR_STATE_ALL =
216             ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP |
217             ADR_STATE_HALF_CYCLE_RESOLVED | ADR_STATE_HALF_CYCLE_REPORTED;
218 
219     // End enumerations in sync with gps.h
220 
221     /**
222      * @hide
223      */
224     @TestApi
GnssMeasurement()225     public GnssMeasurement() {
226         initialize();
227     }
228 
229     /**
230      * Sets all contents to the values stored in the provided object.
231      * @hide
232      */
233     @TestApi
set(GnssMeasurement measurement)234     public void set(GnssMeasurement measurement) {
235         mFlags = measurement.mFlags;
236         mSvid = measurement.mSvid;
237         mConstellationType = measurement.mConstellationType;
238         mTimeOffsetNanos = measurement.mTimeOffsetNanos;
239         mState = measurement.mState;
240         mReceivedSvTimeNanos = measurement.mReceivedSvTimeNanos;
241         mReceivedSvTimeUncertaintyNanos = measurement.mReceivedSvTimeUncertaintyNanos;
242         mCn0DbHz = measurement.mCn0DbHz;
243         mPseudorangeRateMetersPerSecond = measurement.mPseudorangeRateMetersPerSecond;
244         mPseudorangeRateUncertaintyMetersPerSecond =
245                 measurement.mPseudorangeRateUncertaintyMetersPerSecond;
246         mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
247         mAccumulatedDeltaRangeMeters = measurement.mAccumulatedDeltaRangeMeters;
248         mAccumulatedDeltaRangeUncertaintyMeters =
249                 measurement.mAccumulatedDeltaRangeUncertaintyMeters;
250         mCarrierFrequencyHz = measurement.mCarrierFrequencyHz;
251         mCarrierCycles = measurement.mCarrierCycles;
252         mCarrierPhase = measurement.mCarrierPhase;
253         mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
254         mMultipathIndicator = measurement.mMultipathIndicator;
255         mSnrInDb = measurement.mSnrInDb;
256         mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
257         mCodeType = measurement.mCodeType;
258     }
259 
260     /**
261      * Resets all the contents to its original state.
262      * @hide
263      */
264     @TestApi
reset()265     public void reset() {
266         initialize();
267     }
268 
269     /**
270      * Gets the satellite ID.
271      *
272      * <p>Interpretation depends on {@link #getConstellationType()}.
273      * See {@link GnssStatus#getSvid(int)}.
274      */
getSvid()275     public int getSvid() {
276         return mSvid;
277     }
278 
279     /**
280      * Sets the Satellite ID.
281      * @hide
282      */
283     @TestApi
setSvid(int value)284     public void setSvid(int value) {
285         mSvid = value;
286     }
287 
288     /**
289      * Gets the constellation type.
290      *
291      * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
292      * {@link GnssStatus}.
293      */
294     @GnssStatus.ConstellationType
getConstellationType()295     public int getConstellationType() {
296         return mConstellationType;
297     }
298 
299     /**
300      * Sets the constellation type.
301      * @hide
302      */
303     @TestApi
setConstellationType(@nssStatus.ConstellationType int value)304     public void setConstellationType(@GnssStatus.ConstellationType int value) {
305         mConstellationType = value;
306     }
307 
308     /**
309      * Gets the time offset at which the measurement was taken in nanoseconds.
310      *
311      * <p>The reference receiver's time from which this is offset is specified by
312      * {@link GnssClock#getTimeNanos()}.
313      *
314      * <p>The sign of this value is given by the following equation:
315      * <pre>
316      *      measurement time = TimeNanos + TimeOffsetNanos</pre>
317      *
318      * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
319      * accuracy.
320      */
getTimeOffsetNanos()321     public double getTimeOffsetNanos() {
322         return mTimeOffsetNanos;
323     }
324 
325     /**
326      * Sets the time offset at which the measurement was taken in nanoseconds.
327      * @hide
328      */
329     @TestApi
setTimeOffsetNanos(double value)330     public void setTimeOffsetNanos(double value) {
331         mTimeOffsetNanos = value;
332     }
333 
334     /**
335      * Gets per-satellite sync state.
336      *
337      * <p>It represents the current sync state for the associated satellite.
338      *
339      * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
340      */
341     @State
getState()342     public int getState() {
343         return mState;
344     }
345 
346     /**
347      * Sets the sync state.
348      * @hide
349      */
350     @TestApi
setState(@tate int value)351     public void setState(@State int value) {
352         mState = value;
353     }
354 
355     /**
356      * Gets a string representation of the 'sync state'.
357      *
358      * <p>For internal and logging use only.
359      */
getStateString()360     private String getStateString() {
361         if (mState == STATE_UNKNOWN) {
362             return "Unknown";
363         }
364 
365         StringBuilder builder = new StringBuilder();
366         if ((mState & STATE_CODE_LOCK) != 0) {
367             builder.append("CodeLock|");
368         }
369         if ((mState & STATE_BIT_SYNC) != 0) {
370             builder.append("BitSync|");
371         }
372         if ((mState & STATE_SUBFRAME_SYNC) != 0) {
373             builder.append("SubframeSync|");
374         }
375         if ((mState & STATE_TOW_DECODED) != 0) {
376             builder.append("TowDecoded|");
377         }
378         if ((mState & STATE_TOW_KNOWN) != 0) {
379           builder.append("TowKnown|");
380         }
381         if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
382             builder.append("MsecAmbiguous|");
383         }
384         if ((mState & STATE_SYMBOL_SYNC) != 0) {
385             builder.append("SymbolSync|");
386         }
387         if ((mState & STATE_GLO_STRING_SYNC) != 0) {
388             builder.append("GloStringSync|");
389         }
390         if ((mState & STATE_GLO_TOD_DECODED) != 0) {
391             builder.append("GloTodDecoded|");
392         }
393         if ((mState & STATE_GLO_TOD_KNOWN) != 0) {
394           builder.append("GloTodKnown|");
395         }
396         if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
397             builder.append("BdsD2BitSync|");
398         }
399         if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
400             builder.append("BdsD2SubframeSync|");
401         }
402         if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
403             builder.append("GalE1bcCodeLock|");
404         }
405         if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
406             builder.append("E1c2ndCodeLock|");
407         }
408         if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
409             builder.append("GalE1bPageSync|");
410         }
411         if ((mState & STATE_SBAS_SYNC) != 0) {
412             builder.append("SbasSync|");
413         }
414         if ((mState & STATE_2ND_CODE_LOCK) != 0) {
415             builder.append("2ndCodeLock|");
416         }
417 
418         int remainingStates = mState & ~STATE_ALL;
419         if (remainingStates > 0) {
420             builder.append("Other(");
421             builder.append(Integer.toBinaryString(remainingStates));
422             builder.append(")|");
423         }
424         builder.setLength(builder.length() - 1);
425         return builder.toString();
426     }
427 
428     /**
429      * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
430      *
431      * <p>The received satellite time is relative to the beginning of the system week for all
432      * constellations except for Glonass where it is relative to the beginning of the Glonass
433      * system day.
434      *
435      * <p>The table below indicates the valid range of the received GNSS satellite time. These
436      * ranges depend on the constellation and code being tracked and the state of the tracking
437      * algorithms given by the {@link #getState} method. The minimum value of this field is zero.
438      * The maximum value of this field is determined by looking across all of the state flags
439      * that are set, for the given constellation and code type, and finding the the maximum value
440      * in this table.
441      *
442      * <p>For example, for GPS L1 C/A, if STATE_TOW_KNOWN is set, this field can be any value from 0
443      * to 1 week (in nanoseconds), and for GAL E1B code, if only STATE_GAL_E1BC_CODE_LOCK is set,
444      * then this field can be any value from 0 to 4 milliseconds (in nanoseconds.)
445      *
446      * <table border="1">
447      *   <thead>
448      *     <tr>
449      *       <td />
450      *       <td colspan="3"><strong>GPS/QZSS</strong></td>
451      *       <td><strong>GLNS</strong></td>
452      *       <td colspan="2"><strong>BDS</strong></td>
453      *       <td colspan="3"><strong>GAL</strong></td>
454      *       <td><strong>SBAS</strong></td>
455      *     </tr>
456      *     <tr>
457      *       <td><strong>State Flag</strong></td>
458      *       <td><strong>L1 C/A</strong></td>
459      *       <td><strong>L5I</strong></td>
460      *       <td><strong>L5Q</strong></td>
461      *       <td><strong>L1OF</strong></td>
462      *       <td><strong>B1I (D1)</strong></td>
463      *       <td><strong>B1I &nbsp;(D2)</strong></td>
464      *       <td><strong>E1B</strong></td>
465      *       <td><strong>E1C</strong></td>
466      *       <td><strong>E5AQ</strong></td>
467      *       <td><strong>L1 C/A</strong></td>
468      *     </tr>
469      *   </thead>
470      *   <tbody>
471      *     <tr>
472      *       <td>
473      *         <strong>STATE_UNKNOWN</strong>
474      *       </td>
475      *       <td>0</td>
476      *       <td>0</td>
477      *       <td>0</td>
478      *       <td>0</td>
479      *       <td>0</td>
480      *       <td>0</td>
481      *       <td>0</td>
482      *       <td>0</td>
483      *       <td>0</td>
484      *       <td>0</td>
485      *     </tr>
486      *     <tr>
487      *       <td>
488      *         <strong>STATE_CODE_LOCK</strong>
489      *       </td>
490      *       <td>1 ms</td>
491      *       <td>1 ms</td>
492      *       <td>1 ms</td>
493      *       <td>1 ms</td>
494      *       <td>1 ms</td>
495      *       <td>1 ms</td>
496      *       <td>-</td>
497      *       <td>-</td>
498      *       <td>1 ms</td>
499      *       <td>1 ms</td>
500      *     </tr>
501      *     <tr>
502      *       <td>
503      *         <strong>STATE_SYMBOL_SYNC</strong>
504      *       </td>
505      *       <td>20 ms (optional)</td>
506      *       <td>10 ms</td>
507      *       <td>1 ms (optional)</td>
508      *       <td>10 ms</td>
509      *       <td>20 ms (optional)</td>
510      *       <td>2 ms</td>
511      *       <td>4 ms (optional)</td>
512      *       <td>4 ms (optional)</td>
513      *       <td>1 ms (optional)</td>
514      *       <td>2 ms</td>
515      *     </tr>
516      *     <tr>
517      *       <td>
518      *         <strong>STATE_BIT_SYNC</strong>
519      *       </td>
520      *       <td>20 ms</td>
521      *       <td>20 ms</td>
522      *       <td>1 ms (optional)</td>
523      *       <td>20 ms</td>
524      *       <td>20 ms</td>
525      *       <td>-</td>
526      *       <td>8 ms</td>
527      *       <td>-</td>
528      *       <td>1 ms (optional)</td>
529      *       <td>4 ms</td>
530      *     </tr>
531      *     <tr>
532      *       <td>
533      *         <strong>STATE_SUBFRAME_SYNC</strong>
534      *       </td>
535      *       <td>6s</td>
536      *       <td>6s</td>
537      *       <td>-</td>
538      *       <td>2 s</td>
539      *       <td>6 s</td>
540      *       <td>-</td>
541      *       <td>-</td>
542      *       <td>-</td>
543      *       <td>100 ms</td>
544      *       <td>-</td>
545      *     </tr>
546      *     <tr>
547      *       <td>
548      *         <strong>STATE_TOW_DECODED</strong>
549      *       </td>
550      *       <td colspan="2">1 week</td>
551      *       <td>-</td>
552      *       <td>1 day</td>
553      *       <td colspan="2">1 week</td>
554      *       <td colspan="2">1 week</td>
555      *       <td>-</td>
556      *       <td>1 week</td>
557      *     </tr>
558      *     <tr>
559      *       <td>
560      *         <strong>STATE_TOW_KNOWN</strong>
561      *       </td>
562      *       <td colspan="3">1 week</td>
563      *       <td>1 day</td>
564      *       <td colspan="2">1 week</td>
565      *       <td colspan="3">1 week</td>
566      *       <td>1 week</td>
567      *     </tr>
568      *     <tr>
569      *       <td>
570      *         <strong>STATE_GLO_STRING_SYNC</strong>
571      *       </td>
572      *       <td>-</td>
573      *       <td>-</td>
574      *       <td>-</td>
575      *       <td>2 s</td>
576      *       <td>-</td>
577      *       <td>-</td>
578      *       <td>-</td>
579      *       <td>-</td>
580      *       <td>-</td>
581      *       <td>-</td>
582      *     </tr>
583      *     <tr>
584      *       <td>
585      *         <strong>STATE_GLO_TOD_DECODED</strong>
586      *       </td>
587      *       <td>-</td>
588      *       <td>-</td>
589      *       <td>-</td>
590      *       <td>1 day</td>
591      *       <td>-</td>
592      *       <td>-</td>
593      *       <td>-</td>
594      *       <td>-</td>
595      *       <td>-</td>
596      *       <td>-</td>
597      *     </tr>
598      *     <tr>
599      *       <td>
600      *         <strong>STATE_GLO_TOD_KNOWN</strong>
601      *       </td>
602      *       <td>-</td>
603      *       <td>-</td>
604      *       <td>-</td>
605      *       <td>1 day</td>
606      *       <td>-</td>
607      *       <td>-</td>
608      *       <td>-</td>
609      *       <td>-</td>
610      *       <td>-</td>
611      *       <td>-</td>
612      *     </tr>
613      *     <tr>
614      *       <td>
615      *         <strong>STATE_BDS_D2_BIT_SYNC</strong>
616      *       </td>
617      *       <td>-</td>
618      *       <td>-</td>
619      *       <td>-</td>
620      *       <td>-</td>
621      *       <td>-</td>
622      *       <td>2 ms</td>
623      *       <td>-</td>
624      *       <td>-</td>
625      *       <td>-</td>
626      *       <td>-</td>
627      *     </tr>
628      *     <tr>
629      *       <td>
630      *         <strong>STATE_BDS_D2_SUBFRAME_SYNC</strong>
631      *       </td>
632      *       <td>-</td>
633      *       <td>-</td>
634      *       <td>-</td>
635      *       <td>-</td>
636      *       <td>-</td>
637      *       <td>600 ms</td>
638      *       <td>-</td>
639      *       <td>-</td>
640      *       <td>-</td>
641      *       <td>-</td>
642      *     </tr>
643      *     <tr>
644      *       <td>
645      *         <strong>STATE_GAL_E1BC_CODE_LOCK</strong>
646      *       </td>
647      *       <td>-</td>
648      *       <td>-</td>
649      *       <td>-</td>
650      *       <td>-</td>
651      *       <td>-</td>
652      *       <td>-</td>
653      *       <td>4 ms</td>
654      *       <td>4 ms</td>
655      *       <td>-</td>
656      *       <td>-</td>
657      *     </tr>
658      *     <tr>
659      *       <td>
660      *         <strong>STATE_GAL_E1C_2ND_CODE_LOCK</strong>
661      *       </td>
662      *       <td>-</td>
663      *       <td>-</td>
664      *       <td>-</td>
665      *       <td>-</td>
666      *       <td>-</td>
667      *       <td>-</td>
668      *       <td>-</td>
669      *       <td>100 ms</td>
670      *       <td>-</td>
671      *       <td>-</td>
672      *     </tr>
673      *     <tr>
674      *       <td>
675      *         <strong>STATE_2ND_CODE_LOCK</strong>
676      *       </td>
677      *       <td>-</td>
678      *       <td>10 ms (optional)</td>
679      *       <td>20 ms</td>
680      *       <td>-</td>
681      *       <td>-</td>
682      *       <td>-</td>
683      *       <td>-</td>
684      *       <td>100 ms (optional)</td>
685      *       <td>100 ms</td>
686      *       <td>-</td>
687      *     </tr>
688      *     <tr>
689      *       <td>
690      *         <strong>STATE_GAL_E1B_PAGE_SYNC</strong>
691      *       </td>
692      *       <td>-</td>
693      *       <td>-</td>
694      *       <td>-</td>
695      *       <td>-</td>
696      *       <td>-</td>
697      *       <td>-</td>
698      *       <td>2 s</td>
699      *       <td>-</td>
700      *       <td>-</td>
701      *       <td>-</td>
702      *     </tr>
703      *     <tr>
704      *       <td>
705      *         <strong>STATE_SBAS_SYNC</strong>
706      *       </td>
707      *       <td>-</td>
708      *       <td>-</td>
709      *       <td>-</td>
710      *       <td>-</td>
711      *       <td>-</td>
712      *       <td>-</td>
713      *       <td>-</td>
714      *       <td>-</td>
715      *       <td>-</td>
716      *       <td>1 s</td>
717      *     </tr>
718      *   </tbody>
719      * </table>
720      *
721      * <p>Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
722      * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
723      *
724      * <p>Note well: if there is any ambiguity in integer millisecond, STATE_MSEC_AMBIGUOUS must be
725      * set accordingly, in the 'state' field. This value must be populated, unless the 'state' ==
726      * STATE_UNKNOWN.
727      *
728      * <p>Note on optional flags:
729      * <ul>
730      *     <li> For L1 C/A and B1I, STATE_SYMBOL_SYNC is optional since the symbol length is the
731      *     same as the bit length.
732      *     <li> For L5Q and E5aQ, STATE_BIT_SYNC and STATE_SYMBOL_SYNC are optional since they are
733      *     implied by STATE_CODE_LOCK.
734      *     <li> STATE_2ND_CODE_LOCK for L5I is optional since it is implied by STATE_SYMBOL_SYNC.
735      *     <li> STATE_2ND_CODE_LOCK for E1C is optional since it is implied by
736      *     STATE_GAL_E1C_2ND_CODE_LOCK.
737      *     <li> For E1B and E1C, STATE_SYMBOL_SYNC is optional, because it is implied by
738      *     STATE_GAL_E1BC_CODE_LOCK.
739      * </ul>
740      */
getReceivedSvTimeNanos()741     public long getReceivedSvTimeNanos() {
742         return mReceivedSvTimeNanos;
743     }
744 
745     /**
746      * Sets the received GNSS time in nanoseconds.
747      * @hide
748      */
749     @TestApi
setReceivedSvTimeNanos(long value)750     public void setReceivedSvTimeNanos(long value) {
751         mReceivedSvTimeNanos = value;
752     }
753 
754     /**
755      * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
756      */
getReceivedSvTimeUncertaintyNanos()757     public long getReceivedSvTimeUncertaintyNanos() {
758         return mReceivedSvTimeUncertaintyNanos;
759     }
760 
761     /**
762      * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
763      * @hide
764      */
765     @TestApi
setReceivedSvTimeUncertaintyNanos(long value)766     public void setReceivedSvTimeUncertaintyNanos(long value) {
767         mReceivedSvTimeUncertaintyNanos = value;
768     }
769 
770     /**
771      * Gets the Carrier-to-noise density in dB-Hz.
772      *
773      * <p>Typical range: 10-50 db-Hz.
774      *
775      * <p>The value contains the measured C/N0 for the signal at the antenna input.
776      */
getCn0DbHz()777     public double getCn0DbHz() {
778         return mCn0DbHz;
779     }
780 
781     /**
782      * Sets the carrier-to-noise density in dB-Hz.
783      * @hide
784      */
785     @TestApi
setCn0DbHz(double value)786     public void setCn0DbHz(double value) {
787         mCn0DbHz = value;
788     }
789 
790     /**
791      * Gets the Pseudorange rate at the timestamp in m/s.
792      *
793      * <p>The error estimate for this value is
794      * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
795      *
796      * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
797      * errors are not included.
798      *
799      * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
800      * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
801      * is given by the equation:
802      *
803      * <pre>
804      *      pseudorange rate = -k * doppler shift   (where k is a constant)</pre>
805      */
getPseudorangeRateMetersPerSecond()806     public double getPseudorangeRateMetersPerSecond() {
807         return mPseudorangeRateMetersPerSecond;
808     }
809 
810     /**
811      * Sets the pseudorange rate at the timestamp in m/s.
812      * @hide
813      */
814     @TestApi
setPseudorangeRateMetersPerSecond(double value)815     public void setPseudorangeRateMetersPerSecond(double value) {
816         mPseudorangeRateMetersPerSecond = value;
817     }
818 
819     /**
820      * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
821      *
822      * <p>The uncertainty is represented as an absolute (single sided) value.
823      */
getPseudorangeRateUncertaintyMetersPerSecond()824     public double getPseudorangeRateUncertaintyMetersPerSecond() {
825         return mPseudorangeRateUncertaintyMetersPerSecond;
826     }
827 
828     /**
829      * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
830      * @hide
831      */
832     @TestApi
setPseudorangeRateUncertaintyMetersPerSecond(double value)833     public void setPseudorangeRateUncertaintyMetersPerSecond(double value) {
834         mPseudorangeRateUncertaintyMetersPerSecond = value;
835     }
836 
837     /**
838      * Gets 'Accumulated Delta Range' state.
839      *
840      * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
841      * cycle slip (indicating 'loss of lock').
842      */
843     @AdrState
getAccumulatedDeltaRangeState()844     public int getAccumulatedDeltaRangeState() {
845         return mAccumulatedDeltaRangeState;
846     }
847 
848     /**
849      * Sets the 'Accumulated Delta Range' state.
850      * @hide
851      */
852     @TestApi
setAccumulatedDeltaRangeState(@drState int value)853     public void setAccumulatedDeltaRangeState(@AdrState int value) {
854         mAccumulatedDeltaRangeState = value;
855     }
856 
857     /**
858      * Gets a string representation of the 'Accumulated Delta Range state'.
859      *
860      * <p>For internal and logging use only.
861      */
getAccumulatedDeltaRangeStateString()862     private String getAccumulatedDeltaRangeStateString() {
863         if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
864             return "Unknown";
865         }
866         StringBuilder builder = new StringBuilder();
867         if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
868             builder.append("Valid|");
869         }
870         if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
871             builder.append("Reset|");
872         }
873         if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
874             builder.append("CycleSlip|");
875         }
876         if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_RESOLVED) ==
877                 ADR_STATE_HALF_CYCLE_RESOLVED) {
878             builder.append("HalfCycleResolved|");
879         }
880         if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_REPORTED)
881                 == ADR_STATE_HALF_CYCLE_REPORTED) {
882             builder.append("HalfCycleReported|");
883         }
884         int remainingStates = mAccumulatedDeltaRangeState & ~ADR_STATE_ALL;
885         if (remainingStates > 0) {
886             builder.append("Other(");
887             builder.append(Integer.toBinaryString(remainingStates));
888             builder.append(")|");
889         }
890         builder.deleteCharAt(builder.length() - 1);
891         return builder.toString();
892     }
893 
894     /**
895      * Gets the accumulated delta range since the last channel reset, in meters.
896      *
897      * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
898      *
899      * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
900      *
901      * <p>A positive value indicates that the SV is moving away from the receiver.
902      * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
903      * {@link #getCarrierPhase()} is given by the equation:
904      *
905      * <pre>
906      *          accumulated delta range = -k * carrier phase    (where k is a constant)</pre>
907      *
908      * <p>Similar to the concept of an RTCM "Phaserange", when the accumulated delta range is
909      * initially chosen, and whenever it is reset, it will retain the integer nature
910      * of the relative carrier phase offset between satellites observed by this receiver, such that
911      * the double difference of this value between receivers and satellites may be used, together
912      * with integer ambiguity resolution, to determine highly precise relative location between
913      * receivers.
914      *
915      * <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
916      * reported as {@link #ADR_STATE_VALID}.
917      *
918      * <p>The alignment of the phase measurement will not be adjusted by the receiver so the
919      * in-phase and quadrature phase components will have a quarter cycle offset as they do when
920      * transmitted from the satellites. If the measurement is from a combination of the in-phase
921      * and quadrature phase components, then the alignment of the phase measurement will be aligned
922      * to the in-phase component.
923      */
getAccumulatedDeltaRangeMeters()924     public double getAccumulatedDeltaRangeMeters() {
925         return mAccumulatedDeltaRangeMeters;
926     }
927 
928     /**
929      * Sets the accumulated delta range in meters.
930      * @hide
931      */
932     @TestApi
setAccumulatedDeltaRangeMeters(double value)933     public void setAccumulatedDeltaRangeMeters(double value) {
934         mAccumulatedDeltaRangeMeters = value;
935     }
936 
937     /**
938      * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
939      *
940      * <p>The uncertainty is represented as an absolute (single sided) value.
941      *
942      * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
943      */
getAccumulatedDeltaRangeUncertaintyMeters()944     public double getAccumulatedDeltaRangeUncertaintyMeters() {
945         return mAccumulatedDeltaRangeUncertaintyMeters;
946     }
947 
948     /**
949      * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
950      *
951      * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
952      *
953      * @hide
954      */
955     @TestApi
setAccumulatedDeltaRangeUncertaintyMeters(double value)956     public void setAccumulatedDeltaRangeUncertaintyMeters(double value) {
957         mAccumulatedDeltaRangeUncertaintyMeters = value;
958     }
959 
960     /**
961      * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
962      * otherwise.
963      */
hasCarrierFrequencyHz()964     public boolean hasCarrierFrequencyHz() {
965         return isFlagSet(HAS_CARRIER_FREQUENCY);
966     }
967 
968     /**
969      * Gets the carrier frequency of the tracked signal.
970      *
971      * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
972      * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
973      * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
974      *
975      * <p> For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
976      * measurement objects will be reported for this same satellite, in one of the measurement
977      * objects, all the values related to L1 will be filled, and in the other all of the values
978      * related to L5 will be filled.
979      *
980      * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
981      *
982      * @return the carrier frequency of the signal tracked in Hz.
983      */
getCarrierFrequencyHz()984     public float getCarrierFrequencyHz() {
985         return mCarrierFrequencyHz;
986     }
987 
988     /**
989      * Sets the Carrier frequency in Hz.
990      * @hide
991      */
992     @TestApi
setCarrierFrequencyHz(float carrierFrequencyHz)993     public void setCarrierFrequencyHz(float carrierFrequencyHz) {
994         setFlag(HAS_CARRIER_FREQUENCY);
995         mCarrierFrequencyHz = carrierFrequencyHz;
996     }
997 
998     /**
999      * Resets the Carrier frequency in Hz.
1000      * @hide
1001      */
1002     @TestApi
resetCarrierFrequencyHz()1003     public void resetCarrierFrequencyHz() {
1004         resetFlag(HAS_CARRIER_FREQUENCY);
1005         mCarrierFrequencyHz = Float.NaN;
1006     }
1007 
1008     /**
1009      * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
1010      *
1011      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
1012      */
1013     @Deprecated
hasCarrierCycles()1014     public boolean hasCarrierCycles() {
1015         return isFlagSet(HAS_CARRIER_CYCLES);
1016     }
1017 
1018     /**
1019      * The number of full carrier cycles between the satellite and the receiver.
1020      *
1021      * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
1022      *
1023      * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
1024      *
1025      * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
1026      */
1027     @Deprecated
getCarrierCycles()1028     public long getCarrierCycles() {
1029         return mCarrierCycles;
1030     }
1031 
1032     /**
1033      * Sets the number of full carrier cycles between the satellite and the receiver.
1034      *
1035      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
1036      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1037      *
1038      * @hide
1039      */
1040     @TestApi
1041     @Deprecated
setCarrierCycles(long value)1042     public void setCarrierCycles(long value) {
1043         setFlag(HAS_CARRIER_CYCLES);
1044         mCarrierCycles = value;
1045     }
1046 
1047     /**
1048      * Resets the number of full carrier cycles between the satellite and the receiver.
1049      *
1050      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
1051      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1052      * @hide
1053      */
1054     @TestApi
1055     @Deprecated
resetCarrierCycles()1056     public void resetCarrierCycles() {
1057         resetFlag(HAS_CARRIER_CYCLES);
1058         mCarrierCycles = Long.MIN_VALUE;
1059     }
1060 
1061     /**
1062      * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
1063      *
1064      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
1065      */
1066     @Deprecated
hasCarrierPhase()1067     public boolean hasCarrierPhase() {
1068         return isFlagSet(HAS_CARRIER_PHASE);
1069     }
1070 
1071     /**
1072      * Gets the RF phase detected by the receiver.
1073      *
1074      * <p>Range: [0.0, 1.0].
1075      *
1076      * <p>This is the fractional part of the complete carrier phase measurement.
1077      *
1078      * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
1079      *
1080      * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
1081      *
1082      * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
1083      *
1084      * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
1085      */
1086     @Deprecated
getCarrierPhase()1087     public double getCarrierPhase() {
1088         return mCarrierPhase;
1089     }
1090 
1091     /**
1092      * Sets the RF phase detected by the receiver.
1093      *
1094      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
1095      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1096      *
1097      * @hide
1098      */
1099     @TestApi
1100     @Deprecated
setCarrierPhase(double value)1101     public void setCarrierPhase(double value) {
1102         setFlag(HAS_CARRIER_PHASE);
1103         mCarrierPhase = value;
1104     }
1105 
1106     /**
1107      * Resets the RF phase detected by the receiver.
1108      *
1109      * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
1110      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1111      *
1112      * @hide
1113      */
1114     @TestApi
1115     @Deprecated
resetCarrierPhase()1116     public void resetCarrierPhase() {
1117         resetFlag(HAS_CARRIER_PHASE);
1118         mCarrierPhase = Double.NaN;
1119     }
1120 
1121     /**
1122      * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
1123      * otherwise.
1124      *
1125      * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
1126      */
1127     @Deprecated
hasCarrierPhaseUncertainty()1128     public boolean hasCarrierPhaseUncertainty() {
1129         return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
1130     }
1131 
1132     /**
1133      * Gets the carrier-phase's uncertainty (1-Sigma).
1134      *
1135      * <p>The uncertainty is represented as an absolute (single sided) value.
1136      *
1137      * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
1138      *
1139      * @deprecated use {@link #getAccumulatedDeltaRangeUncertaintyMeters()} instead.
1140      */
1141     @Deprecated
getCarrierPhaseUncertainty()1142     public double getCarrierPhaseUncertainty() {
1143         return mCarrierPhaseUncertainty;
1144     }
1145 
1146     /**
1147      * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
1148      *
1149      * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
1150      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1151      *
1152      * @hide
1153      */
1154     @TestApi
1155     @Deprecated
setCarrierPhaseUncertainty(double value)1156     public void setCarrierPhaseUncertainty(double value) {
1157         setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
1158         mCarrierPhaseUncertainty = value;
1159     }
1160 
1161     /**
1162      * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
1163      *
1164      * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
1165      * and {@link #setAccumulatedDeltaRangeState(int)} instead.
1166      *
1167      * @hide
1168      */
1169     @TestApi
1170     @Deprecated
resetCarrierPhaseUncertainty()1171     public void resetCarrierPhaseUncertainty() {
1172         resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
1173         mCarrierPhaseUncertainty = Double.NaN;
1174     }
1175 
1176     /**
1177      * Gets a value indicating the 'multipath' state of the event.
1178      */
1179     @MultipathIndicator
getMultipathIndicator()1180     public int getMultipathIndicator() {
1181         return mMultipathIndicator;
1182     }
1183 
1184     /**
1185      * Sets the 'multi-path' indicator.
1186      * @hide
1187      */
1188     @TestApi
setMultipathIndicator(@ultipathIndicator int value)1189     public void setMultipathIndicator(@MultipathIndicator int value) {
1190         mMultipathIndicator = value;
1191     }
1192 
1193     /**
1194      * Gets a string representation of the 'multi-path indicator'.
1195      *
1196      * <p>For internal and logging use only.
1197      */
getMultipathIndicatorString()1198     private String getMultipathIndicatorString() {
1199         switch (mMultipathIndicator) {
1200             case MULTIPATH_INDICATOR_UNKNOWN:
1201                 return "Unknown";
1202             case MULTIPATH_INDICATOR_DETECTED:
1203                 return "Detected";
1204             case MULTIPATH_INDICATOR_NOT_DETECTED:
1205                 return "NotDetected";
1206             default:
1207                 return "<Invalid: " + mMultipathIndicator + ">";
1208         }
1209     }
1210 
1211     /**
1212      * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
1213      */
hasSnrInDb()1214     public boolean hasSnrInDb() {
1215         return isFlagSet(HAS_SNR);
1216     }
1217 
1218     /**
1219      * Gets the (post-correlation & integration) Signal-to-Noise ratio (SNR) in dB.
1220      *
1221      * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
1222      */
getSnrInDb()1223     public double getSnrInDb() {
1224         return mSnrInDb;
1225     }
1226 
1227     /**
1228      * Sets the Signal-to-noise ratio (SNR) in dB.
1229      * @hide
1230      */
1231     @TestApi
setSnrInDb(double snrInDb)1232     public void setSnrInDb(double snrInDb) {
1233         setFlag(HAS_SNR);
1234         mSnrInDb = snrInDb;
1235     }
1236 
1237     /**
1238      * Resets the Signal-to-noise ratio (SNR) in dB.
1239      * @hide
1240      */
1241     @TestApi
resetSnrInDb()1242     public void resetSnrInDb() {
1243         resetFlag(HAS_SNR);
1244         mSnrInDb = Double.NaN;
1245     }
1246 
1247     /**
1248      * Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
1249      * {@code false} otherwise.
1250      */
hasAutomaticGainControlLevelDb()1251     public boolean hasAutomaticGainControlLevelDb() {
1252         return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
1253     }
1254 
1255     /**
1256      * Gets the Automatic Gain Control level in dB.
1257      *
1258      * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal. The AGC
1259      * level may be used to indicate potential interference. When AGC is at a nominal level, this
1260      * value must be set as 0. Higher gain (and/or lower input power) shall be output as a positive
1261      * number. Hence in cases of strong jamming, in the band of this signal, this value will go more
1262      * negative.
1263      *
1264      * <p> Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
1265      * components) may also affect the typical output of of this value on any given hardware design
1266      * in an open sky test - the important aspect of this output is that changes in this value are
1267      * indicative of changes on input signal power in the frequency band for this measurement.
1268      *
1269      * <p> The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
1270      */
getAutomaticGainControlLevelDb()1271     public double getAutomaticGainControlLevelDb() {
1272         return mAutomaticGainControlLevelInDb;
1273     }
1274 
1275     /**
1276      * Sets the Automatic Gain Control level in dB.
1277      * @hide
1278      */
1279     @TestApi
setAutomaticGainControlLevelInDb(double agcLevelDb)1280     public void setAutomaticGainControlLevelInDb(double agcLevelDb) {
1281         setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
1282         mAutomaticGainControlLevelInDb = agcLevelDb;
1283     }
1284 
1285     /**
1286      * Resets the Automatic Gain Control level.
1287      * @hide
1288      */
1289     @TestApi
resetAutomaticGainControlLevel()1290     public void resetAutomaticGainControlLevel() {
1291         resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
1292         mAutomaticGainControlLevelInDb = Double.NaN;
1293     }
1294 
1295     /**
1296      * Returns {@code true} if {@link #getCodeType()} is available,
1297      * {@code false} otherwise.
1298      */
hasCodeType()1299     public boolean hasCodeType() {
1300         return isFlagSet(HAS_CODE_TYPE);
1301     }
1302 
1303     /**
1304      * Gets the GNSS measurement's code type.
1305      *
1306      * <p>Similar to the Attribute field described in RINEX 3.03, e.g., in Tables 4-10, and Table
1307      * A2 at the RINEX 3.03 Update 1 Document.
1308      *
1309      * <p>Returns "A" for GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA.
1310      *
1311      * <p>Returns "B" for GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB.
1312      *
1313      * <p>Returns "C" for GPS L1 C/A,  GPS L2 C/A, GLONASS G1 C/A, GLONASS G2 C/A, GALILEO E1C,
1314      * GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C.
1315      *
1316      * <p>Returns "I" for GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, GALILEO E5a+b I,
1317      * SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I.
1318      *
1319      * <p>Returns "L" for GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), LEX(6) L.
1320      *
1321      * <p>Returns "M" for GPS L1M, GPS L2M.
1322      *
1323      * <p>Returns "N" for GPS L1 codeless, GPS L2 codeless.
1324      *
1325      * <p>Returns "P" for GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P.
1326      *
1327      * <p>Returns "Q" for GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, GALILEO E5a+b Q,
1328      * SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
1329      *
1330      * <p>Returns "S" for GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), LEX(6) S.
1331      *
1332      * <p>Returns "W" for GPS L1 Z-tracking, GPS L2 Z-tracking.
1333      *
1334      * <p>Returns "X" for GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q), GALILEO
1335      * E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q), GALILEO E6 (B+C), SBAS
1336      * L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), LEX(6) (S+L), BDS B1 (I+Q), BDS
1337      * B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
1338      *
1339      * <p>Returns "Y" for GPS L1Y, GPS L2Y.
1340      *
1341      * <p>Returns "Z" for GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF.
1342      *
1343      * <p>Returns "UNKNOWN" if the GNSS Measurement's code type is unknown.
1344      *
1345      * <p>This is used to specify the observation descriptor defined in GNSS Observation Data File
1346      * Header Section Description in the RINEX standard (Version 3.XX), in cases where the code type
1347      * does not align with the above listed values. For example, if a code type "G" is added, this
1348      * string shall be set to "G".
1349      */
1350     @NonNull
getCodeType()1351     public String getCodeType() {
1352         return mCodeType;
1353     }
1354 
1355     /**
1356      * Sets the GNSS measurement's code type.
1357      *
1358      * @hide
1359      */
1360     @TestApi
setCodeType(@onNull String codeType)1361     public void setCodeType(@NonNull String codeType) {
1362         setFlag(HAS_CODE_TYPE);
1363         mCodeType = codeType;
1364     }
1365 
1366     /**
1367      * Resets the GNSS measurement's code type.
1368      *
1369      * @hide
1370      */
1371     @TestApi
resetCodeType()1372     public void resetCodeType() {
1373         resetFlag(HAS_CODE_TYPE);
1374         mCodeType = "UNKNOWN";
1375     }
1376 
1377     public static final @android.annotation.NonNull Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
1378         @Override
1379         public GnssMeasurement createFromParcel(Parcel parcel) {
1380             GnssMeasurement gnssMeasurement = new GnssMeasurement();
1381 
1382             gnssMeasurement.mFlags = parcel.readInt();
1383             gnssMeasurement.mSvid = parcel.readInt();
1384             gnssMeasurement.mConstellationType = parcel.readInt();
1385             gnssMeasurement.mTimeOffsetNanos = parcel.readDouble();
1386             gnssMeasurement.mState = parcel.readInt();
1387             gnssMeasurement.mReceivedSvTimeNanos = parcel.readLong();
1388             gnssMeasurement.mReceivedSvTimeUncertaintyNanos = parcel.readLong();
1389             gnssMeasurement.mCn0DbHz = parcel.readDouble();
1390             gnssMeasurement.mPseudorangeRateMetersPerSecond = parcel.readDouble();
1391             gnssMeasurement.mPseudorangeRateUncertaintyMetersPerSecond = parcel.readDouble();
1392             gnssMeasurement.mAccumulatedDeltaRangeState = parcel.readInt();
1393             gnssMeasurement.mAccumulatedDeltaRangeMeters = parcel.readDouble();
1394             gnssMeasurement.mAccumulatedDeltaRangeUncertaintyMeters = parcel.readDouble();
1395             gnssMeasurement.mCarrierFrequencyHz = parcel.readFloat();
1396             gnssMeasurement.mCarrierCycles = parcel.readLong();
1397             gnssMeasurement.mCarrierPhase = parcel.readDouble();
1398             gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
1399             gnssMeasurement.mMultipathIndicator = parcel.readInt();
1400             gnssMeasurement.mSnrInDb = parcel.readDouble();
1401             gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
1402             gnssMeasurement.mCodeType = parcel.readString();
1403 
1404             return gnssMeasurement;
1405         }
1406 
1407         @Override
1408         public GnssMeasurement[] newArray(int i) {
1409             return new GnssMeasurement[i];
1410         }
1411     };
1412 
1413     @Override
writeToParcel(Parcel parcel, int flags)1414     public void writeToParcel(Parcel parcel, int flags) {
1415         parcel.writeInt(mFlags);
1416         parcel.writeInt(mSvid);
1417         parcel.writeInt(mConstellationType);
1418         parcel.writeDouble(mTimeOffsetNanos);
1419         parcel.writeInt(mState);
1420         parcel.writeLong(mReceivedSvTimeNanos);
1421         parcel.writeLong(mReceivedSvTimeUncertaintyNanos);
1422         parcel.writeDouble(mCn0DbHz);
1423         parcel.writeDouble(mPseudorangeRateMetersPerSecond);
1424         parcel.writeDouble(mPseudorangeRateUncertaintyMetersPerSecond);
1425         parcel.writeInt(mAccumulatedDeltaRangeState);
1426         parcel.writeDouble(mAccumulatedDeltaRangeMeters);
1427         parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyMeters);
1428         parcel.writeFloat(mCarrierFrequencyHz);
1429         parcel.writeLong(mCarrierCycles);
1430         parcel.writeDouble(mCarrierPhase);
1431         parcel.writeDouble(mCarrierPhaseUncertainty);
1432         parcel.writeInt(mMultipathIndicator);
1433         parcel.writeDouble(mSnrInDb);
1434         parcel.writeDouble(mAutomaticGainControlLevelInDb);
1435         parcel.writeString(mCodeType);
1436     }
1437 
1438     @Override
describeContents()1439     public int describeContents() {
1440         return 0;
1441     }
1442 
1443     @Override
toString()1444     public String toString() {
1445         final String format = "   %-29s = %s\n";
1446         final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
1447         StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
1448 
1449         builder.append(String.format(format, "Svid", mSvid));
1450         builder.append(String.format(format, "ConstellationType", mConstellationType));
1451         builder.append(String.format(format, "TimeOffsetNanos", mTimeOffsetNanos));
1452 
1453         builder.append(String.format(format, "State", getStateString()));
1454 
1455         builder.append(String.format(
1456                 formatWithUncertainty,
1457                 "ReceivedSvTimeNanos",
1458                 mReceivedSvTimeNanos,
1459                 "ReceivedSvTimeUncertaintyNanos",
1460                 mReceivedSvTimeUncertaintyNanos));
1461 
1462         builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
1463 
1464         builder.append(String.format(
1465                 formatWithUncertainty,
1466                 "PseudorangeRateMetersPerSecond",
1467                 mPseudorangeRateMetersPerSecond,
1468                 "PseudorangeRateUncertaintyMetersPerSecond",
1469                 mPseudorangeRateUncertaintyMetersPerSecond));
1470 
1471         builder.append(String.format(
1472                 format,
1473                 "AccumulatedDeltaRangeState",
1474                 getAccumulatedDeltaRangeStateString()));
1475 
1476         builder.append(String.format(
1477                 formatWithUncertainty,
1478                 "AccumulatedDeltaRangeMeters",
1479                 mAccumulatedDeltaRangeMeters,
1480                 "AccumulatedDeltaRangeUncertaintyMeters",
1481                 mAccumulatedDeltaRangeUncertaintyMeters));
1482 
1483         builder.append(String.format(
1484                 format,
1485                 "CarrierFrequencyHz",
1486                 hasCarrierFrequencyHz() ? mCarrierFrequencyHz : null));
1487 
1488         builder.append(String.format(
1489                 format,
1490                 "CarrierCycles",
1491                 hasCarrierCycles() ? mCarrierCycles : null));
1492 
1493         builder.append(String.format(
1494                 formatWithUncertainty,
1495                 "CarrierPhase",
1496                 hasCarrierPhase() ? mCarrierPhase : null,
1497                 "CarrierPhaseUncertainty",
1498                 hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
1499 
1500         builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
1501 
1502         builder.append(String.format(
1503                 format,
1504                 "SnrInDb",
1505                 hasSnrInDb() ? mSnrInDb : null));
1506         builder.append(String.format(
1507                 format,
1508                 "AgcLevelDb",
1509                 hasAutomaticGainControlLevelDb() ? mAutomaticGainControlLevelInDb : null));
1510         builder.append(String.format(
1511                 format,
1512                 "CodeType",
1513                 hasCodeType() ? mCodeType : null));
1514 
1515         return builder.toString();
1516     }
1517 
initialize()1518     private void initialize() {
1519         mFlags = HAS_NO_FLAGS;
1520         setSvid(0);
1521         setTimeOffsetNanos(Long.MIN_VALUE);
1522         setState(STATE_UNKNOWN);
1523         setReceivedSvTimeNanos(Long.MIN_VALUE);
1524         setReceivedSvTimeUncertaintyNanos(Long.MAX_VALUE);
1525         setCn0DbHz(Double.MIN_VALUE);
1526         setPseudorangeRateMetersPerSecond(Double.MIN_VALUE);
1527         setPseudorangeRateUncertaintyMetersPerSecond(Double.MIN_VALUE);
1528         setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
1529         setAccumulatedDeltaRangeMeters(Double.MIN_VALUE);
1530         setAccumulatedDeltaRangeUncertaintyMeters(Double.MIN_VALUE);
1531         resetCarrierFrequencyHz();
1532         resetCarrierCycles();
1533         resetCarrierPhase();
1534         resetCarrierPhaseUncertainty();
1535         setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
1536         resetSnrInDb();
1537         resetAutomaticGainControlLevel();
1538         resetCodeType();
1539     }
1540 
setFlag(int flag)1541     private void setFlag(int flag) {
1542         mFlags |= flag;
1543     }
1544 
resetFlag(int flag)1545     private void resetFlag(int flag) {
1546         mFlags &= ~flag;
1547     }
1548 
isFlagSet(int flag)1549     private boolean isFlagSet(int flag) {
1550         return (mFlags & flag) == flag;
1551     }
1552 }
1553