• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION;
20 import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH;
21 import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC;
22 import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY;
23 
24 import android.annotation.FloatRange;
25 import android.annotation.IntRange;
26 import android.annotation.NonNull;
27 import android.annotation.Nullable;
28 import android.annotation.SystemApi;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 
32 import com.android.internal.util.Preconditions;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Objects;
37 
38 /**
39  * A container with measurement corrections for a single visible satellite
40  *
41  * @hide
42  */
43 @SystemApi
44 public final class GnssSingleSatCorrection implements Parcelable {
45 
46     private static final int HAS_PROB_SAT_IS_LOS_MASK =
47             SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY;
48     private static final int HAS_COMBINED_EXCESS_PATH_LENGTH_MASK =
49             SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH;
50     private static final int HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK =
51             SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC;
52     private static final int HAS_COMBINED_ATTENUATION_MASK =
53             SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION;
54 
55     /* A bitmask of fields present in this object (see HAS_* constants defined above). */
56     private final int mSingleSatCorrectionFlags;
57 
58     private final int mConstellationType;
59     private final int mSatId;
60     private final float mCarrierFrequencyHz;
61     private final float mProbSatIsLos;
62     private final float mCombinedExcessPathLengthMeters;
63     private final float mCombinedExcessPathLengthUncertaintyMeters;
64     private final float mCombinedAttenuationDb;
65 
66     @NonNull
67     private final List<GnssExcessPathInfo> mGnssExcessPathInfoList;
68 
GnssSingleSatCorrection(int singleSatCorrectionFlags, int constellationType, int satId, float carrierFrequencyHz, float probSatIsLos, float excessPathLengthMeters, float excessPathLengthUncertaintyMeters, float combinedAttenuationDb, @NonNull List<GnssExcessPathInfo> gnssExcessPathInfoList)69     private GnssSingleSatCorrection(int singleSatCorrectionFlags, int constellationType, int satId,
70             float carrierFrequencyHz, float probSatIsLos, float excessPathLengthMeters,
71             float excessPathLengthUncertaintyMeters,
72             float combinedAttenuationDb,
73             @NonNull List<GnssExcessPathInfo> gnssExcessPathInfoList) {
74         mSingleSatCorrectionFlags = singleSatCorrectionFlags;
75         mConstellationType = constellationType;
76         mSatId = satId;
77         mCarrierFrequencyHz = carrierFrequencyHz;
78         mProbSatIsLos = probSatIsLos;
79         mCombinedExcessPathLengthMeters = excessPathLengthMeters;
80         mCombinedExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
81         mCombinedAttenuationDb = combinedAttenuationDb;
82         mGnssExcessPathInfoList = gnssExcessPathInfoList;
83     }
84 
85     /**
86      * Gets a bitmask of fields present in this object.
87      *
88      * @hide
89      */
getSingleSatelliteCorrectionFlags()90     public int getSingleSatelliteCorrectionFlags() {
91         return mSingleSatCorrectionFlags;
92     }
93 
94     /**
95      * Gets the constellation type.
96      *
97      * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link
98      * GnssStatus}.
99      */
100     @GnssStatus.ConstellationType
getConstellationType()101     public int getConstellationType() {
102         return mConstellationType;
103     }
104 
105     /**
106      * Gets the satellite ID.
107      *
108      * <p>Interpretation depends on {@link #getConstellationType()}. See {@link
109      * GnssStatus#getSvid(int)}.
110      */
111     @IntRange(from = 0)
getSatelliteId()112     public int getSatelliteId() {
113         return mSatId;
114     }
115 
116     /**
117      * Gets the carrier frequency of the tracked signal.
118      *
119      * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
120      * L5 = 1176.45 MHz, varying GLO channels, etc.
121      *
122      * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
123      * objects will be reported for this same satellite, in one of the correction objects, all the
124      * values related to L1 will be filled, and in the other all of the values related to L5 will be
125      * filled.
126      *
127      * @return the carrier frequency of the signal tracked in Hz.
128      */
129     @FloatRange(from = 0.0f,  fromInclusive = false)
getCarrierFrequencyHz()130     public float getCarrierFrequencyHz() {
131         return mCarrierFrequencyHz;
132     }
133 
134     /**
135      * Returns the probability that the satellite is in line-of-sight condition at the given
136      * location.
137      */
138     @FloatRange(from = 0.0f, to = 1.0f)
getProbabilityLineOfSight()139     public float getProbabilityLineOfSight() {
140         return mProbSatIsLos;
141     }
142 
143     /**
144      * Returns the combined excess path length to be subtracted from pseudorange before using it in
145      * calculating location.
146      */
147     @FloatRange(from = 0.0f)
getExcessPathLengthMeters()148     public float getExcessPathLengthMeters() {
149         return mCombinedExcessPathLengthMeters;
150     }
151 
152     /** Returns the error estimate (1-sigma) for the combined excess path length estimate. */
153     @FloatRange(from = 0.0f)
getExcessPathLengthUncertaintyMeters()154     public float getExcessPathLengthUncertaintyMeters() {
155         return mCombinedExcessPathLengthUncertaintyMeters;
156     }
157 
158     /**
159      * Returns the combined expected reduction of signal strength for this satellite in
160      * non-negative dB.
161      */
162     @FloatRange(from = 0.0f)
getCombinedAttenuationDb()163     public float getCombinedAttenuationDb() {
164         return mCombinedAttenuationDb;
165     }
166 
167     /**
168      * Returns the reflecting plane characteristics at which the signal has bounced.
169      *
170      * @deprecated Combined excess path does not have a reflecting plane.
171      */
172     @Nullable
173     @Deprecated
getReflectingPlane()174     public GnssReflectingPlane getReflectingPlane() {
175         return null;
176     }
177 
178     /**
179      * Returns the list of {@link GnssExcessPathInfo} associated with this satellite signal.
180      */
181     @NonNull
getGnssExcessPathInfoList()182     public List<GnssExcessPathInfo> getGnssExcessPathInfoList() {
183         return mGnssExcessPathInfoList;
184     }
185 
186     /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */
hasValidSatelliteLineOfSight()187     public boolean hasValidSatelliteLineOfSight() {
188         return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0;
189     }
190 
191     /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */
hasExcessPathLength()192     public boolean hasExcessPathLength() {
193         return (mSingleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_MASK) != 0;
194     }
195 
196     /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */
hasExcessPathLengthUncertainty()197     public boolean hasExcessPathLengthUncertainty() {
198         return (mSingleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK) != 0;
199     }
200 
201     /**
202      * Returns {@code true} if {@link #getReflectingPlane()} is valid.
203      *
204      * @deprecated Combined excess path does not have a reflecting plane.
205      */
206     @Deprecated
hasReflectingPlane()207     public boolean hasReflectingPlane() {
208         return false;
209     }
210 
211     /** Returns {@code true} if {@link #getCombinedAttenuationDb()} is valid. */
hasCombinedAttenuation()212     public boolean hasCombinedAttenuation() {
213         return (mSingleSatCorrectionFlags & HAS_COMBINED_ATTENUATION_MASK) != 0;
214     }
215 
216     @Override
describeContents()217     public int describeContents() {
218         return 0;
219     }
220 
221     @Override
writeToParcel(@onNull Parcel parcel, int flags)222     public void writeToParcel(@NonNull Parcel parcel, int flags) {
223         parcel.writeInt(mSingleSatCorrectionFlags);
224         parcel.writeInt(mConstellationType);
225         parcel.writeInt(mSatId);
226         parcel.writeFloat(mCarrierFrequencyHz);
227         if (hasValidSatelliteLineOfSight()) {
228             parcel.writeFloat(mProbSatIsLos);
229         }
230         if (hasExcessPathLength()) {
231             parcel.writeFloat(mCombinedExcessPathLengthMeters);
232         }
233         if (hasExcessPathLengthUncertainty()) {
234             parcel.writeFloat(mCombinedExcessPathLengthUncertaintyMeters);
235         }
236         if (hasCombinedAttenuation()) {
237             parcel.writeFloat(mCombinedAttenuationDb);
238         }
239         parcel.writeTypedList(mGnssExcessPathInfoList);
240     }
241 
242     public static final Creator<GnssSingleSatCorrection> CREATOR =
243             new Creator<GnssSingleSatCorrection>() {
244                 @Override
245                 @NonNull
246                 public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) {
247                     int singleSatCorrectionFlags = parcel.readInt();
248                     int constellationType = parcel.readInt();
249                     int satId = parcel.readInt();
250                     float carrierFrequencyHz = parcel.readFloat();
251                     float probSatIsLos = (singleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0
252                             ? parcel.readFloat() : 0;
253                     float combinedExcessPathLengthMeters =
254                             (singleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_MASK) != 0
255                                     ? parcel.readFloat() : 0;
256                     float combinedExcessPathLengthUncertaintyMeters =
257                             (singleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK)
258                                     != 0 ? parcel.readFloat() : 0;
259                     float combinedAttenuationDb =
260                             (singleSatCorrectionFlags & HAS_COMBINED_ATTENUATION_MASK) != 0
261                                     ? parcel.readFloat() : 0;
262                     List<GnssExcessPathInfo> gnssExcessPathInfoList = parcel.createTypedArrayList(
263                             GnssExcessPathInfo.CREATOR);
264                     return new GnssSingleSatCorrection(singleSatCorrectionFlags, constellationType,
265                             satId, carrierFrequencyHz, probSatIsLos, combinedExcessPathLengthMeters,
266                             combinedExcessPathLengthUncertaintyMeters, combinedAttenuationDb,
267                             gnssExcessPathInfoList);
268                 }
269 
270                 @Override
271                 public GnssSingleSatCorrection[] newArray(int i) {
272                     return new GnssSingleSatCorrection[i];
273                 }
274             };
275 
276     @Override
equals(Object obj)277     public boolean equals(Object obj) {
278         if (obj instanceof GnssSingleSatCorrection) {
279             GnssSingleSatCorrection that = (GnssSingleSatCorrection) obj;
280             return this.mSingleSatCorrectionFlags == that.mSingleSatCorrectionFlags
281                     && this.mConstellationType == that.mConstellationType
282                     && this.mSatId == that.mSatId
283                     && Float.compare(mCarrierFrequencyHz, that.mCarrierFrequencyHz) == 0
284                     && (!hasValidSatelliteLineOfSight() || Float.compare(mProbSatIsLos,
285                     that.mProbSatIsLos) == 0)
286                     && (!hasExcessPathLength() || Float.compare(mCombinedExcessPathLengthMeters,
287                     that.mCombinedExcessPathLengthMeters) == 0)
288                     && (!hasExcessPathLengthUncertainty() || Float.compare(
289                     mCombinedExcessPathLengthUncertaintyMeters,
290                     that.mCombinedExcessPathLengthUncertaintyMeters) == 0)
291                     && (!hasCombinedAttenuation() || Float.compare(mCombinedAttenuationDb,
292                     that.mCombinedAttenuationDb) == 0)
293                     && mGnssExcessPathInfoList.equals(that.mGnssExcessPathInfoList);
294         }
295         return false;
296     }
297 
298     @Override
hashCode()299     public int hashCode() {
300         return Objects.hash(mSingleSatCorrectionFlags,
301                 mConstellationType,
302                 mSatId,
303                 mCarrierFrequencyHz,
304                 mProbSatIsLos,
305                 mCombinedExcessPathLengthMeters,
306                 mCombinedExcessPathLengthUncertaintyMeters,
307                 mCombinedAttenuationDb,
308                 mGnssExcessPathInfoList);
309     }
310 
311     @NonNull
312     @Override
toString()313     public String toString() {
314         StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:[");
315         builder.append(" ConstellationType=").append(mConstellationType);
316         builder.append(" SatId=").append(mSatId);
317         builder.append(" CarrierFrequencyHz=").append(mCarrierFrequencyHz);
318         if (hasValidSatelliteLineOfSight()) {
319             builder.append(" ProbSatIsLos=").append(mProbSatIsLos);
320         }
321         if (hasExcessPathLength()) {
322             builder.append(" CombinedExcessPathLengthMeters=").append(
323                     mCombinedExcessPathLengthMeters);
324         }
325         if (hasExcessPathLengthUncertainty()) {
326             builder.append(" CombinedExcessPathLengthUncertaintyMeters=").append(
327                     mCombinedExcessPathLengthUncertaintyMeters);
328         }
329         if (hasCombinedAttenuation()) {
330             builder.append(" CombinedAttenuationDb=").append(
331                     mCombinedAttenuationDb);
332         }
333         if (!mGnssExcessPathInfoList.isEmpty()) {
334             builder.append(' ').append(mGnssExcessPathInfoList.toString());
335         }
336         builder.append(']');
337         return builder.toString();
338     }
339 
340     /** Builder for {@link GnssSingleSatCorrection} */
341     public static final class Builder {
342         private int mSingleSatCorrectionFlags;
343         private int mConstellationType;
344         private int mSatId;
345         private float mCarrierFrequencyHz;
346         private float mProbSatIsLos;
347         private float mCombinedExcessPathLengthMeters;
348         private float mCombinedExcessPathLengthUncertaintyMeters;
349         private float mCombinedAttenuationDb;
350         @NonNull
351         private List<GnssExcessPathInfo> mGnssExcessInfoList = new ArrayList<>();
352 
353         /** Sets the constellation type. */
setConstellationType( @nssStatus.ConstellationType int constellationType)354         @NonNull public Builder setConstellationType(
355                 @GnssStatus.ConstellationType int constellationType) {
356             mConstellationType = constellationType;
357             return this;
358         }
359 
360         /** Sets the satellite ID defined in the ICD of the given constellation. */
setSatelliteId(@ntRangefrom = 0) int satId)361         @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) {
362             Preconditions.checkArgumentNonnegative(satId, "satId should be non-negative.");
363             mSatId = satId;
364             return this;
365         }
366 
367         /** Sets the carrier frequency in Hz. */
setCarrierFrequencyHz( @loatRangefrom = 0.0f, fromInclusive = false) float carrierFrequencyHz)368         @NonNull public Builder setCarrierFrequencyHz(
369                 @FloatRange(from = 0.0f,  fromInclusive = false) float carrierFrequencyHz) {
370             Preconditions.checkArgumentInRange(
371                     carrierFrequencyHz, 0, Float.MAX_VALUE, "carrierFrequencyHz");
372             mCarrierFrequencyHz = carrierFrequencyHz;
373             return this;
374         }
375 
376         /**
377          * Sets the line-of-sight probability of the satellite at the given location in the range
378          * between 0 and 1.
379          */
setProbabilityLineOfSight( @loatRangefrom = 0.0f, to = 1.0f) float probSatIsLos)380         @NonNull public Builder setProbabilityLineOfSight(
381                 @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) {
382             Preconditions.checkArgumentInRange(
383                     probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1.");
384             mProbSatIsLos = probSatIsLos;
385             mSingleSatCorrectionFlags |= HAS_PROB_SAT_IS_LOS_MASK;
386             return this;
387         }
388 
389         /**
390          * Clears the line-of-sight probability of the satellite at the given location.
391          *
392          * <p>This is to negate {@link #setProbabilityLineOfSight} call.
393          */
clearProbabilityLineOfSight()394         @NonNull public Builder clearProbabilityLineOfSight() {
395             mProbSatIsLos = 0;
396             mSingleSatCorrectionFlags &= ~HAS_PROB_SAT_IS_LOS_MASK;
397             return this;
398         }
399 
400         /**
401          * Sets the combined excess path length to be subtracted from pseudorange before using it in
402          * calculating location.
403          */
404         @NonNull
setExcessPathLengthMeters( @loatRangefrom = 0.0f) float combinedExcessPathLengthMeters)405         public Builder setExcessPathLengthMeters(
406                 @FloatRange(from = 0.0f) float combinedExcessPathLengthMeters) {
407             Preconditions.checkArgumentInRange(combinedExcessPathLengthMeters, 0, Float.MAX_VALUE,
408                     "excessPathLengthMeters");
409             mCombinedExcessPathLengthMeters = combinedExcessPathLengthMeters;
410             mSingleSatCorrectionFlags |= HAS_COMBINED_EXCESS_PATH_LENGTH_MASK;
411             return this;
412         }
413 
414         /**
415          * Clears the combined excess path length.
416          *
417          * <p>This is to negate {@link #setExcessPathLengthMeters} call.
418          */
clearExcessPathLengthMeters()419         @NonNull public Builder clearExcessPathLengthMeters() {
420             mCombinedExcessPathLengthMeters = 0;
421             mSingleSatCorrectionFlags &= ~HAS_COMBINED_EXCESS_PATH_LENGTH_MASK;
422             return this;
423         }
424 
425         /** Sets the error estimate (1-sigma) for the combined excess path length estimate. */
setExcessPathLengthUncertaintyMeters( @loatRangefrom = 0.0f) float combinedExcessPathLengthUncertaintyMeters)426         @NonNull public Builder setExcessPathLengthUncertaintyMeters(
427                 @FloatRange(from = 0.0f) float combinedExcessPathLengthUncertaintyMeters) {
428             Preconditions.checkArgumentInRange(combinedExcessPathLengthUncertaintyMeters, 0,
429                     Float.MAX_VALUE, "excessPathLengthUncertaintyMeters");
430             mCombinedExcessPathLengthUncertaintyMeters = combinedExcessPathLengthUncertaintyMeters;
431             mSingleSatCorrectionFlags |= HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK;
432             return this;
433         }
434 
435         /**
436          * Clears the error estimate (1-sigma) for the combined excess path length estimate.
437          *
438          * <p>This is to negate {@link #setExcessPathLengthUncertaintyMeters} call.
439          */
clearExcessPathLengthUncertaintyMeters()440         @NonNull public Builder clearExcessPathLengthUncertaintyMeters() {
441             mCombinedExcessPathLengthUncertaintyMeters = 0;
442             mSingleSatCorrectionFlags &= ~HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK;
443             return this;
444         }
445 
446         /**
447          * Sets the combined attenuation in Db.
448          */
setCombinedAttenuationDb( @loatRangefrom = 0.0f) float combinedAttenuationDb)449         @NonNull public Builder setCombinedAttenuationDb(
450                 @FloatRange(from = 0.0f) float combinedAttenuationDb) {
451             Preconditions.checkArgumentInRange(combinedAttenuationDb, 0, Float.MAX_VALUE,
452                     "combinedAttenuationDb");
453             mCombinedAttenuationDb = combinedAttenuationDb;
454             mSingleSatCorrectionFlags |= HAS_COMBINED_ATTENUATION_MASK;
455             return this;
456         }
457 
458         /**
459          * Clears the combined attenuation.
460          *
461          * <p>This is to negate {@link #setCombinedAttenuationDb} call.
462          */
clearCombinedAttenuationDb()463         @NonNull public Builder clearCombinedAttenuationDb() {
464             mCombinedAttenuationDb = 0;
465             mSingleSatCorrectionFlags &= ~HAS_COMBINED_ATTENUATION_MASK;
466             return this;
467         }
468 
469         /**
470          * Sets the reflecting plane information.
471          *
472          * @deprecated Combined excess path does not have a reflecting plane.
473          */
474         @Deprecated
setReflectingPlane(@ullable GnssReflectingPlane reflectingPlane)475         @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) {
476             return this;
477         }
478 
479         /**
480          * Sets the collection of {@link GnssExcessPathInfo}.
481          */
482         @NonNull
setGnssExcessPathInfoList(@onNull List<GnssExcessPathInfo> infoList)483         public Builder setGnssExcessPathInfoList(@NonNull List<GnssExcessPathInfo> infoList) {
484             mGnssExcessInfoList = new ArrayList<>(infoList);
485             return this;
486         }
487 
488         /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */
build()489         @NonNull public GnssSingleSatCorrection build() {
490             return new GnssSingleSatCorrection(mSingleSatCorrectionFlags,
491                     mConstellationType,
492                     mSatId,
493                     mCarrierFrequencyHz,
494                     mProbSatIsLos,
495                     mCombinedExcessPathLengthMeters,
496                     mCombinedExcessPathLengthUncertaintyMeters,
497                     mCombinedAttenuationDb,
498                     mGnssExcessInfoList);
499         }
500     }
501 }
502