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.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import com.android.internal.util.Preconditions; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.List; 34 35 /** 36 * A class implementing a container for data associated with a measurement event. 37 * Events are delivered to registered instances of {@link Callback}. 38 */ 39 public final class GnssMeasurementsEvent implements Parcelable { 40 private final int mFlag; 41 private final GnssClock mClock; 42 private final List<GnssMeasurement> mMeasurements; 43 private final List<GnssAutomaticGainControl> mGnssAgcs; 44 private final boolean mIsFullTracking; 45 46 private static final int HAS_IS_FULL_TRACKING = 1; 47 48 /** 49 * Used for receiving GNSS satellite measurements from the GNSS engine. 50 * Each measurement contains raw and computed data identifying a satellite. 51 * You can implement this interface and call 52 * {@link LocationManager#registerGnssMeasurementsCallback}. 53 */ 54 public static abstract class Callback { 55 /** 56 * The status of the GNSS measurements event. 57 * @deprecated Do not use. 58 * @hide 59 */ 60 @Deprecated 61 @Retention(RetentionPolicy.SOURCE) 62 @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED, STATUS_NOT_ALLOWED}) 63 public @interface GnssMeasurementsStatus {} 64 65 /** 66 * The system does not support tracking of GNSS Measurements. 67 * 68 * <p>This status will not change in the future. 69 * 70 * @deprecated Do not use. 71 */ 72 @Deprecated 73 public static final int STATUS_NOT_SUPPORTED = 0; 74 75 /** 76 * GNSS Measurements are successfully being tracked, it will receive updates once they are 77 * available. 78 * 79 * @deprecated Do not use. 80 */ 81 @Deprecated 82 public static final int STATUS_READY = 1; 83 84 /** 85 * GPS provider or Location is disabled, updates will not be received until they are 86 * enabled. 87 * 88 * @deprecated Do not use. 89 */ 90 @Deprecated 91 public static final int STATUS_LOCATION_DISABLED = 2; 92 93 /** 94 * The client is not allowed to register for GNSS Measurements in general or in the 95 * requested mode. 96 * 97 * <p>Such a status is returned when a client tries to request a functionality from the GNSS 98 * chipset while another client has an ongoing request that does not allow such 99 * functionality to be performed. 100 * 101 * <p>If such a status is received, one would try again at a later time point where no 102 * other client is having a conflicting request. 103 * 104 * @deprecated Do not use. 105 */ 106 @Deprecated 107 public static final int STATUS_NOT_ALLOWED = 3; 108 109 /** 110 * Reports the latest collected GNSS Measurements. 111 */ onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs)112 public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {} 113 114 /** 115 * Reports the latest status of the GNSS Measurements sub-system. 116 * 117 * @deprecated Do not rely on this callback. From Android S onwards this callback will be 118 * invoked once with {@link #STATUS_READY} in all cases for backwards compatibility, and 119 * then never invoked again. Use LocationManager APIs if you need to determine if 120 * GNSS measurements are supported or if location is off, etc... 121 */ 122 @Deprecated onStatusChanged(@nssMeasurementsStatus int status)123 public void onStatusChanged(@GnssMeasurementsStatus int status) {} 124 } 125 126 /** 127 * Create a {@link GnssMeasurementsEvent} instance with a full list of parameters. 128 */ GnssMeasurementsEvent(int flag, @NonNull GnssClock clock, @NonNull List<GnssMeasurement> measurements, @NonNull List<GnssAutomaticGainControl> agcs, boolean isFullTracking)129 private GnssMeasurementsEvent(int flag, 130 @NonNull GnssClock clock, 131 @NonNull List<GnssMeasurement> measurements, 132 @NonNull List<GnssAutomaticGainControl> agcs, 133 boolean isFullTracking) { 134 mFlag = flag; 135 mMeasurements = measurements; 136 mGnssAgcs = agcs; 137 mClock = clock; 138 mIsFullTracking = isFullTracking; 139 } 140 141 /** 142 * Gets the GNSS receiver clock information associated with the measurements for the current 143 * event. 144 */ 145 @NonNull getClock()146 public GnssClock getClock() { 147 return mClock; 148 } 149 150 /** 151 * Gets the collection of measurements associated with the current event. 152 */ 153 @NonNull getMeasurements()154 public Collection<GnssMeasurement> getMeasurements() { 155 return mMeasurements; 156 } 157 158 /** 159 * Gets the collection of {@link GnssAutomaticGainControl} associated with the 160 * current event. 161 */ 162 @NonNull getGnssAutomaticGainControls()163 public Collection<GnssAutomaticGainControl> getGnssAutomaticGainControls() { 164 return mGnssAgcs; 165 } 166 167 /** 168 * True indicates that this event was produced while the chipset was in full tracking mode, ie, 169 * the GNSS chipset switched off duty cycling. In this mode, no clock discontinuities are 170 * expected and, when supported, carrier phase should be continuous in good signal conditions. 171 * All non-blocklisted, healthy constellations, satellites and frequency bands that are 172 * meaningful to positioning accuracy must be tracked and reported in this mode. 173 * 174 * False indicates that the GNSS chipset may optimize power via duty cycling, constellations and 175 * frequency limits, etc. 176 * 177 * <p>The value is only available if {@link #hasIsFullTracking()} is {@code true}. 178 */ isFullTracking()179 public boolean isFullTracking() { 180 return mIsFullTracking; 181 } 182 183 /** 184 * Return {@code true} if {@link #isFullTracking()} is available, {@code false} otherwise. 185 */ hasIsFullTracking()186 public boolean hasIsFullTracking() { 187 return (mFlag & HAS_IS_FULL_TRACKING) == HAS_IS_FULL_TRACKING; 188 } 189 190 public static final @android.annotation.NonNull Creator<GnssMeasurementsEvent> CREATOR = 191 new Creator<GnssMeasurementsEvent>() { 192 @Override 193 public GnssMeasurementsEvent createFromParcel(Parcel in) { 194 int flag = in.readInt(); 195 GnssClock clock = in.readParcelable(getClass().getClassLoader(), 196 android.location.GnssClock.class); 197 List<GnssMeasurement> measurements = in.createTypedArrayList(GnssMeasurement.CREATOR); 198 List<GnssAutomaticGainControl> agcs = in.createTypedArrayList( 199 GnssAutomaticGainControl.CREATOR); 200 boolean isFullTracking = in.readBoolean(); 201 return new GnssMeasurementsEvent(flag, clock, measurements, agcs, isFullTracking); 202 } 203 204 @Override 205 public GnssMeasurementsEvent[] newArray(int size) { 206 return new GnssMeasurementsEvent[size]; 207 } 208 }; 209 210 @Override describeContents()211 public int describeContents() { 212 return 0; 213 } 214 215 @Override writeToParcel(Parcel parcel, int flags)216 public void writeToParcel(Parcel parcel, int flags) { 217 parcel.writeInt(mFlag); 218 parcel.writeParcelable(mClock, flags); 219 parcel.writeTypedList(mMeasurements); 220 parcel.writeTypedList(mGnssAgcs); 221 parcel.writeBoolean(mIsFullTracking); 222 } 223 224 @Override toString()225 public String toString() { 226 StringBuilder builder = new StringBuilder("GnssMeasurementsEvent["); 227 builder.append(mClock); 228 builder.append(' ').append(mMeasurements.toString()); 229 builder.append(' ').append(mGnssAgcs.toString()); 230 if (hasIsFullTracking()) { 231 builder.append(" isFullTracking=").append(mIsFullTracking); 232 } 233 builder.append("]"); 234 return builder.toString(); 235 } 236 237 /** Builder for {@link GnssMeasurementsEvent} */ 238 public static final class Builder { 239 private int mFlag; 240 private GnssClock mClock; 241 private List<GnssMeasurement> mMeasurements; 242 private List<GnssAutomaticGainControl> mGnssAgcs; 243 private boolean mIsFullTracking; 244 245 /** 246 * Constructs a {@link GnssMeasurementsEvent.Builder} instance. 247 */ Builder()248 public Builder() { 249 mClock = new GnssClock(); 250 mMeasurements = new ArrayList<>(); 251 mGnssAgcs = new ArrayList<>(); 252 } 253 254 /** 255 * Constructs a {@link GnssMeasurementsEvent.Builder} instance by copying a 256 * {@link GnssMeasurementsEvent}. 257 */ Builder(@onNull GnssMeasurementsEvent event)258 public Builder(@NonNull GnssMeasurementsEvent event) { 259 mFlag = event.mFlag; 260 mClock = event.getClock(); 261 mMeasurements = (List<GnssMeasurement>) event.getMeasurements(); 262 mGnssAgcs = (List<GnssAutomaticGainControl>) event.getGnssAutomaticGainControls(); 263 mIsFullTracking = event.isFullTracking(); 264 } 265 266 /** 267 * Sets the {@link GnssClock}. 268 */ 269 @NonNull setClock(@onNull GnssClock clock)270 public Builder setClock(@NonNull GnssClock clock) { 271 Preconditions.checkNotNull(clock); 272 mClock = clock; 273 return this; 274 } 275 276 /** 277 * Sets the collection of {@link GnssMeasurement}. 278 * 279 * This API exists for JNI since it is easier for JNI to work with an array than a 280 * collection. 281 * @hide 282 */ 283 @NonNull setMeasurements(@ullable GnssMeasurement... measurements)284 public Builder setMeasurements(@Nullable GnssMeasurement... measurements) { 285 mMeasurements = measurements == null ? Collections.emptyList() : Arrays.asList( 286 measurements); 287 return this; 288 } 289 290 /** 291 * Sets the collection of {@link GnssMeasurement}. 292 */ 293 @NonNull setMeasurements(@onNull Collection<GnssMeasurement> measurements)294 public Builder setMeasurements(@NonNull Collection<GnssMeasurement> measurements) { 295 mMeasurements = new ArrayList<>(measurements); 296 return this; 297 } 298 299 /** 300 * Sets the collection of {@link GnssAutomaticGainControl}. 301 * 302 * This API exists for JNI since it is easier for JNI to work with an array than a 303 * collection. 304 * @hide 305 */ 306 @NonNull setGnssAutomaticGainControls(@ullable GnssAutomaticGainControl... agcs)307 public Builder setGnssAutomaticGainControls(@Nullable GnssAutomaticGainControl... agcs) { 308 mGnssAgcs = agcs == null ? Collections.emptyList() : Arrays.asList(agcs); 309 return this; 310 } 311 312 /** 313 * Sets the collection of {@link GnssAutomaticGainControl}. 314 */ 315 @NonNull setGnssAutomaticGainControls( @onNull Collection<GnssAutomaticGainControl> agcs)316 public Builder setGnssAutomaticGainControls( 317 @NonNull Collection<GnssAutomaticGainControl> agcs) { 318 mGnssAgcs = new ArrayList<>(agcs); 319 return this; 320 } 321 322 /** 323 * Sets whether the GNSS chipset was in the full tracking mode at the time this event was 324 * produced. 325 * 326 * True indicates that this event was produced while the chipset was in full tracking 327 * mode, ie, the GNSS chipset switched off duty cycling. In this mode, no clock 328 * discontinuities are expected and, when supported, carrier phase should be continuous in 329 * good signal conditions. All non-blocklisted, healthy constellations, satellites and 330 * frequency bands that are meaningful to positioning accuracy must be tracked and reported 331 * in this mode. 332 * 333 * False indicates that the GNSS chipset may optimize power via duty cycling, constellations 334 * and frequency limits, etc. 335 */ 336 @NonNull setIsFullTracking(boolean isFullTracking)337 public Builder setIsFullTracking(boolean isFullTracking) { 338 mFlag |= HAS_IS_FULL_TRACKING; 339 mIsFullTracking = isFullTracking; 340 return this; 341 } 342 343 /** 344 * Clears the full tracking mode indicator. 345 */ 346 @NonNull clearIsFullTracking()347 public Builder clearIsFullTracking() { 348 mFlag &= ~HAS_IS_FULL_TRACKING; 349 return this; 350 } 351 352 /** Builds a {@link GnssMeasurementsEvent} instance as specified by this builder. */ 353 @NonNull build()354 public GnssMeasurementsEvent build() { 355 return new GnssMeasurementsEvent(mFlag, mClock, mMeasurements, mGnssAgcs, 356 mIsFullTracking); 357 } 358 } 359 } 360