1 /*
2  * Copyright (C) 2020 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.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.SystemApi;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.util.TimeUtils;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.util.Objects;
29 
30 /**
31  * This class contains extra parameters to pass in a GNSS measurement request.
32  */
33 public final class GnssMeasurementRequest implements Parcelable {
34     /**
35      * Represents a passive only request. Such a request will not trigger any active GNSS
36      * measurements or power usage itself, but may receive GNSS measurements generated in response
37      * to other requests.
38      *
39      * <p class="note">Note that on Android T, such a request will trigger one GNSS measurement.
40      * Another GNSS measurement will be triggered after {@link #PASSIVE_INTERVAL} and so on.
41      *
42      * @see GnssMeasurementRequest#getIntervalMillis()
43      */
44     public static final int PASSIVE_INTERVAL = Integer.MAX_VALUE;
45 
46     private final boolean mCorrelationVectorOutputsEnabled;
47     private final boolean mFullTracking;
48     private final int mIntervalMillis;
49 
50     /**
51      * Creates a {@link GnssMeasurementRequest} with a full list of parameters.
52      */
GnssMeasurementRequest(boolean fullTracking, boolean correlationVectorOutputsEnabled, int intervalMillis)53     private GnssMeasurementRequest(boolean fullTracking, boolean correlationVectorOutputsEnabled,
54             int intervalMillis) {
55         mFullTracking = fullTracking;
56         mCorrelationVectorOutputsEnabled = correlationVectorOutputsEnabled;
57         mIntervalMillis = intervalMillis;
58     }
59 
60     /**
61      * Represents whether to enable correlation vector outputs.
62      *
63      * <p>If true, enable correlation vectors as part of the raw GNSS measurements outputs.
64      * If false, disable correlation vectors.
65      *
66      * @hide
67      */
68     @SystemApi
isCorrelationVectorOutputsEnabled()69     public boolean isCorrelationVectorOutputsEnabled() {
70         return mCorrelationVectorOutputsEnabled;
71     }
72 
73     /**
74      * Represents whether to enable full GNSS tracking.
75      *
76      * <p>If true, GNSS chipset switches off duty cycling. In such a mode, no clock
77      * discontinuities are expected, and when supported, carrier phase should be continuous in
78      * good signal conditions. All non-blocklisted, healthy constellations, satellites and
79      * frequency bands that are meaningful to positioning accuracy must be tracked and reported in
80      * this mode. The GNSS chipset will consume more power in full tracking mode than in duty
81      * cycling mode. If false, GNSS chipset optimizes power via duty cycling, constellations and
82      * frequency limits, etc.
83      *
84      * <p>Full GNSS tracking mode affects GnssMeasurement and other GNSS functionalities
85      * including GNSS location.
86      */
isFullTracking()87     public boolean isFullTracking() {
88         return mFullTracking;
89     }
90 
91     /**
92      * Returns the requested time interval between the reported measurements in milliseconds, or
93      * {@link #PASSIVE_INTERVAL} if this is a passive, no power request. A passive request will not
94      * actively generate GNSS measurement updates, but may receive GNSS measurement updates
95      * generated as a result of other GNSS measurement requests.
96      *
97      * <p>If the time interval is not set, the default value is 0, which means the fastest rate the
98      * GNSS chipset can report.
99      *
100      * <p>The GNSS chipset may report measurements with a rate faster than requested.
101      *
102      * <p class="note">Note that on Android T, a request interval of {@link #PASSIVE_INTERVAL}
103      * will first trigger one GNSS measurement. Another GNSS measurement will be triggered after
104      * {@link #PASSIVE_INTERVAL} milliseconds ans so on.
105      */
getIntervalMillis()106     public @IntRange(from = 0) int getIntervalMillis() {
107         return mIntervalMillis;
108     }
109 
110     @NonNull
111     public static final Creator<GnssMeasurementRequest> CREATOR =
112             new Creator<GnssMeasurementRequest>() {
113                 @Override
114                 @NonNull
115                 public GnssMeasurementRequest createFromParcel(@NonNull Parcel parcel) {
116                     return new GnssMeasurementRequest(parcel.readBoolean(), parcel.readBoolean(),
117                             parcel.readInt());
118                 }
119 
120                 @Override
121                 public GnssMeasurementRequest[] newArray(int i) {
122                     return new GnssMeasurementRequest[i];
123                 }
124             };
125 
126     @Override
writeToParcel(@onNull Parcel parcel, int flags)127     public void writeToParcel(@NonNull Parcel parcel, int flags) {
128         parcel.writeBoolean(mFullTracking);
129         parcel.writeBoolean(mCorrelationVectorOutputsEnabled);
130         parcel.writeInt(mIntervalMillis);
131     }
132 
133     @NonNull
134     @Override
toString()135     public String toString() {
136         StringBuilder s = new StringBuilder();
137         s.append("GnssMeasurementRequest[");
138         s.append("@");
139         TimeUtils.formatDuration(mIntervalMillis, s);
140         if (mFullTracking) {
141             s.append(", FullTracking");
142         }
143         if (mCorrelationVectorOutputsEnabled) {
144             s.append(", CorrelationVectorOutputs");
145         }
146         s.append(']');
147         return s.toString();
148     }
149 
150     @Override
equals(Object obj)151     public boolean equals(Object obj) {
152         if (this == obj) return true;
153         if (obj == null) return false;
154         if (!(obj instanceof GnssMeasurementRequest)) return false;
155 
156         GnssMeasurementRequest other = (GnssMeasurementRequest) obj;
157         if (mFullTracking != other.mFullTracking) return false;
158         if (mCorrelationVectorOutputsEnabled != other.mCorrelationVectorOutputsEnabled) {
159             return false;
160         }
161         if (mIntervalMillis != other.mIntervalMillis) {
162             return false;
163         }
164         return true;
165     }
166 
167     @Override
hashCode()168     public int hashCode() {
169         return Objects.hash(mFullTracking, mCorrelationVectorOutputsEnabled, mIntervalMillis);
170     }
171 
172     @Override
describeContents()173     public int describeContents() {
174         return 0;
175     }
176 
177     /** Builder for {@link GnssMeasurementRequest} */
178     public static final class Builder {
179         private boolean mCorrelationVectorOutputsEnabled;
180         private boolean mFullTracking;
181         private int mIntervalMillis;
182 
183         /**
184          * Constructs a {@link Builder} instance.
185          */
Builder()186         public Builder() {
187         }
188 
189         /**
190          * Constructs a {@link Builder} instance by copying a {@link GnssMeasurementRequest}.
191          */
Builder(@onNull GnssMeasurementRequest request)192         public Builder(@NonNull GnssMeasurementRequest request) {
193             mCorrelationVectorOutputsEnabled = request.isCorrelationVectorOutputsEnabled();
194             mFullTracking = request.isFullTracking();
195             mIntervalMillis = request.getIntervalMillis();
196         }
197 
198         /**
199          * Set the value of whether to enable correlation vector outputs, which is false by default.
200          *
201          * <p>If true, enable correlation vectors as part of the raw GNSS measurements outputs.
202          * If false, disable correlation vectors.
203          *
204          * @hide
205          */
206         @SystemApi
setCorrelationVectorOutputsEnabled(boolean value)207         @NonNull public Builder setCorrelationVectorOutputsEnabled(boolean value) {
208             mCorrelationVectorOutputsEnabled = value;
209             return this;
210         }
211 
212         /**
213          * Set the value of whether to enable full GNSS tracking, which is false by default.
214          *
215          * <p>If true, GNSS chipset switches off duty cycling. In such a mode, no clock
216          * discontinuities are expected, and when supported, carrier phase should be continuous in
217          * good signal conditions. All non-blocklisted, healthy constellations, satellites and
218          * frequency bands that the chipset supports must be reported in this mode. The GNSS chipset
219          * will consume more power in full tracking mode than in duty cycling mode. If false,
220          * GNSS chipset optimizes power via duty cycling, constellations and frequency limits, etc.
221          *
222          * <p>Full GNSS tracking mode affects GnssMeasurement and other GNSS functionalities
223          * including GNSS location.
224          *
225          * <p>Full tracking requests always override non-full tracking requests. If any full
226          * tracking request occurs, all listeners on the device will receive full tracking GNSS
227          * measurements.
228          */
setFullTracking(boolean value)229         @NonNull public Builder setFullTracking(boolean value) {
230             mFullTracking = value;
231             return this;
232         }
233 
234         /**
235          * Set the time interval between the reported measurements in milliseconds, which is 0 by
236          * default. The request interval may be set to {@link #PASSIVE_INTERVAL} which indicates
237          * this request will not actively generate GNSS measurement updates, but may receive
238          * GNSS measurement updates generated as a result of other GNSS measurement requests.
239          *
240          * <p>An interval of 0 milliseconds means the fastest rate the chipset can report.
241          *
242          * <p>The GNSS chipset may report measurements with a rate faster than requested.
243          *
244          * <p class="note">Note that on Android T, a request interval of {@link #PASSIVE_INTERVAL}
245          * will first trigger one GNSS measurement. Another GNSS measurement will be triggered after
246          * {@link #PASSIVE_INTERVAL} milliseconds and so on.
247          */
setIntervalMillis(@ntRangefrom = 0) int value)248         @NonNull public Builder setIntervalMillis(@IntRange(from = 0) int value) {
249             mIntervalMillis = Preconditions.checkArgumentInRange(value, 0, Integer.MAX_VALUE,
250                     "intervalMillis");
251             return this;
252         }
253 
254         /** Builds a {@link GnssMeasurementRequest} instance as specified by this builder. */
255         @NonNull
build()256         public GnssMeasurementRequest build() {
257             return new GnssMeasurementRequest(mFullTracking, mCorrelationVectorOutputsEnabled,
258                     mIntervalMillis);
259         }
260     }
261 }
262