| /* |
| * Copyright (C) 2018 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.IntRange; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SystemApi; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| |
| import com.android.internal.util.Preconditions; |
| |
| /** |
| * A container with measurement corrections for a single visible satellite |
| * |
| * @hide |
| */ |
| @SystemApi |
| public final class GnssSingleSatCorrection implements Parcelable { |
| |
| /** |
| * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link |
| * #mProbSatIsLos}. |
| * |
| * @hide |
| */ |
| public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0; |
| |
| /** |
| * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link |
| * #mExcessPathLengthMeters}. |
| * |
| * @hide |
| */ |
| public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1; |
| |
| /** |
| * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link |
| * #mExcessPathLengthUncertaintyMeters}. |
| * |
| * @hide |
| */ |
| public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2; |
| |
| /** |
| * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link |
| * #mReflectingPlane}. |
| * |
| * @hide |
| */ |
| public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3; |
| |
| /** A bitmask of fields present in this object (see HAS_* constants defined above) */ |
| private final int mSingleSatCorrectionFlags; |
| |
| /** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */ |
| @GnssStatus.ConstellationType |
| private final int mConstellationType; |
| |
| /** |
| * Satellite vehicle ID number |
| * |
| * <p>Interpretation depends on {@link GnssStatus#getSvid(int)}. |
| */ |
| @IntRange(from = 0) |
| private final int mSatId; |
| |
| /** |
| * Carrier frequency of the signal to be corrected, for example it can be the GPS center |
| * frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc. |
| * |
| * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction |
| * objects will be reported for this same satellite, in one of the correction objects, all the |
| * values related to L1 will be filled, and in the other all of the values related to L5 will be |
| * filled. |
| */ |
| @FloatRange(from = 0.0f, fromInclusive = false) |
| private final float mCarrierFrequencyHz; |
| |
| /** |
| * The probability that the satellite is estimated to be in Line-of-Sight condition at the given |
| * location. |
| */ |
| @FloatRange(from = 0.0f, to = 1.0f) |
| private final float mProbSatIsLos; |
| |
| /** |
| * Excess path length to be subtracted from pseudorange before using it in calculating location. |
| */ |
| @FloatRange(from = 0.0f) |
| private final float mExcessPathLengthMeters; |
| |
| /** Error estimate (1-sigma) for the Excess path length estimate */ |
| @FloatRange(from = 0.0f) |
| private final float mExcessPathLengthUncertaintyMeters; |
| |
| /** |
| * Defines the reflecting plane location and azimuth information |
| * |
| * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite |
| * signal goes through multiple reflections or if reflection plane serving is not supported. |
| */ |
| @Nullable |
| private final GnssReflectingPlane mReflectingPlane; |
| |
| private GnssSingleSatCorrection(Builder builder) { |
| mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags; |
| mSatId = builder.mSatId; |
| mConstellationType = builder.mConstellationType; |
| mCarrierFrequencyHz = builder.mCarrierFrequencyHz; |
| mProbSatIsLos = builder.mProbSatIsLos; |
| mExcessPathLengthMeters = builder.mExcessPathLengthMeters; |
| mExcessPathLengthUncertaintyMeters = builder.mExcessPathLengthUncertaintyMeters; |
| mReflectingPlane = builder.mReflectingPlane; |
| } |
| |
| /** |
| * Gets a bitmask of fields present in this object |
| * |
| * @hide |
| */ |
| public int getSingleSatelliteCorrectionFlags() { |
| return mSingleSatCorrectionFlags; |
| } |
| |
| /** |
| * Gets the constellation type. |
| * |
| * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link |
| * GnssStatus}. |
| */ |
| @GnssStatus.ConstellationType |
| public int getConstellationType() { |
| return mConstellationType; |
| } |
| |
| /** |
| * Gets the satellite ID. |
| * |
| * <p>Interpretation depends on {@link #getConstellationType()}. See {@link |
| * GnssStatus#getSvid(int)}. |
| */ |
| @IntRange(from = 0) |
| public int getSatelliteId() { |
| return mSatId; |
| } |
| |
| /** |
| * Gets the carrier frequency of the tracked signal. |
| * |
| * <p>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. |
| * |
| * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction |
| * objects will be reported for this same satellite, in one of the correction objects, all the |
| * values related to L1 will be filled, and in the other all of the values related to L5 will be |
| * filled. |
| * |
| * @return the carrier frequency of the signal tracked in Hz. |
| */ |
| @FloatRange(from = 0.0f, fromInclusive = false) |
| public float getCarrierFrequencyHz() { |
| return mCarrierFrequencyHz; |
| } |
| |
| /** |
| * Returns the probability that the satellite is in line-of-sight condition at the given |
| * location. |
| */ |
| @FloatRange(from = 0.0f, to = 1.0f) |
| public float getProbabilityLineOfSight() { |
| return mProbSatIsLos; |
| } |
| |
| /** |
| * Returns the Excess path length to be subtracted from pseudorange before using it in |
| * calculating location. |
| */ |
| @FloatRange(from = 0.0f) |
| public float getExcessPathLengthMeters() { |
| return mExcessPathLengthMeters; |
| } |
| |
| /** Returns the error estimate (1-sigma) for the Excess path length estimate */ |
| @FloatRange(from = 0.0f) |
| public float getExcessPathLengthUncertaintyMeters() { |
| return mExcessPathLengthUncertaintyMeters; |
| } |
| |
| /** |
| * Returns the reflecting plane characteristics at which the signal has bounced |
| * |
| * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite |
| * signal goes through multiple reflections or if reflection plane serving is not supported |
| */ |
| @Nullable |
| public GnssReflectingPlane getReflectingPlane() { |
| return mReflectingPlane; |
| } |
| |
| /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */ |
| public boolean hasValidSatelliteLineOfSight() { |
| return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0; |
| } |
| |
| /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */ |
| public boolean hasExcessPathLength() { |
| return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0; |
| } |
| |
| /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */ |
| public boolean hasExcessPathLengthUncertainty() { |
| return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0; |
| } |
| |
| /** Returns {@code true} if {@link #getReflectingPlane()} is valid. */ |
| public boolean hasReflectingPlane() { |
| return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0; |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| public static final Creator<GnssSingleSatCorrection> CREATOR = |
| new Creator<GnssSingleSatCorrection>() { |
| @Override |
| @NonNull |
| public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) { |
| int mSingleSatCorrectionFlags = parcel.readInt(); |
| boolean hasReflectingPlane = |
| (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0; |
| final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder = |
| new Builder() |
| .setConstellationType(parcel.readInt()) |
| .setSatelliteId(parcel.readInt()) |
| .setCarrierFrequencyHz(parcel.readFloat()) |
| .setProbabilityLineOfSight(parcel.readFloat()) |
| .setExcessPathLengthMeters(parcel.readFloat()) |
| .setExcessPathLengthUncertaintyMeters(parcel.readFloat()); |
| if (hasReflectingPlane) { |
| singleSatCorrectionBuilder.setReflectingPlane( |
| GnssReflectingPlane.CREATOR.createFromParcel(parcel)); |
| } |
| return singleSatCorrectionBuilder.build(); |
| } |
| |
| @Override |
| public GnssSingleSatCorrection[] newArray(int i) { |
| return new GnssSingleSatCorrection[i]; |
| } |
| }; |
| |
| @Override |
| public String toString() { |
| final String format = " %-29s = %s\n"; |
| StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n"); |
| builder.append( |
| String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags)); |
| builder.append(String.format(format, "ConstellationType = ", mConstellationType)); |
| builder.append(String.format(format, "SatId = ", mSatId)); |
| builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz)); |
| builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos)); |
| builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters)); |
| builder.append( |
| String.format( |
| format, |
| "ExcessPathLengthUncertaintyMeters = ", |
| mExcessPathLengthUncertaintyMeters)); |
| if (hasReflectingPlane()) { |
| builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane)); |
| } |
| return builder.toString(); |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel parcel, int flags) { |
| parcel.writeInt(mSingleSatCorrectionFlags); |
| parcel.writeInt(mConstellationType); |
| parcel.writeInt(mSatId); |
| parcel.writeFloat(mCarrierFrequencyHz); |
| parcel.writeFloat(mProbSatIsLos); |
| parcel.writeFloat(mExcessPathLengthMeters); |
| parcel.writeFloat(mExcessPathLengthUncertaintyMeters); |
| if (hasReflectingPlane()) { |
| mReflectingPlane.writeToParcel(parcel, flags); |
| } |
| } |
| |
| /** Builder for {@link GnssSingleSatCorrection} */ |
| public static final class Builder { |
| |
| /** |
| * For documentation of below fields, see corresponding fields in {@link |
| * GnssSingleSatCorrection}. |
| */ |
| private int mSingleSatCorrectionFlags; |
| |
| private int mConstellationType; |
| private int mSatId; |
| private float mCarrierFrequencyHz; |
| private float mProbSatIsLos; |
| private float mExcessPathLengthMeters; |
| private float mExcessPathLengthUncertaintyMeters; |
| @Nullable |
| private GnssReflectingPlane mReflectingPlane; |
| |
| /** Sets the constellation type. */ |
| @NonNull public Builder setConstellationType( |
| @GnssStatus.ConstellationType int constellationType) { |
| mConstellationType = constellationType; |
| return this; |
| } |
| |
| /** Sets the Satellite ID defined in the ICD of the given constellation. */ |
| @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) { |
| mSatId = satId; |
| return this; |
| } |
| |
| /** Sets the Carrier frequency in Hz. */ |
| @NonNull public Builder setCarrierFrequencyHz( |
| @FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) { |
| mCarrierFrequencyHz = carrierFrequencyHz; |
| return this; |
| } |
| |
| /** |
| * Sets the line-of-sight probability of the satellite at the given location in the range |
| * between 0 and 1. |
| */ |
| @NonNull public Builder setProbabilityLineOfSight( |
| @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) { |
| Preconditions.checkArgumentInRange( |
| probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1."); |
| mProbSatIsLos = probSatIsLos; |
| mSingleSatCorrectionFlags = |
| (byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK); |
| return this; |
| } |
| |
| /** |
| * Sets the Excess path length to be subtracted from pseudorange before using it in |
| * calculating location. |
| */ |
| @NonNull public Builder setExcessPathLengthMeters( |
| @FloatRange(from = 0.0f) float excessPathLengthMeters) { |
| mExcessPathLengthMeters = excessPathLengthMeters; |
| mSingleSatCorrectionFlags = |
| (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK); |
| return this; |
| } |
| |
| /** Sets the error estimate (1-sigma) for the Excess path length estimate */ |
| @NonNull public Builder setExcessPathLengthUncertaintyMeters( |
| @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) { |
| mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; |
| mSingleSatCorrectionFlags = |
| (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK); |
| return this; |
| } |
| |
| /** Sets the reflecting plane information */ |
| @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) { |
| mReflectingPlane = reflectingPlane; |
| if (reflectingPlane != null) { |
| mSingleSatCorrectionFlags = |
| (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK); |
| } else { |
| mSingleSatCorrectionFlags = |
| (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK); |
| } |
| return this; |
| } |
| |
| /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */ |
| @NonNull public GnssSingleSatCorrection build() { |
| return new GnssSingleSatCorrection(this); |
| } |
| } |
| } |