1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.location;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Objects;
31 import java.util.concurrent.Executor;
32 
33 /**
34  * GNSS chipset capabilities.
35  */
36 public final class GnssCapabilities implements Parcelable {
37 
38     // IMPORTANT - must match the Capabilities enum in IGnssCallback.hal
39     /** @hide */
40     public static final int TOP_HAL_CAPABILITY_SCHEDULING = 1;
41     /** @hide */
42     public static final int TOP_HAL_CAPABILITY_MSB = 1 << 1;
43     /** @hide */
44     public static final int TOP_HAL_CAPABILITY_MSA = 1 << 2;
45     /** @hide */
46     public static final int TOP_HAL_CAPABILITY_SINGLE_SHOT = 1 << 3;
47     /** @hide */
48     public static final int TOP_HAL_CAPABILITY_ON_DEMAND_TIME = 1 << 4;
49     /** @hide */
50     public static final int TOP_HAL_CAPABILITY_GEOFENCING = 1 << 5;
51     /** @hide */
52     public static final int TOP_HAL_CAPABILITY_MEASUREMENTS = 1 << 6;
53     /** @hide */
54     public static final int TOP_HAL_CAPABILITY_NAV_MESSAGES = 1 << 7;
55     /** @hide */
56     public static final int TOP_HAL_CAPABILITY_LOW_POWER_MODE = 1 << 8;
57     /** @hide */
58     public static final int TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9;
59     /** @hide */
60     public static final int TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS = 1 << 10;
61     /** @hide */
62     public static final int TOP_HAL_CAPABILITY_ANTENNA_INFO = 1 << 11;
63     /** @hide */
64     public static final int TOP_HAL_CAPABILITY_CORRELATION_VECTOR = 1 << 12;
65     /** @hide */
66     public static final int TOP_HAL_CAPABILITY_SATELLITE_PVT = 1 << 13;
67     /** @hide */
68     public static final int TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 1 << 14;
69     /** @hide */
70     public static final int TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE = 1 << 15;
71 
72     /** @hide */
73     @IntDef(flag = true, prefix = {"TOP_HAL_CAPABILITY_"}, value = {TOP_HAL_CAPABILITY_SCHEDULING,
74             TOP_HAL_CAPABILITY_MSB, TOP_HAL_CAPABILITY_MSA, TOP_HAL_CAPABILITY_SINGLE_SHOT,
75             TOP_HAL_CAPABILITY_ON_DEMAND_TIME, TOP_HAL_CAPABILITY_GEOFENCING,
76             TOP_HAL_CAPABILITY_MEASUREMENTS, TOP_HAL_CAPABILITY_NAV_MESSAGES,
77             TOP_HAL_CAPABILITY_LOW_POWER_MODE, TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST,
78             TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS, TOP_HAL_CAPABILITY_ANTENNA_INFO,
79             TOP_HAL_CAPABILITY_CORRELATION_VECTOR, TOP_HAL_CAPABILITY_SATELLITE_PVT,
80             TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING,
81             TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE})
82 
83     @Retention(RetentionPolicy.SOURCE)
84     public @interface TopHalCapabilityFlags {}
85 
86     // IMPORTANT - must match the Capabilities enum in IMeasurementCorrectionsCallback.hal
87     /** @hide */
88     public static final int SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_LOS_SATS = 1;
89     /** @hide */
90     public static final int SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_EXCESS_PATH_LENGTH = 2;
91     /** @hide */
92     public static final int SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_REFLECTING_PLANE = 4;
93 
94     /** @hide */
95     @IntDef(flag = true, prefix = {"SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_"}, value = {
96             SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_LOS_SATS,
97             SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_EXCESS_PATH_LENGTH,
98             SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_REFLECTING_PLANE})
99     @Retention(RetentionPolicy.SOURCE)
100     public @interface SubHalMeasurementCorrectionsCapabilityFlags {}
101 
102     // IMPORATANT - must match values in IGnssPowerIndicationCallback.aidl
103     /** @hide */
104     public static final int SUB_HAL_POWER_CAPABILITY_TOTAL = 1;
105     /** @hide */
106     public static final int SUB_HAL_POWER_CAPABILITY_SINGLEBAND_TRACKING = 2;
107     /** @hide */
108     public static final int SUB_HAL_POWER_CAPABILITY_MULTIBAND_TRACKING = 4;
109     /** @hide */
110     public static final int SUB_HAL_POWER_CAPABILITY_SINGLEBAND_ACQUISITION = 8;
111     /** @hide */
112     public static final int SUB_HAL_POWER_CAPABILITY_MULTIBAND_ACQUISITION = 16;
113     /** @hide */
114     public static final int SUB_HAL_POWER_CAPABILITY_OTHER_MODES = 32;
115 
116     /** @hide */
117     @IntDef(flag = true, prefix = {"SUB_HAL_POWER_CAPABILITY_"}, value = {
118             SUB_HAL_POWER_CAPABILITY_TOTAL, SUB_HAL_POWER_CAPABILITY_SINGLEBAND_TRACKING,
119             SUB_HAL_POWER_CAPABILITY_MULTIBAND_TRACKING,
120             SUB_HAL_POWER_CAPABILITY_SINGLEBAND_ACQUISITION,
121             SUB_HAL_POWER_CAPABILITY_MULTIBAND_ACQUISITION,
122             SUB_HAL_POWER_CAPABILITY_OTHER_MODES})
123     @Retention(RetentionPolicy.SOURCE)
124     public @interface SubHalPowerCapabilityFlags {}
125 
126     /** The capability is unknown to be supported or not. */
127     public static final int CAPABILITY_UNKNOWN = 0;
128     /** The capability is supported. */
129     public static final int CAPABILITY_SUPPORTED = 1;
130     /** The capability is not supported. */
131     public static final int CAPABILITY_UNSUPPORTED = 2;
132 
133     /** @hide */
134     @IntDef(flag = true, prefix = {"CAPABILITY_"}, value = {CAPABILITY_UNKNOWN,
135             CAPABILITY_SUPPORTED,
136             CAPABILITY_UNSUPPORTED})
137     @Retention(RetentionPolicy.SOURCE)
138     public @interface CapabilitySupportType {}
139 
140 
141     /**
142      * Returns an empty GnssCapabilities object.
143      *
144      * @hide
145      */
empty()146     public static GnssCapabilities empty() {
147         return new GnssCapabilities(/*topFlags=*/ 0, /*isAdrCapabilityKnown=*/ false,
148                 /*measurementCorrectionsFlags=*/ 0, /*powerFlags=*/ 0, /*gnssSignalTypes=*/
149                 Collections.emptyList());
150     }
151 
152     private final @TopHalCapabilityFlags int mTopFlags;
153     private final boolean mIsAdrCapabilityKnown;
154     private final @SubHalMeasurementCorrectionsCapabilityFlags int mMeasurementCorrectionsFlags;
155     private final @SubHalPowerCapabilityFlags int mPowerFlags;
156     private final @NonNull List<GnssSignalType> mGnssSignalTypes;
157 
GnssCapabilities( @opHalCapabilityFlags int topFlags, boolean isAdrCapabilityKnown, @SubHalMeasurementCorrectionsCapabilityFlags int measurementCorrectionsFlags, @SubHalPowerCapabilityFlags int powerFlags, @NonNull List<GnssSignalType> gnssSignalTypes)158     private GnssCapabilities(
159             @TopHalCapabilityFlags int topFlags,
160             boolean isAdrCapabilityKnown,
161             @SubHalMeasurementCorrectionsCapabilityFlags int measurementCorrectionsFlags,
162             @SubHalPowerCapabilityFlags int powerFlags,
163             @NonNull List<GnssSignalType> gnssSignalTypes) {
164         Objects.requireNonNull(gnssSignalTypes);
165         mTopFlags = topFlags;
166         mIsAdrCapabilityKnown = isAdrCapabilityKnown;
167         mMeasurementCorrectionsFlags = measurementCorrectionsFlags;
168         mPowerFlags = powerFlags;
169         mGnssSignalTypes = Collections.unmodifiableList(gnssSignalTypes);
170     }
171 
172     /**
173      * Returns a new GnssCapabilities object with top hal values set from the given flags.
174      *
175      * @hide
176      */
withTopHalFlags(@opHalCapabilityFlags int flags, boolean isAdrCapabilityKnown)177     public GnssCapabilities withTopHalFlags(@TopHalCapabilityFlags int flags,
178             boolean isAdrCapabilityKnown) {
179         if (mTopFlags == flags && mIsAdrCapabilityKnown == isAdrCapabilityKnown) {
180             return this;
181         } else {
182             return new GnssCapabilities(flags, isAdrCapabilityKnown,
183                     mMeasurementCorrectionsFlags, mPowerFlags, mGnssSignalTypes);
184         }
185     }
186 
187     /**
188      * Returns a new GnssCapabilities object with gnss measurement corrections sub hal values set
189      * from the given flags.
190      *
191      * @hide
192      */
withSubHalMeasurementCorrectionsFlags( @ubHalMeasurementCorrectionsCapabilityFlags int flags)193     public GnssCapabilities withSubHalMeasurementCorrectionsFlags(
194             @SubHalMeasurementCorrectionsCapabilityFlags int flags) {
195         if (mMeasurementCorrectionsFlags == flags) {
196             return this;
197         } else {
198             return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown, flags, mPowerFlags,
199                     mGnssSignalTypes);
200         }
201     }
202 
203     /**
204      * Returns a new GnssCapabilities object with gnss measurement corrections sub hal values set
205      * from the given flags.
206      *
207      * @hide
208      */
withSubHalPowerFlags(@ubHalPowerCapabilityFlags int flags)209     public GnssCapabilities withSubHalPowerFlags(@SubHalPowerCapabilityFlags int flags) {
210         if (mPowerFlags == flags) {
211             return this;
212         } else {
213             return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown,
214                     mMeasurementCorrectionsFlags, flags, mGnssSignalTypes);
215         }
216     }
217 
218     /**
219      * Returns a new GnssCapabilities object with a list of GnssSignalType.
220      *
221      * @hide
222      */
withSignalTypes(@onNull List<GnssSignalType> gnssSignalTypes)223     public GnssCapabilities withSignalTypes(@NonNull List<GnssSignalType> gnssSignalTypes) {
224         Objects.requireNonNull(gnssSignalTypes);
225         if (mGnssSignalTypes.equals(gnssSignalTypes)) {
226             return this;
227         } else {
228             return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown,
229                     mMeasurementCorrectionsFlags, mPowerFlags, new ArrayList<>(gnssSignalTypes));
230         }
231     }
232 
233     /**
234      * Returns {@code true} if GNSS chipset supports scheduling, {@code false} otherwise.
235      */
hasScheduling()236     public boolean hasScheduling() {
237         return (mTopFlags & TOP_HAL_CAPABILITY_SCHEDULING) != 0;
238     }
239 
240     /**
241      * Returns {@code true} if GNSS chipset supports Mobile Station Based assistance, {@code false}
242      * otherwise.
243      */
hasMsb()244     public boolean hasMsb() {
245         return (mTopFlags & TOP_HAL_CAPABILITY_MSB) != 0;
246     }
247 
248     /**
249      * Returns {@code true} if GNSS chipset supports Mobile Station Assisted assitance,
250      * {@code false} otherwise.
251      */
hasMsa()252     public boolean hasMsa() {
253         return (mTopFlags & TOP_HAL_CAPABILITY_MSA) != 0;
254     }
255 
256     /**
257      * Returns {@code true} if GNSS chipset supports single shot locating, {@code false} otherwise.
258      */
hasSingleShotFix()259     public boolean hasSingleShotFix() {
260         return (mTopFlags & TOP_HAL_CAPABILITY_SINGLE_SHOT) != 0;
261     }
262 
263     /**
264      * Returns {@code true} if GNSS chipset requests periodic time signal injection from the
265      * platform in addition to on-demand and occasional time updates, {@code false} otherwise.
266      *
267      * <p><em>Note: The naming of this capability and the behavior it controls differ substantially.
268      * This is the result of a historic implementation bug, b/73893222.</em>
269      */
hasOnDemandTime()270     public boolean hasOnDemandTime() {
271         return (mTopFlags & TOP_HAL_CAPABILITY_ON_DEMAND_TIME) != 0;
272     }
273 
274     /**
275      * Returns {@code true} if GNSS chipset supports geofencing, {@code false} otherwise.
276      */
hasGeofencing()277     public boolean hasGeofencing() {
278         return (mTopFlags & TOP_HAL_CAPABILITY_GEOFENCING) != 0;
279     }
280 
281     /**
282      * Returns {@code true} if GNSS chipset supports measurements, {@code false} otherwise.
283      *
284      * @see LocationManager#registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback)
285      */
hasMeasurements()286     public boolean hasMeasurements() {
287         return (mTopFlags & TOP_HAL_CAPABILITY_MEASUREMENTS) != 0;
288     }
289 
290     /**
291      * Returns {@code true} if GNSS chipset supports navigation messages, {@code false} otherwise.
292      *
293      * @deprecated Use {@link #hasNavigationMessages()} instead.
294      *
295      * @hide
296      */
297     @Deprecated
298     @SystemApi
hasNavMessages()299     public boolean hasNavMessages() {
300         return hasNavigationMessages();
301     }
302 
303     /**
304      * Returns {@code true} if GNSS chipset supports navigation messages, {@code false} otherwise.
305      *
306      * @see LocationManager#registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)
307      */
hasNavigationMessages()308     public boolean hasNavigationMessages() {
309         return (mTopFlags & TOP_HAL_CAPABILITY_NAV_MESSAGES) != 0;
310     }
311 
312     /**
313      * Returns {@code true} if GNSS chipset supports low power mode, {@code false} otherwise.
314      *
315      * <p>The low power mode is defined in GNSS HAL. When the low power mode is active, the GNSS
316      * hardware must make strong tradeoffs to substantially restrict power use.
317      */
hasLowPowerMode()318     public boolean hasLowPowerMode() {
319         return (mTopFlags & TOP_HAL_CAPABILITY_LOW_POWER_MODE) != 0;
320     }
321 
322     /**
323      * Returns {@code true} if GNSS chipset supports satellite blocklists, {@code false} otherwise.
324      *
325      * @deprecated Use {@link #hasSatelliteBlocklist} instead.
326      *
327      * @hide
328      */
329     @SystemApi
330     @Deprecated
hasSatelliteBlacklist()331     public boolean hasSatelliteBlacklist() {
332         return (mTopFlags & TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST) != 0;
333     }
334 
335     /**
336      * Returns {@code true} if GNSS chipset supports satellite blocklists, {@code false} otherwise.
337      */
hasSatelliteBlocklist()338     public boolean hasSatelliteBlocklist() {
339         return (mTopFlags & TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST) != 0;
340     }
341 
342     /**
343      * Returns {@code true} if GNSS chipset supports satellite PVT, {@code false} otherwise.
344      */
hasSatellitePvt()345     public boolean hasSatellitePvt() {
346         return (mTopFlags & TOP_HAL_CAPABILITY_SATELLITE_PVT) != 0;
347     }
348 
349     /**
350      * Returns {@code true} if GNSS chipset supports measurement corrections, {@code false}
351      * otherwise.
352      */
hasMeasurementCorrections()353     public boolean hasMeasurementCorrections() {
354         return (mTopFlags & TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS) != 0;
355     }
356 
357     /**
358      * Returns {@code true} if GNSS chipset supports antenna info, {@code false} otherwise.
359      *
360      * @deprecated Use {@link #hasAntennaInfo()} instead.
361      */
362     @Deprecated
hasGnssAntennaInfo()363     public boolean hasGnssAntennaInfo() {
364         return hasAntennaInfo();
365     }
366 
367     /**
368      * Returns {@code true} if GNSS chipset supports antenna info, {@code false} otherwise.
369      *
370      * @see LocationManager#registerAntennaInfoListener(Executor, GnssAntennaInfo.Listener)
371      */
hasAntennaInfo()372     public boolean hasAntennaInfo() {
373         return (mTopFlags & TOP_HAL_CAPABILITY_ANTENNA_INFO) != 0;
374     }
375 
376     /**
377      * Returns {@code true} if GNSS chipset supports correlation vectors as part of measurements
378      * outputs, {@code false} otherwise.
379      */
hasMeasurementCorrelationVectors()380     public boolean hasMeasurementCorrelationVectors() {
381         return (mTopFlags & TOP_HAL_CAPABILITY_CORRELATION_VECTOR) != 0;
382     }
383 
384     /**
385      * Returns {@code true} if GNSS chipset will benefit from measurement corrections for driving
386      * use case if provided, {@code false} otherwise.
387      */
hasMeasurementCorrectionsForDriving()388     public boolean hasMeasurementCorrectionsForDriving() {
389         return (mTopFlags & TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING) != 0;
390     }
391 
392     /**
393      * Returns {@link #CAPABILITY_SUPPORTED} if GNSS chipset supports accumulated delta
394      * range, {@link #CAPABILITY_UNSUPPORTED} if GNSS chipset does not support accumulated
395      * delta range, and {@link #CAPABILITY_UNKNOWN} if it is unknown, which means GNSS
396      * chipset may or may not support accumulated delta range.
397      *
398      * <p>The accumulated delta range information can be queried in
399      * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeState()},
400      * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeMeters()}, and
401      * {@link android.location.GnssMeasurement#getAccumulatedDeltaRangeUncertaintyMeters()}.
402      */
hasAccumulatedDeltaRange()403     public @CapabilitySupportType int hasAccumulatedDeltaRange() {
404         if (!mIsAdrCapabilityKnown) {
405             return CAPABILITY_UNKNOWN;
406         }
407         if ((mTopFlags & TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE) != 0) {
408             return CAPABILITY_SUPPORTED;
409         } else {
410             return CAPABILITY_UNSUPPORTED;
411         }
412     }
413 
414     /**
415      * Returns {@code true} if GNSS chipset supports line-of-sight satellite identification
416      * measurement corrections, {@code false} otherwise.
417      */
hasMeasurementCorrectionsLosSats()418     public boolean hasMeasurementCorrectionsLosSats() {
419         return (mMeasurementCorrectionsFlags & SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_LOS_SATS)
420                 != 0;
421     }
422 
423     /**
424      * Returns {@code true} if GNSS chipset supports per satellite excess-path-length measurement
425      * corrections, {@code false} otherwise.
426      */
hasMeasurementCorrectionsExcessPathLength()427     public boolean hasMeasurementCorrectionsExcessPathLength() {
428         return (mMeasurementCorrectionsFlags
429                 & SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_EXCESS_PATH_LENGTH) != 0;
430     }
431 
432     /**
433      * Returns {@code true} if GNSS chipset supports reflecting plane measurement corrections,
434      * {@code false} otherwise.
435      *
436      * @deprecated Use {@link #hasMeasurementCorrectionsReflectingPlane()} instead.
437      *
438      * @hide
439      */
440     @SystemApi
hasMeasurementCorrectionsReflectingPane()441     public boolean hasMeasurementCorrectionsReflectingPane() {
442         return hasMeasurementCorrectionsReflectingPlane();
443     }
444 
445     /**
446      * Returns {@code true} if GNSS chipset supports reflecting plane measurement corrections,
447      * {@code false} otherwise.
448      */
hasMeasurementCorrectionsReflectingPlane()449     public boolean hasMeasurementCorrectionsReflectingPlane() {
450         return (mMeasurementCorrectionsFlags
451                 & SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_REFLECTING_PLANE) != 0;
452     }
453 
454     /**
455      * Returns {@code true} if GNSS chipset supports measuring power totals, {@code false}
456      * otherwise.
457      */
hasPowerTotal()458     public boolean hasPowerTotal() {
459         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_TOTAL) != 0;
460     }
461 
462     /**
463      * Returns {@code true} if GNSS chipset supports measuring single-band tracking power,
464      * {@code false} otherwise.
465      */
hasPowerSinglebandTracking()466     public boolean hasPowerSinglebandTracking() {
467         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_SINGLEBAND_TRACKING) != 0;
468     }
469 
470     /**
471      * Returns {@code true} if GNSS chipset supports measuring multi-band tracking power,
472      * {@code false} otherwise.
473      */
hasPowerMultibandTracking()474     public boolean hasPowerMultibandTracking() {
475         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_MULTIBAND_TRACKING) != 0;
476     }
477 
478     /**
479      * Returns {@code true} if GNSS chipset supports measuring single-band acquisition power,
480      * {@code false} otherwise.
481      */
hasPowerSinglebandAcquisition()482     public boolean hasPowerSinglebandAcquisition() {
483         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_SINGLEBAND_ACQUISITION) != 0;
484     }
485 
486     /**
487      * Returns {@code true} if GNSS chipset supports measuring multi-band acquisition power,
488      * {@code false} otherwise.
489      */
hasPowerMultibandAcquisition()490     public boolean hasPowerMultibandAcquisition() {
491         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_MULTIBAND_ACQUISITION) != 0;
492     }
493 
494     /**
495      * Returns {@code true} if GNSS chipset supports measuring OEM defined mode power, {@code false}
496      * otherwise.
497      */
hasPowerOtherModes()498     public boolean hasPowerOtherModes() {
499         return (mPowerFlags & SUB_HAL_POWER_CAPABILITY_OTHER_MODES) != 0;
500     }
501 
502     /**
503      * Returns the list of {@link GnssSignalType}s that the GNSS chipset supports.
504      */
505     @NonNull
getGnssSignalTypes()506     public List<GnssSignalType> getGnssSignalTypes() {
507         return mGnssSignalTypes;
508     }
509 
510     @Override
equals(Object o)511     public boolean equals(Object o) {
512         if (this == o) {
513             return true;
514         }
515         if (!(o instanceof GnssCapabilities)) {
516             return false;
517         }
518 
519         GnssCapabilities that = (GnssCapabilities) o;
520         return mTopFlags == that.mTopFlags
521                 && mIsAdrCapabilityKnown == that.mIsAdrCapabilityKnown
522                 && mMeasurementCorrectionsFlags == that.mMeasurementCorrectionsFlags
523                 && mPowerFlags == that.mPowerFlags
524                 && mGnssSignalTypes.equals(that.mGnssSignalTypes);
525     }
526 
527     @Override
hashCode()528     public int hashCode() {
529         return Objects.hash(mTopFlags, mIsAdrCapabilityKnown, mMeasurementCorrectionsFlags,
530                 mPowerFlags, mGnssSignalTypes);
531     }
532 
533     public static final @NonNull Creator<GnssCapabilities> CREATOR =
534             new Creator<GnssCapabilities>() {
535                 @Override
536                 public GnssCapabilities createFromParcel(Parcel in) {
537                     return new GnssCapabilities(in.readInt(), in.readBoolean(), in.readInt(),
538                             in.readInt(), in.createTypedArrayList(GnssSignalType.CREATOR));
539                 }
540 
541                 @Override
542                 public GnssCapabilities[] newArray(int size) {
543                     return new GnssCapabilities[size];
544                 }
545             };
546 
547     @Override
describeContents()548     public int describeContents() {
549         return 0;
550     }
551 
552     @Override
writeToParcel(@onNull Parcel parcel, int flags)553     public void writeToParcel(@NonNull Parcel parcel, int flags) {
554         parcel.writeInt(mTopFlags);
555         parcel.writeBoolean(mIsAdrCapabilityKnown);
556         parcel.writeInt(mMeasurementCorrectionsFlags);
557         parcel.writeInt(mPowerFlags);
558         parcel.writeTypedList(mGnssSignalTypes);
559     }
560 
561     @Override
toString()562     public String toString() {
563         StringBuilder builder = new StringBuilder();
564         builder.append("[");
565         if (hasScheduling()) {
566             builder.append("SCHEDULING ");
567         }
568         if (hasMsb()) {
569             builder.append("MSB ");
570         }
571         if (hasMsa()) {
572             builder.append("MSA ");
573         }
574         if (hasSingleShotFix()) {
575             builder.append("SINGLE_SHOT ");
576         }
577         if (hasOnDemandTime()) {
578             builder.append("ON_DEMAND_TIME ");
579         }
580         if (hasGeofencing()) {
581             builder.append("GEOFENCING ");
582         }
583         if (hasMeasurementCorrections()) {
584             builder.append("MEASUREMENTS ");
585         }
586         if (hasNavigationMessages()) {
587             builder.append("NAVIGATION_MESSAGES ");
588         }
589         if (hasLowPowerMode()) {
590             builder.append("LOW_POWER_MODE ");
591         }
592         if (hasSatelliteBlocklist()) {
593             builder.append("SATELLITE_BLOCKLIST ");
594         }
595         if (hasSatellitePvt()) {
596             builder.append("SATELLITE_PVT ");
597         }
598         if (hasMeasurementCorrections()) {
599             builder.append("MEASUREMENT_CORRECTIONS ");
600         }
601         if (hasAntennaInfo()) {
602             builder.append("ANTENNA_INFO ");
603         }
604         if (hasMeasurementCorrelationVectors()) {
605             builder.append("MEASUREMENT_CORRELATION_VECTORS ");
606         }
607         if (hasMeasurementCorrectionsForDriving()) {
608             builder.append("MEASUREMENT_CORRECTIONS_FOR_DRIVING ");
609         }
610         if (hasAccumulatedDeltaRange() == CAPABILITY_SUPPORTED) {
611             builder.append("ACCUMULATED_DELTA_RANGE ");
612         } else if (hasAccumulatedDeltaRange() == CAPABILITY_UNKNOWN) {
613             builder.append("ACCUMULATED_DELTA_RANGE(unknown) ");
614         }
615         if (hasMeasurementCorrectionsLosSats()) {
616             builder.append("LOS_SATS ");
617         }
618         if (hasMeasurementCorrectionsExcessPathLength()) {
619             builder.append("EXCESS_PATH_LENGTH ");
620         }
621         if (hasMeasurementCorrectionsReflectingPlane()) {
622             builder.append("REFLECTING_PLANE ");
623         }
624         if (hasPowerTotal()) {
625             builder.append("TOTAL_POWER ");
626         }
627         if (hasPowerSinglebandTracking()) {
628             builder.append("SINGLEBAND_TRACKING_POWER ");
629         }
630         if (hasPowerMultibandTracking()) {
631             builder.append("MULTIBAND_TRACKING_POWER ");
632         }
633         if (hasPowerSinglebandAcquisition()) {
634             builder.append("SINGLEBAND_ACQUISITION_POWER ");
635         }
636         if (hasPowerMultibandAcquisition()) {
637             builder.append("MULTIBAND_ACQUISITION_POWER ");
638         }
639         if (hasPowerOtherModes()) {
640             builder.append("OTHER_MODES_POWER ");
641         }
642         if (!mGnssSignalTypes.isEmpty()) {
643             builder.append("signalTypes=").append(mGnssSignalTypes).append(" ");
644         }
645         if (builder.length() > 1) {
646             builder.setLength(builder.length() - 1);
647         } else {
648             builder.append("NONE");
649         }
650         builder.append("]");
651         return builder.toString();
652     }
653 
654     /**
655      * Builder for GnssCapabilities.
656      */
657     public static final class Builder {
658 
659         private @TopHalCapabilityFlags int mTopFlags;
660         private boolean mIsAdrCapabilityKnown;
661         private @SubHalMeasurementCorrectionsCapabilityFlags int mMeasurementCorrectionsFlags;
662         private @SubHalPowerCapabilityFlags int mPowerFlags;
663         private @NonNull List<GnssSignalType> mGnssSignalTypes;
664 
Builder()665         public Builder() {
666             mTopFlags = 0;
667             mIsAdrCapabilityKnown = false;
668             mMeasurementCorrectionsFlags = 0;
669             mPowerFlags = 0;
670             mGnssSignalTypes = Collections.emptyList();
671         }
672 
Builder(@onNull GnssCapabilities capabilities)673         public Builder(@NonNull GnssCapabilities capabilities) {
674             mTopFlags = capabilities.mTopFlags;
675             mIsAdrCapabilityKnown = capabilities.mIsAdrCapabilityKnown;
676             mMeasurementCorrectionsFlags = capabilities.mMeasurementCorrectionsFlags;
677             mPowerFlags = capabilities.mPowerFlags;
678             mGnssSignalTypes = capabilities.mGnssSignalTypes;
679         }
680 
681         /**
682          * Sets scheduling capability.
683          */
setHasScheduling(boolean capable)684         public @NonNull Builder setHasScheduling(boolean capable) {
685             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_SCHEDULING, capable);
686             return this;
687         }
688 
689         /**
690          * Sets Mobile Station Based capability.
691          */
setHasMsb(boolean capable)692         public @NonNull Builder setHasMsb(boolean capable) {
693             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MSB, capable);
694             return this;
695         }
696 
697         /**
698          * Sets Mobile Station Assisted capability.
699          */
setHasMsa(boolean capable)700         public @NonNull Builder setHasMsa(boolean capable) {
701             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MSA, capable);
702             return this;
703         }
704 
705         /**
706          * Sets single shot locating capability.
707          */
setHasSingleShotFix(boolean capable)708         public @NonNull Builder setHasSingleShotFix(boolean capable) {
709             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_SINGLE_SHOT, capable);
710             return this;
711         }
712 
713         /**
714          * Sets on demand time capability.
715          */
setHasOnDemandTime(boolean capable)716         public @NonNull Builder setHasOnDemandTime(boolean capable) {
717             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ON_DEMAND_TIME, capable);
718             return this;
719         }
720 
721         /**
722          * Sets geofencing capability.
723          */
setHasGeofencing(boolean capable)724         public @NonNull Builder setHasGeofencing(boolean capable) {
725             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_GEOFENCING, capable);
726             return this;
727         }
728 
729         /**
730          * Sets measurements capability.
731          */
setHasMeasurements(boolean capable)732         public @NonNull Builder setHasMeasurements(boolean capable) {
733             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MEASUREMENTS, capable);
734             return this;
735         }
736 
737         /**
738          * Sets navigation messages capability.
739          */
setHasNavigationMessages(boolean capable)740         public @NonNull Builder setHasNavigationMessages(boolean capable) {
741             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_NAV_MESSAGES, capable);
742             return this;
743         }
744 
745         /**
746          * Sets low power mode capability.
747          *
748          * <p>The low power mode is defined in GNSS HAL. When the low power mode is active, the GNSS
749          * hardware must make strong tradeoffs to substantially restrict power use.
750          */
setHasLowPowerMode(boolean capable)751         public @NonNull Builder setHasLowPowerMode(boolean capable) {
752             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_LOW_POWER_MODE, capable);
753             return this;
754         }
755 
756         /**
757          * Sets satellite blocklist capability.
758          */
setHasSatelliteBlocklist(boolean capable)759         public @NonNull Builder setHasSatelliteBlocklist(boolean capable) {
760             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST, capable);
761             return this;
762         }
763 
764         /**
765          * Sets satellite PVT capability.
766          */
setHasSatellitePvt(boolean capable)767         public @NonNull Builder setHasSatellitePvt(boolean capable) {
768             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_SATELLITE_PVT, capable);
769             return this;
770         }
771 
772         /**
773          * Sets measurement corrections capability.
774          */
setHasMeasurementCorrections(boolean capable)775         public @NonNull Builder setHasMeasurementCorrections(boolean capable) {
776             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS, capable);
777             return this;
778         }
779 
780         /**
781          * Sets antenna info capability.
782          */
setHasAntennaInfo(boolean capable)783         public @NonNull Builder setHasAntennaInfo(boolean capable) {
784             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ANTENNA_INFO, capable);
785             return this;
786         }
787 
788         /**
789          * Sets correlation vector capability.
790          */
setHasMeasurementCorrelationVectors(boolean capable)791         public @NonNull Builder setHasMeasurementCorrelationVectors(boolean capable) {
792             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_CORRELATION_VECTOR, capable);
793             return this;
794         }
795 
796         /**
797          * Sets measurement corrections for driving capability.
798          */
setHasMeasurementCorrectionsForDriving(boolean capable)799         public @NonNull Builder setHasMeasurementCorrectionsForDriving(boolean capable) {
800             mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING,
801                     capable);
802             return this;
803         }
804 
805         /**
806          * Sets accumulated delta range capability.
807          */
setHasAccumulatedDeltaRange(@apabilitySupportType int capable)808         public @NonNull Builder setHasAccumulatedDeltaRange(@CapabilitySupportType int capable) {
809             if (capable == CAPABILITY_UNKNOWN) {
810                 mIsAdrCapabilityKnown = false;
811                 mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE, false);
812             } else if (capable == CAPABILITY_SUPPORTED) {
813                 mIsAdrCapabilityKnown = true;
814                 mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE, true);
815             } else if (capable == CAPABILITY_UNSUPPORTED) {
816                 mIsAdrCapabilityKnown = true;
817                 mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_ACCUMULATED_DELTA_RANGE, false);
818             }
819             return this;
820         }
821 
822         /**
823          * Sets measurement corrections line-of-sight satellites capability.
824          */
setHasMeasurementCorrectionsLosSats(boolean capable)825         public @NonNull Builder setHasMeasurementCorrectionsLosSats(boolean capable) {
826             mMeasurementCorrectionsFlags = setFlag(mMeasurementCorrectionsFlags,
827                     SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_LOS_SATS, capable);
828             return this;
829         }
830 
831         /**
832          * Sets measurement corrections excess path length capability.
833          */
setHasMeasurementCorrectionsExcessPathLength(boolean capable)834         public @NonNull Builder setHasMeasurementCorrectionsExcessPathLength(boolean capable) {
835             mMeasurementCorrectionsFlags = setFlag(mMeasurementCorrectionsFlags,
836                     SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_EXCESS_PATH_LENGTH, capable);
837             return this;
838         }
839 
840         /**
841          * Sets measurement corrections reflecting plane capability.
842          */
setHasMeasurementCorrectionsReflectingPlane(boolean capable)843         public @NonNull Builder setHasMeasurementCorrectionsReflectingPlane(boolean capable) {
844             mMeasurementCorrectionsFlags = setFlag(mMeasurementCorrectionsFlags,
845                     SUB_HAL_MEASUREMENT_CORRECTIONS_CAPABILITY_REFLECTING_PLANE, capable);
846             return this;
847         }
848 
849         /**
850          * Sets power totals capability.
851          */
setHasPowerTotal(boolean capable)852         public @NonNull Builder setHasPowerTotal(boolean capable) {
853             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_TOTAL, capable);
854             return this;
855         }
856 
857         /**
858          * Sets power single-band tracking capability.
859          */
setHasPowerSinglebandTracking(boolean capable)860         public @NonNull Builder setHasPowerSinglebandTracking(boolean capable) {
861             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_SINGLEBAND_TRACKING,
862                     capable);
863             return this;
864         }
865 
866         /**
867          * Sets power multi-band tracking capability.
868          */
setHasPowerMultibandTracking(boolean capable)869         public @NonNull Builder setHasPowerMultibandTracking(boolean capable) {
870             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_MULTIBAND_TRACKING,
871                     capable);
872             return this;
873         }
874 
875         /**
876          * Sets power single-band acquisition capability.
877          */
setHasPowerSinglebandAcquisition(boolean capable)878         public @NonNull Builder setHasPowerSinglebandAcquisition(boolean capable) {
879             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_SINGLEBAND_ACQUISITION,
880                     capable);
881             return this;
882         }
883 
884         /**
885          * Sets power multi-band acquisition capability.
886          */
setHasPowerMultibandAcquisition(boolean capable)887         public @NonNull Builder setHasPowerMultibandAcquisition(boolean capable) {
888             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_MULTIBAND_ACQUISITION,
889                     capable);
890             return this;
891         }
892 
893         /**
894          * Sets OEM-defined power modes capability.
895          */
setHasPowerOtherModes(boolean capable)896         public @NonNull Builder setHasPowerOtherModes(boolean capable) {
897             mPowerFlags = setFlag(mPowerFlags, SUB_HAL_POWER_CAPABILITY_OTHER_MODES, capable);
898             return this;
899         }
900 
901         /**
902          * Sets a list of {@link GnssSignalType}.
903          */
setGnssSignalTypes(@onNull List<GnssSignalType> gnssSignalTypes)904         public @NonNull Builder setGnssSignalTypes(@NonNull List<GnssSignalType> gnssSignalTypes) {
905             mGnssSignalTypes = gnssSignalTypes;
906             return this;
907         }
908 
909         /**
910          * Builds a new GnssCapabilities.
911          */
build()912         public @NonNull GnssCapabilities build() {
913             return new GnssCapabilities(mTopFlags, mIsAdrCapabilityKnown,
914                     mMeasurementCorrectionsFlags, mPowerFlags, new ArrayList<>(mGnssSignalTypes));
915         }
916 
setFlag(int value, int flag, boolean set)917         private static int setFlag(int value, int flag, boolean set) {
918             if (set) {
919                 return value | flag;
920             } else {
921                 return value & ~flag;
922             }
923         }
924     }
925 }
926