/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.location; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; /** * This class represents the current state of the GNSS engine and is used in conjunction with * {@link GnssStatus.Callback}. * * @see LocationManager#registerGnssStatusCallback * @see GnssStatus.Callback */ public final class GnssStatus implements Parcelable { // These must match the definitions in GNSS HAL. // // Note: these constants are also duplicated in GnssStatusCompat.java in the androidx support // library. if adding a constellation, please update that file as well. /** Unknown constellation type. */ public static final int CONSTELLATION_UNKNOWN = 0; /** Constellation type constant for GPS. */ public static final int CONSTELLATION_GPS = 1; /** Constellation type constant for SBAS. */ public static final int CONSTELLATION_SBAS = 2; /** Constellation type constant for Glonass. */ public static final int CONSTELLATION_GLONASS = 3; /** Constellation type constant for QZSS. */ public static final int CONSTELLATION_QZSS = 4; /** Constellation type constant for Beidou. */ public static final int CONSTELLATION_BEIDOU = 5; /** Constellation type constant for Galileo. */ public static final int CONSTELLATION_GALILEO = 6; /** Constellation type constant for IRNSS. */ public static final int CONSTELLATION_IRNSS = 7; /** @hide */ public static final int CONSTELLATION_COUNT = 8; private static final int SVID_FLAGS_NONE = 0; private static final int SVID_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0); private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1); private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2); private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3); private static final int SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4); private static final int SVID_SHIFT_WIDTH = 12; private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 8; private static final int CONSTELLATION_TYPE_MASK = 0xf; /** * Used for receiving notifications when GNSS events happen. * * @see LocationManager#registerGnssStatusCallback */ public static abstract class Callback { /** * Called when GNSS system has started. */ public void onStarted() { } /** * Called when GNSS system has stopped. */ public void onStopped() { } /** * Called when the GNSS system has received its first fix since starting. * * @param ttffMillis the time from start to first fix in milliseconds. */ public void onFirstFix(int ttffMillis) { } /** * Called periodically to report GNSS satellite status. * * @param status the current status of all satellites. */ public void onSatelliteStatusChanged(@NonNull GnssStatus status) { } } /** * Constellation type. * * @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS, CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO, CONSTELLATION_IRNSS}) public @interface ConstellationType { } /** * Create a GnssStatus that wraps the given arguments without any additional overhead. Callers * are responsible for guaranteeing that the arguments are never modified after calling this * method. * * @hide */ @NonNull public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) { Preconditions.checkState(svCount >= 0); Preconditions.checkState(svidWithFlags.length >= svCount); Preconditions.checkState(elevations.length >= svCount); Preconditions.checkState(azimuths.length >= svCount); Preconditions.checkState(carrierFrequencies.length >= svCount); Preconditions.checkState(basebandCn0DbHzs.length >= svCount); return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, carrierFrequencies, basebandCn0DbHzs); } private final int mSvCount; private final int[] mSvidWithFlags; private final float[] mCn0DbHzs; private final float[] mElevations; private final float[] mAzimuths; private final float[] mCarrierFrequencies; private final float[] mBasebandCn0DbHzs; private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) { mSvCount = svCount; mSvidWithFlags = svidWithFlags; mCn0DbHzs = cn0DbHzs; mElevations = elevations; mAzimuths = azimuths; mCarrierFrequencies = carrierFrequencies; mBasebandCn0DbHzs = basebandCn0DbHzs; } /** * Gets the total number of satellites in satellite list. */ @IntRange(from = 0) public int getSatelliteCount() { return mSvCount; } /** * Retrieves the constellation type of the satellite at the specified index. * * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 */ @ConstellationType public int getConstellationType(@IntRange(from = 0) int satelliteIndex) { return ((mSvidWithFlags[satelliteIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH) & CONSTELLATION_TYPE_MASK); } /** * Gets the identification number for the satellite at the specific index. * *
This svid is pseudo-random number for most constellations. It is FCN & OSN number for * Glonass. * *
The distinction is made by looking at constellation field * {@link #getConstellationType(int)} Expected values are in the range of: * *
For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 * MHz, L5 = 1176.45 MHz, varying GLO channels, etc. * *
The value is only available if {@link #hasCarrierFrequencyHz(int satelliteIndex)} is
* {@code true}.
*
* @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
*/
@FloatRange(from = 0)
public float getCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) {
return mCarrierFrequencies[satelliteIndex];
}
/**
* Reports whether a valid {@link #getBasebandCn0DbHz(int satelliteIndex)} is available.
*
* @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
*/
public boolean hasBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_BASEBAND_CN0) != 0;
}
/**
* Retrieves the baseband carrier-to-noise density of the satellite at the specified index in
* dB-Hz.
*
* @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
*/
@FloatRange(from = 0, to = 63)
public float getBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
return mBasebandCn0DbHzs[satelliteIndex];
}
/**
* Returns the string representation of a constellation type.
*
* @param constellationType the constellation type.
* @return the string representation.
* @hide
*/
@NonNull
public static String constellationTypeToString(@ConstellationType int constellationType) {
switch (constellationType) {
case CONSTELLATION_UNKNOWN:
return "UNKNOWN";
case CONSTELLATION_GPS:
return "GPS";
case CONSTELLATION_SBAS:
return "SBAS";
case CONSTELLATION_GLONASS:
return "GLONASS";
case CONSTELLATION_QZSS:
return "QZSS";
case CONSTELLATION_BEIDOU:
return "BEIDOU";
case CONSTELLATION_GALILEO:
return "GALILEO";
case CONSTELLATION_IRNSS:
return "IRNSS";
default:
return Integer.toString(constellationType);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof GnssStatus)) {
return false;
}
GnssStatus that = (GnssStatus) o;
return mSvCount == that.mSvCount
&& Arrays.equals(mSvidWithFlags, that.mSvidWithFlags)
&& Arrays.equals(mCn0DbHzs, that.mCn0DbHzs)
&& Arrays.equals(mElevations, that.mElevations)
&& Arrays.equals(mAzimuths, that.mAzimuths)
&& Arrays.equals(mCarrierFrequencies, that.mCarrierFrequencies)
&& Arrays.equals(mBasebandCn0DbHzs, that.mBasebandCn0DbHzs);
}
@Override
public int hashCode() {
int result = Objects.hash(mSvCount);
result = 31 * result + Arrays.hashCode(mSvidWithFlags);
result = 31 * result + Arrays.hashCode(mCn0DbHzs);
return result;
}
public static final @NonNull Creator