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