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