diff --git a/Android.bp b/Android.bp index 753cefc38ed6e..edaa11e3dc73f 100644 --- a/Android.bp +++ b/Android.bp @@ -97,6 +97,7 @@ filegroup { ":platform-compat-native-aidl", // AIDL sources from external directories + ":android.hardware.gnss-V2-java-source", ":android.hardware.graphics.common-V3-java-source", ":android.hardware.security.keymint-V2-java-source", ":android.hardware.security.secureclock-V1-java-source", diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 09d111418e067..8406d1c08f11b 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -5488,6 +5488,32 @@ package android.location { method @NonNull public android.location.GnssCapabilities.Builder setHasSatellitePvt(boolean); } + public final class GnssExcessPathInfo implements android.os.Parcelable { + method public int describeContents(); + method @FloatRange(from=0.0f) public float getAttenuationDb(); + method @FloatRange(from=0.0f) public float getExcessPathLengthMeters(); + method @FloatRange(from=0.0f) public float getExcessPathLengthUncertaintyMeters(); + method @NonNull public android.location.GnssReflectingPlane getReflectingPlane(); + method public boolean hasAttenuation(); + method public boolean hasExcessPathLength(); + method public boolean hasExcessPathLengthUncertainty(); + method public boolean hasReflectingPlane(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public static final class GnssExcessPathInfo.Builder { + ctor public GnssExcessPathInfo.Builder(); + method @NonNull public android.location.GnssExcessPathInfo build(); + method @NonNull public android.location.GnssExcessPathInfo.Builder clearAttenuationDb(); + method @NonNull public android.location.GnssExcessPathInfo.Builder clearExcessPathLengthMeters(); + method @NonNull public android.location.GnssExcessPathInfo.Builder clearExcessPathLengthUncertaintyMeters(); + method @NonNull public android.location.GnssExcessPathInfo.Builder setAttenuationDb(@FloatRange(from=0.0f) float); + method @NonNull public android.location.GnssExcessPathInfo.Builder setExcessPathLengthMeters(@FloatRange(from=0.0f) float); + method @NonNull public android.location.GnssExcessPathInfo.Builder setExcessPathLengthUncertaintyMeters(@FloatRange(from=0.0f) float); + method @NonNull public android.location.GnssExcessPathInfo.Builder setReflectingPlane(@Nullable android.location.GnssReflectingPlane); + } + public final class GnssMeasurement implements android.os.Parcelable { method @Nullable public java.util.Collection getCorrelationVectors(); method @Nullable public android.location.SatellitePvt getSatellitePvt(); @@ -5569,15 +5595,18 @@ package android.location { public final class GnssSingleSatCorrection implements android.os.Parcelable { method public int describeContents(); method @FloatRange(from=0.0f, fromInclusive=false) public float getCarrierFrequencyHz(); + method @FloatRange(from=0.0f) public float getCombinedAttenuationDb(); method public int getConstellationType(); method @FloatRange(from=0.0f) public float getExcessPathLengthMeters(); method @FloatRange(from=0.0f) public float getExcessPathLengthUncertaintyMeters(); + method @NonNull public java.util.List getGnssExcessPathInfoList(); method @FloatRange(from=0.0f, to=1.0f) public float getProbabilityLineOfSight(); - method @Nullable public android.location.GnssReflectingPlane getReflectingPlane(); + method @Deprecated @Nullable public android.location.GnssReflectingPlane getReflectingPlane(); method @IntRange(from=0) public int getSatelliteId(); + method public boolean hasCombinedAttenuation(); method public boolean hasExcessPathLength(); method public boolean hasExcessPathLengthUncertainty(); - method public boolean hasReflectingPlane(); + method @Deprecated public boolean hasReflectingPlane(); method public boolean hasValidSatelliteLineOfSight(); method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -5586,15 +5615,18 @@ package android.location { public static final class GnssSingleSatCorrection.Builder { ctor public GnssSingleSatCorrection.Builder(); method @NonNull public android.location.GnssSingleSatCorrection build(); + method @NonNull public android.location.GnssSingleSatCorrection.Builder clearCombinedAttenuationDb(); method @NonNull public android.location.GnssSingleSatCorrection.Builder clearExcessPathLengthMeters(); method @NonNull public android.location.GnssSingleSatCorrection.Builder clearExcessPathLengthUncertaintyMeters(); method @NonNull public android.location.GnssSingleSatCorrection.Builder clearProbabilityLineOfSight(); method @NonNull public android.location.GnssSingleSatCorrection.Builder setCarrierFrequencyHz(@FloatRange(from=0.0f, fromInclusive=false) float); + method @NonNull public android.location.GnssSingleSatCorrection.Builder setCombinedAttenuationDb(@FloatRange(from=0.0f) float); method @NonNull public android.location.GnssSingleSatCorrection.Builder setConstellationType(int); method @NonNull public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthMeters(@FloatRange(from=0.0f) float); method @NonNull public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthUncertaintyMeters(@FloatRange(from=0.0f) float); + method @NonNull public android.location.GnssSingleSatCorrection.Builder setGnssExcessPathInfoList(@NonNull java.util.List); method @NonNull public android.location.GnssSingleSatCorrection.Builder setProbabilityLineOfSight(@FloatRange(from=0.0f, to=1.0f) float); - method @NonNull public android.location.GnssSingleSatCorrection.Builder setReflectingPlane(@Nullable android.location.GnssReflectingPlane); + method @Deprecated @NonNull public android.location.GnssSingleSatCorrection.Builder setReflectingPlane(@Nullable android.location.GnssReflectingPlane); method @NonNull public android.location.GnssSingleSatCorrection.Builder setSatelliteId(@IntRange(from=0) int); } diff --git a/location/java/android/location/GnssExcessPathInfo.java b/location/java/android/location/GnssExcessPathInfo.java new file mode 100644 index 0000000000000..72b2374bad8f7 --- /dev/null +++ b/location/java/android/location/GnssExcessPathInfo.java @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2022 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 static android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo.EXCESS_PATH_INFO_HAS_ATTENUATION; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo.EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo.EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.ExcessPathInfo.EXCESS_PATH_INFO_HAS_REFLECTING_PLANE; + +import android.annotation.FloatRange; +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; + +import java.util.Objects; + +/** + * Contains the info of an excess path signal caused by reflection + * + * @hide + */ +@SystemApi +public final class GnssExcessPathInfo implements Parcelable { + + private static final int HAS_EXCESS_PATH_LENGTH_MASK = EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH; + private static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = + EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC; + private static final int HAS_REFLECTING_PLANE_MASK = EXCESS_PATH_INFO_HAS_REFLECTING_PLANE; + private static final int HAS_ATTENUATION_MASK = EXCESS_PATH_INFO_HAS_ATTENUATION; + + /* A bitmask of fields present in this object (see HAS_* constants defined above) */ + private final int mFlags; + private final float mExcessPathLengthMeters; + private final float mExcessPathLengthUncertaintyMeters; + @Nullable + private final GnssReflectingPlane mReflectingPlane; + private final float mAttenuationDb; + + private GnssExcessPathInfo( + int flags, + float excessPathLengthMeters, + float excessPathLengthUncertaintyMeters, + @Nullable GnssReflectingPlane reflectingPlane, + float attenuationDb) { + mFlags = flags; + mExcessPathLengthMeters = excessPathLengthMeters; + mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; + mReflectingPlane = reflectingPlane; + mAttenuationDb = attenuationDb; + } + + /** + * Gets a bitmask of fields present in this object. + * + *

This API exists for JNI since it is easier for JNI to get one integer flag than looking up + * several has* methods. + * @hide + */ + public int getFlags() { + return mFlags; + } + + /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */ + public boolean hasExcessPathLength() { + return (mFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0; + } + + /** + * Returns the excess path length to be subtracted from pseudorange before using it in + * calculating location. + * + *

{@link #hasExcessPathLength()} must be true when calling this method. Otherwise, an + * {@link UnsupportedOperationException} will be thrown. + */ + @FloatRange(from = 0.0f) + public float getExcessPathLengthMeters() { + if (!hasExcessPathLength()) { + throw new UnsupportedOperationException( + "getExcessPathLengthMeters() is not supported when hasExcessPathLength() is " + + "false"); + } + return mExcessPathLengthMeters; + } + + /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */ + public boolean hasExcessPathLengthUncertainty() { + return (mFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0; + } + + /** + * Returns the error estimate (1-sigma) for the excess path length estimate. + * + *

{@link #hasExcessPathLengthUncertainty()} must be true when calling this method. + * Otherwise, an {@link UnsupportedOperationException} will be thrown. + */ + @FloatRange(from = 0.0f) + public float getExcessPathLengthUncertaintyMeters() { + if (!hasExcessPathLengthUncertainty()) { + throw new UnsupportedOperationException( + "getExcessPathLengthUncertaintyMeters() is not supported when " + + "hasExcessPathLengthUncertainty() is false"); + } + return mExcessPathLengthUncertaintyMeters; + } + + /** + * Returns {@code true} if {@link #getReflectingPlane()} is valid. + * + *

Returns false if the satellite signal goes through multiple reflections or if reflection + * plane serving is not supported. + */ + public boolean hasReflectingPlane() { + return (mFlags & HAS_REFLECTING_PLANE_MASK) != 0; + } + + /** + * Returns the reflecting plane characteristics at which the signal has bounced. + * + *

{@link #hasReflectingPlane()} must be true when calling this method. Otherwise, an + * {@link UnsupportedOperationException} will be thrown. + */ + @NonNull + public GnssReflectingPlane getReflectingPlane() { + if (!hasReflectingPlane()) { + throw new UnsupportedOperationException( + "getReflectingPlane() is not supported when hasReflectingPlane() is false"); + } + return mReflectingPlane; + } + + /** Returns {@code true} if {@link #getAttenuationDb()} is valid. */ + public boolean hasAttenuation() { + return (mFlags & HAS_ATTENUATION_MASK) != 0; + } + + /** + * Returns the expected reduction of signal strength of this path in non-negative dB. + * + *

{@link #hasAttenuation()} must be true when calling this method. Otherwise, an + * {@link UnsupportedOperationException} will be thrown. + */ + @FloatRange(from = 0.0f) + public float getAttenuationDb() { + if (!hasAttenuation()) { + throw new UnsupportedOperationException( + "getAttenuationDb() is not supported when hasAttenuation() is false"); + } + return mAttenuationDb; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel parcel, int parcelFlags) { + parcel.writeInt(mFlags); + if (hasExcessPathLength()) { + parcel.writeFloat(mExcessPathLengthMeters); + } + if (hasExcessPathLengthUncertainty()) { + parcel.writeFloat(mExcessPathLengthUncertaintyMeters); + } + if (hasReflectingPlane()) { + mReflectingPlane.writeToParcel(parcel, parcelFlags); + } + if (hasAttenuation()) { + parcel.writeFloat(mAttenuationDb); + } + } + + public static final @NonNull Creator CREATOR = + new Creator() { + @Override + @NonNull + public GnssExcessPathInfo createFromParcel(@NonNull Parcel parcel) { + int flags = parcel.readInt(); + float excessPathLengthMeters = + (flags & HAS_EXCESS_PATH_LENGTH_MASK) != 0 + ? parcel.readFloat() : 0; + float excessPathLengthUncertaintyMeters = + (flags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0 + ? parcel.readFloat() : 0; + GnssReflectingPlane reflectingPlane = + (flags & HAS_REFLECTING_PLANE_MASK) != 0 + ? GnssReflectingPlane.CREATOR.createFromParcel(parcel) : null; + float attenuationDb = + (flags & HAS_ATTENUATION_MASK) != 0 + ? parcel.readFloat() : 0; + return new GnssExcessPathInfo(flags, excessPathLengthMeters, + excessPathLengthUncertaintyMeters, reflectingPlane, attenuationDb); + } + + @Override + public GnssExcessPathInfo[] newArray(int i) { + return new GnssExcessPathInfo[i]; + } + }; + + @Override + public boolean equals(Object obj) { + if (obj instanceof GnssExcessPathInfo) { + GnssExcessPathInfo that = (GnssExcessPathInfo) obj; + return this.mFlags == that.mFlags + && (!hasExcessPathLength() || Float.compare(this.mExcessPathLengthMeters, + that.mExcessPathLengthMeters) == 0) + && (!hasExcessPathLengthUncertainty() || Float.compare( + this.mExcessPathLengthUncertaintyMeters, + that.mExcessPathLengthUncertaintyMeters) == 0) + && (!hasReflectingPlane() || Objects.equals(this.mReflectingPlane, + that.mReflectingPlane)) + && (!hasAttenuation() || Float.compare(this.mAttenuationDb, + that.mAttenuationDb) == 0); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(mFlags, + mExcessPathLengthMeters, + mExcessPathLengthUncertaintyMeters, + mReflectingPlane, + mAttenuationDb); + } + + @NonNull + @Override + public String toString() { + StringBuilder builder = new StringBuilder("GnssExcessPathInfo["); + if (hasExcessPathLength()) { + builder.append(" ExcessPathLengthMeters=").append(mExcessPathLengthMeters); + } + if (hasExcessPathLengthUncertainty()) { + builder.append(" ExcessPathLengthUncertaintyMeters=").append( + mExcessPathLengthUncertaintyMeters); + } + if (hasReflectingPlane()) { + builder.append(" ReflectingPlane=").append(mReflectingPlane); + } + if (hasAttenuation()) { + builder.append(" AttenuationDb=").append(mAttenuationDb); + } + builder.append(']'); + return builder.toString(); + } + + /** Builder for {@link GnssExcessPathInfo}. */ + public static final class Builder { + private int mFlags; + private float mExcessPathLengthMeters; + private float mExcessPathLengthUncertaintyMeters; + @Nullable + private GnssReflectingPlane mReflectingPlane; + private float mAttenuationDb; + + /** Constructor for {@link Builder}. */ + public Builder() {} + + /** + * 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) { + Preconditions.checkArgumentInRange(excessPathLengthMeters, 0, Float.MAX_VALUE, + "excessPathLengthMeters"); + mExcessPathLengthMeters = excessPathLengthMeters; + mFlags |= HAS_EXCESS_PATH_LENGTH_MASK; + return this; + } + + /** + * Clears the excess path length. + * + *

This is to negate {@link #setExcessPathLengthMeters} call. + */ + @NonNull + public Builder clearExcessPathLengthMeters() { + mExcessPathLengthMeters = 0; + mFlags &= ~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) { + Preconditions.checkArgumentInRange(excessPathLengthUncertaintyMeters, 0, + Float.MAX_VALUE, "excessPathLengthUncertaintyMeters"); + mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; + mFlags |= HAS_EXCESS_PATH_LENGTH_UNC_MASK; + return this; + } + + /** + * Clears the error estimate (1-sigma) for the excess path length estimate + * + *

This is to negate {@link #setExcessPathLengthUncertaintyMeters} call. + */ + @NonNull + public Builder clearExcessPathLengthUncertaintyMeters() { + mExcessPathLengthUncertaintyMeters = 0; + mFlags &= ~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) { + mFlags |= HAS_REFLECTING_PLANE_MASK; + } else { + mFlags &= ~HAS_REFLECTING_PLANE_MASK; + } + return this; + } + + /** + * Sets the attenuation value in dB. + */ + @NonNull + public Builder setAttenuationDb(@FloatRange(from = 0.0f) float attenuationDb) { + Preconditions.checkArgumentInRange(attenuationDb, 0, Float.MAX_VALUE, + "attenuationDb"); + mAttenuationDb = attenuationDb; + mFlags |= HAS_ATTENUATION_MASK; + return this; + } + + /** + * Clears the attenuation value in dB. + * + *

This is to negate {@link #setAttenuationDb(float)} call. + */ + @NonNull + public Builder clearAttenuationDb() { + mAttenuationDb = 0; + mFlags &= ~HAS_ATTENUATION_MASK; + return this; + } + + /** Builds a {@link GnssExcessPathInfo} instance as specified by this builder. */ + @NonNull + public GnssExcessPathInfo build() { + return new GnssExcessPathInfo( + mFlags, + mExcessPathLengthMeters, + mExcessPathLengthUncertaintyMeters, + mReflectingPlane, + mAttenuationDb); + } + } +} diff --git a/location/java/android/location/GnssReflectingPlane.java b/location/java/android/location/GnssReflectingPlane.java index 1acdd1ecce0b6..115cbec5e4de3 100644 --- a/location/java/android/location/GnssReflectingPlane.java +++ b/location/java/android/location/GnssReflectingPlane.java @@ -22,9 +22,14 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + /** * Holds the characteristics of the reflecting plane that a satellite signal has bounced from. * + *

Starting with Android T, this class supports {@link #equals} and {@link #hashCode}, which + * are not supported before that. + * * @hide */ @SystemApi @@ -107,18 +112,6 @@ public final class GnssReflectingPlane implements Parcelable { } }; - @NonNull - @Override - public String toString() { - final String format = " %-29s = %s\n"; - StringBuilder builder = new StringBuilder("ReflectingPlane:\n"); - builder.append(String.format(format, "LatitudeDegrees = ", mLatitudeDegrees)); - builder.append(String.format(format, "LongitudeDegrees = ", mLongitudeDegrees)); - builder.append(String.format(format, "AltitudeMeters = ", mAltitudeMeters)); - builder.append(String.format(format, "AzimuthDegrees = ", mAzimuthDegrees)); - return builder.toString(); - } - @Override public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeDouble(mLatitudeDegrees); @@ -127,6 +120,35 @@ public final class GnssReflectingPlane implements Parcelable { parcel.writeDouble(mAzimuthDegrees); } + @NonNull + @Override + public String toString() { + StringBuilder builder = new StringBuilder("ReflectingPlane["); + builder.append(" LatitudeDegrees=").append(mLatitudeDegrees); + builder.append(" LongitudeDegrees=").append(mLongitudeDegrees); + builder.append(" AltitudeMeters=").append(mAltitudeMeters); + builder.append(" AzimuthDegrees=").append(mAzimuthDegrees); + builder.append(']'); + return builder.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof GnssReflectingPlane) { + GnssReflectingPlane that = (GnssReflectingPlane) obj; + return Double.compare(this.mLatitudeDegrees, that.mLatitudeDegrees) == 0 + && Double.compare(this.mLongitudeDegrees, that.mLongitudeDegrees) == 0 + && Double.compare(this.mAltitudeMeters, that.mAltitudeMeters) == 0 + && Double.compare(this.mAzimuthDegrees, that.mAzimuthDegrees) == 0; + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(mLatitudeDegrees, mLatitudeDegrees, mAltitudeMeters, mAzimuthDegrees); + } + /** Builder for {@link GnssReflectingPlane} */ public static final class Builder { /** For documentation, see corresponding fields in {@link GnssReflectingPlane}. */ diff --git a/location/java/android/location/GnssSingleSatCorrection.java b/location/java/android/location/GnssSingleSatCorrection.java index 262630b79cb02..a7fce0aaaf6c5 100644 --- a/location/java/android/location/GnssSingleSatCorrection.java +++ b/location/java/android/location/GnssSingleSatCorrection.java @@ -16,6 +16,11 @@ package android.location; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC; +import static android.hardware.gnss.measurement_corrections.SingleSatCorrection.SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY; + import android.annotation.FloatRange; import android.annotation.IntRange; import android.annotation.NonNull; @@ -26,6 +31,8 @@ import android.os.Parcelable; import com.android.internal.util.Preconditions; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -36,106 +43,47 @@ import java.util.Objects; @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; + private static final int HAS_PROB_SAT_IS_LOS_MASK = + SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY; + private static final int HAS_COMBINED_EXCESS_PATH_LENGTH_MASK = + SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH; + private static final int HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK = + SINGLE_SAT_CORRECTION_HAS_COMBINED_EXCESS_PATH_LENGTH_UNC; + private static final int HAS_COMBINED_ATTENUATION_MASK = + SINGLE_SAT_CORRECTION_HAS_COMBINED_ATTENUATION; - /** - * 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) */ + /* 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 - * - *

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. - * - *

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; + private final float mCombinedExcessPathLengthMeters; + private final float mCombinedExcessPathLengthUncertaintyMeters; + private final float mCombinedAttenuationDb; - /** - * 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 - * - *

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; + @NonNull + private final List mGnssExcessPathInfoList; private GnssSingleSatCorrection(int singleSatCorrectionFlags, int constellationType, int satId, float carrierFrequencyHz, float probSatIsLos, float excessPathLengthMeters, - float excessPathLengthUncertaintyMeters, GnssReflectingPlane reflectingPlane) { + float excessPathLengthUncertaintyMeters, + float combinedAttenuationDb, + @NonNull List gnssExcessPathInfoList) { mSingleSatCorrectionFlags = singleSatCorrectionFlags; mConstellationType = constellationType; mSatId = satId; mCarrierFrequencyHz = carrierFrequencyHz; mProbSatIsLos = probSatIsLos; - mExcessPathLengthMeters = excessPathLengthMeters; - mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; - mReflectingPlane = reflectingPlane; + mCombinedExcessPathLengthMeters = excessPathLengthMeters; + mCombinedExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; + mCombinedAttenuationDb = combinedAttenuationDb; + mGnssExcessPathInfoList = gnssExcessPathInfoList; } /** - * Gets a bitmask of fields present in this object + * Gets a bitmask of fields present in this object. * * @hide */ @@ -193,29 +141,46 @@ public final class GnssSingleSatCorrection implements Parcelable { } /** - * Returns the Excess path length to be subtracted from pseudorange before using it in + * Returns the combined excess path length to be subtracted from pseudorange before using it in * calculating location. */ @FloatRange(from = 0.0f) public float getExcessPathLengthMeters() { - return mExcessPathLengthMeters; + return mCombinedExcessPathLengthMeters; } - /** Returns the error estimate (1-sigma) for the Excess path length estimate */ + /** Returns the error estimate (1-sigma) for the combined excess path length estimate. */ @FloatRange(from = 0.0f) public float getExcessPathLengthUncertaintyMeters() { - return mExcessPathLengthUncertaintyMeters; + return mCombinedExcessPathLengthUncertaintyMeters; } /** - * Returns the reflecting plane characteristics at which the signal has bounced + * Returns the combined expected reduction of signal strength for this satellite in + * non-negative dB. + */ + @FloatRange(from = 0.0f) + public float getCombinedAttenuationDb() { + return mCombinedAttenuationDb; + } + + /** + * Returns the reflecting plane characteristics at which the signal has bounced. * - *

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 + * @deprecated Combined excess path does not have a reflecting plane. */ @Nullable + @Deprecated public GnssReflectingPlane getReflectingPlane() { - return mReflectingPlane; + return null; + } + + /** + * Returns the list of {@link GnssExcessPathInfo} associated with this satellite signal. + */ + @NonNull + public List getGnssExcessPathInfoList() { + return mGnssExcessPathInfoList; } /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */ @@ -225,17 +190,27 @@ public final class GnssSingleSatCorrection implements Parcelable { /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */ public boolean hasExcessPathLength() { - return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0; + return (mSingleSatCorrectionFlags & HAS_COMBINED_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; + return (mSingleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK) != 0; } - /** Returns {@code true} if {@link #getReflectingPlane()} is valid. */ + /** + * Returns {@code true} if {@link #getReflectingPlane()} is valid. + * + * @deprecated Combined excess path does not have a reflecting plane. + */ + @Deprecated public boolean hasReflectingPlane() { - return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0; + return false; + } + + /** Returns {@code true} if {@link #getCombinedAttenuationDb()} is valid. */ + public boolean hasCombinedAttenuation() { + return (mSingleSatCorrectionFlags & HAS_COMBINED_ATTENUATION_MASK) != 0; } @Override @@ -253,14 +228,15 @@ public final class GnssSingleSatCorrection implements Parcelable { parcel.writeFloat(mProbSatIsLos); } if (hasExcessPathLength()) { - parcel.writeFloat(mExcessPathLengthMeters); + parcel.writeFloat(mCombinedExcessPathLengthMeters); } if (hasExcessPathLengthUncertainty()) { - parcel.writeFloat(mExcessPathLengthUncertaintyMeters); + parcel.writeFloat(mCombinedExcessPathLengthUncertaintyMeters); } - if (hasReflectingPlane()) { - mReflectingPlane.writeToParcel(parcel, flags); + if (hasCombinedAttenuation()) { + parcel.writeFloat(mCombinedAttenuationDb); } + parcel.writeTypedList(mGnssExcessPathInfoList); } public static final Creator CREATOR = @@ -274,18 +250,21 @@ public final class GnssSingleSatCorrection implements Parcelable { float carrierFrequencyHz = parcel.readFloat(); float probSatIsLos = (singleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0 ? parcel.readFloat() : 0; - float excessPathLengthMeters = - (singleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0 + float combinedExcessPathLengthMeters = + (singleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_MASK) != 0 ? parcel.readFloat() : 0; - float excessPathLengthUncertaintyMeters = - (singleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0 + float combinedExcessPathLengthUncertaintyMeters = + (singleSatCorrectionFlags & HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK) + != 0 ? parcel.readFloat() : 0; + float combinedAttenuationDb = + (singleSatCorrectionFlags & HAS_COMBINED_ATTENUATION_MASK) != 0 ? parcel.readFloat() : 0; - GnssReflectingPlane reflectingPlane = - (singleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0 - ? GnssReflectingPlane.CREATOR.createFromParcel(parcel) : null; + List gnssExcessPathInfoList = parcel.createTypedArrayList( + GnssExcessPathInfo.CREATOR); return new GnssSingleSatCorrection(singleSatCorrectionFlags, constellationType, - satId, carrierFrequencyHz, probSatIsLos, excessPathLengthMeters, - excessPathLengthUncertaintyMeters, reflectingPlane); + satId, carrierFrequencyHz, probSatIsLos, combinedExcessPathLengthMeters, + combinedExcessPathLengthUncertaintyMeters, combinedAttenuationDb, + gnssExcessPathInfoList); } @Override @@ -296,56 +275,24 @@ public final class GnssSingleSatCorrection implements Parcelable { @Override public boolean equals(Object obj) { - if (this == obj) { - return true; + if (obj instanceof GnssSingleSatCorrection) { + GnssSingleSatCorrection that = (GnssSingleSatCorrection) obj; + return this.mSingleSatCorrectionFlags == that.mSingleSatCorrectionFlags + && this.mConstellationType == that.mConstellationType + && this.mSatId == that.mSatId + && Float.compare(mCarrierFrequencyHz, that.mCarrierFrequencyHz) == 0 + && (!hasValidSatelliteLineOfSight() || Float.compare(mProbSatIsLos, + that.mProbSatIsLos) == 0) + && (!hasExcessPathLength() || Float.compare(mCombinedExcessPathLengthMeters, + that.mCombinedExcessPathLengthMeters) == 0) + && (!hasExcessPathLengthUncertainty() || Float.compare( + mCombinedExcessPathLengthUncertaintyMeters, + that.mCombinedExcessPathLengthUncertaintyMeters) == 0) + && (!hasCombinedAttenuation() || Float.compare(mCombinedAttenuationDb, + that.mCombinedAttenuationDb) == 0) + && mGnssExcessPathInfoList.equals(that.mGnssExcessPathInfoList); } - if (!(obj instanceof GnssSingleSatCorrection)) { - return false; - } - - GnssSingleSatCorrection other = (GnssSingleSatCorrection) obj; - if (mConstellationType != other.mConstellationType) { - return false; - } - if (mSatId != other.mSatId) { - return false; - } - if (Float.compare(mCarrierFrequencyHz, other.mCarrierFrequencyHz) != 0) { - return false; - } - - if (hasValidSatelliteLineOfSight() != other.hasValidSatelliteLineOfSight()) { - return false; - } - if (hasValidSatelliteLineOfSight() - && Float.compare(mProbSatIsLos, other.mProbSatIsLos) != 0) { - return false; - } - - if (hasExcessPathLength() != other.hasExcessPathLength()) { - return false; - } - if (hasExcessPathLength() - && Float.compare(mExcessPathLengthMeters, other.mExcessPathLengthMeters) != 0) { - return false; - } - - if (hasExcessPathLengthUncertainty() != other.hasExcessPathLengthUncertainty()) { - return false; - } - if (hasExcessPathLengthUncertainty() && Float.compare(mExcessPathLengthUncertaintyMeters, - other.mExcessPathLengthUncertaintyMeters) != 0) { - return false; - } - - if (hasReflectingPlane() != other.hasReflectingPlane()) { - return false; - } - if (hasReflectingPlane() - && !mReflectingPlane.equals(other.mReflectingPlane)) { - return false; - } - return true; + return false; } @Override @@ -355,9 +302,10 @@ public final class GnssSingleSatCorrection implements Parcelable { mSatId, mCarrierFrequencyHz, mProbSatIsLos, - mExcessPathLengthMeters, - mExcessPathLengthUncertaintyMeters, - mReflectingPlane); + mCombinedExcessPathLengthMeters, + mCombinedExcessPathLengthUncertaintyMeters, + mCombinedAttenuationDb, + mGnssExcessPathInfoList); } @NonNull @@ -371,14 +319,19 @@ public final class GnssSingleSatCorrection implements Parcelable { builder.append(" ProbSatIsLos=").append(mProbSatIsLos); } if (hasExcessPathLength()) { - builder.append(" ExcessPathLengthMeters=").append(mExcessPathLengthMeters); + builder.append(" CombinedExcessPathLengthMeters=").append( + mCombinedExcessPathLengthMeters); } if (hasExcessPathLengthUncertainty()) { - builder.append(" ExcessPathLengthUncertaintyMeters=").append( - mExcessPathLengthUncertaintyMeters); + builder.append(" CombinedExcessPathLengthUncertaintyMeters=").append( + mCombinedExcessPathLengthUncertaintyMeters); } - if (hasReflectingPlane()) { - builder.append(" ReflectingPlane=").append(mReflectingPlane); + if (hasCombinedAttenuation()) { + builder.append(" CombinedAttenuationDb=").append( + mCombinedAttenuationDb); + } + if (!mGnssExcessPathInfoList.isEmpty()) { + builder.append(' ').append(mGnssExcessPathInfoList.toString()); } builder.append(']'); return builder.toString(); @@ -386,21 +339,16 @@ public final class GnssSingleSatCorrection implements Parcelable { /** 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; + private float mCombinedExcessPathLengthMeters; + private float mCombinedExcessPathLengthUncertaintyMeters; + private float mCombinedAttenuationDb; + @NonNull + private List mGnssExcessInfoList = new ArrayList<>(); /** Sets the constellation type. */ @NonNull public Builder setConstellationType( @@ -409,18 +357,18 @@ public final class GnssSingleSatCorrection implements Parcelable { return this; } - /** Sets the Satellite ID defined in the ICD of the given constellation. */ + /** Sets the satellite ID defined in the ICD of the given constellation. */ @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) { Preconditions.checkArgumentNonnegative(satId, "satId should be non-negative."); mSatId = satId; return this; } - /** Sets the Carrier frequency in Hz. */ + /** Sets the carrier frequency in Hz. */ @NonNull public Builder setCarrierFrequencyHz( @FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) { - Preconditions.checkArgument( - carrierFrequencyHz >= 0, "carrierFrequencyHz should be non-negative."); + Preconditions.checkArgumentInRange( + carrierFrequencyHz, 0, Float.MAX_VALUE, "carrierFrequencyHz"); mCarrierFrequencyHz = carrierFrequencyHz; return this; } @@ -450,58 +398,90 @@ public final class GnssSingleSatCorrection implements Parcelable { } /** - * Sets the Excess path length to be subtracted from pseudorange before using it in + * Sets the combined excess path length to be subtracted from pseudorange before using it in * calculating location. */ - @NonNull public Builder setExcessPathLengthMeters( - @FloatRange(from = 0.0f) float excessPathLengthMeters) { - Preconditions.checkArgument(excessPathLengthMeters >= 0, - "excessPathLengthMeters should be non-negative."); - mExcessPathLengthMeters = excessPathLengthMeters; - mSingleSatCorrectionFlags |= HAS_EXCESS_PATH_LENGTH_MASK; + @NonNull + public Builder setExcessPathLengthMeters( + @FloatRange(from = 0.0f) float combinedExcessPathLengthMeters) { + Preconditions.checkArgumentInRange(combinedExcessPathLengthMeters, 0, Float.MAX_VALUE, + "excessPathLengthMeters"); + mCombinedExcessPathLengthMeters = combinedExcessPathLengthMeters; + mSingleSatCorrectionFlags |= HAS_COMBINED_EXCESS_PATH_LENGTH_MASK; return this; } /** - * Clears the Excess path length. + * Clears the combined excess path length. * *

This is to negate {@link #setExcessPathLengthMeters} call. */ @NonNull public Builder clearExcessPathLengthMeters() { - mExcessPathLengthMeters = 0; - mSingleSatCorrectionFlags &= ~HAS_EXCESS_PATH_LENGTH_MASK; + mCombinedExcessPathLengthMeters = 0; + mSingleSatCorrectionFlags &= ~HAS_COMBINED_EXCESS_PATH_LENGTH_MASK; return this; } - /** Sets the error estimate (1-sigma) for the Excess path length estimate */ + /** Sets the error estimate (1-sigma) for the combined excess path length estimate. */ @NonNull public Builder setExcessPathLengthUncertaintyMeters( - @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) { - Preconditions.checkArgument(excessPathLengthUncertaintyMeters >= 0, - "excessPathLengthUncertaintyMeters should be non-negative."); - mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters; - mSingleSatCorrectionFlags |= HAS_EXCESS_PATH_LENGTH_UNC_MASK; + @FloatRange(from = 0.0f) float combinedExcessPathLengthUncertaintyMeters) { + Preconditions.checkArgumentInRange(combinedExcessPathLengthUncertaintyMeters, 0, + Float.MAX_VALUE, "excessPathLengthUncertaintyMeters"); + mCombinedExcessPathLengthUncertaintyMeters = combinedExcessPathLengthUncertaintyMeters; + mSingleSatCorrectionFlags |= HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK; return this; } /** - * Clears the error estimate (1-sigma) for the Excess path length estimate + * Clears the error estimate (1-sigma) for the combined excess path length estimate. * *

This is to negate {@link #setExcessPathLengthUncertaintyMeters} call. */ @NonNull public Builder clearExcessPathLengthUncertaintyMeters() { - mExcessPathLengthUncertaintyMeters = 0; - mSingleSatCorrectionFlags &= ~HAS_EXCESS_PATH_LENGTH_UNC_MASK; + mCombinedExcessPathLengthUncertaintyMeters = 0; + mSingleSatCorrectionFlags &= ~HAS_COMBINED_EXCESS_PATH_LENGTH_UNC_MASK; return this; } - /** Sets the reflecting plane information */ + /** + * Sets the combined attenuation in Db. + */ + @NonNull public Builder setCombinedAttenuationDb( + @FloatRange(from = 0.0f) float combinedAttenuationDb) { + Preconditions.checkArgumentInRange(combinedAttenuationDb, 0, Float.MAX_VALUE, + "combinedAttenuationDb"); + mCombinedAttenuationDb = combinedAttenuationDb; + mSingleSatCorrectionFlags |= HAS_COMBINED_ATTENUATION_MASK; + return this; + } + + /** + * Clears the combined attenuation. + * + *

This is to negate {@link #setCombinedAttenuationDb} call. + */ + @NonNull public Builder clearCombinedAttenuationDb() { + mCombinedAttenuationDb = 0; + mSingleSatCorrectionFlags &= ~HAS_COMBINED_ATTENUATION_MASK; + return this; + } + + /** + * Sets the reflecting plane information. + * + * @deprecated Combined excess path does not have a reflecting plane. + */ + @Deprecated @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) { - mReflectingPlane = reflectingPlane; - if (reflectingPlane != null) { - mSingleSatCorrectionFlags |= HAS_REFLECTING_PLANE_MASK; - } else { - mSingleSatCorrectionFlags &= ~HAS_REFLECTING_PLANE_MASK; - } + return this; + } + + /** + * Sets the collection of {@link GnssExcessPathInfo}. + */ + @NonNull + public Builder setGnssExcessPathInfoList(@NonNull List infoList) { + mGnssExcessInfoList = new ArrayList<>(infoList); return this; } @@ -512,9 +492,10 @@ public final class GnssSingleSatCorrection implements Parcelable { mSatId, mCarrierFrequencyHz, mProbSatIsLos, - mExcessPathLengthMeters, - mExcessPathLengthUncertaintyMeters, - mReflectingPlane); + mCombinedExcessPathLengthMeters, + mCombinedExcessPathLengthUncertaintyMeters, + mCombinedAttenuationDb, + mGnssExcessInfoList); } } } diff --git a/services/core/jni/gnss/MeasurementCorrections.cpp b/services/core/jni/gnss/MeasurementCorrections.cpp index 8a3d84cbe9c62..07d0a45e9c40f 100644 --- a/services/core/jni/gnss/MeasurementCorrections.cpp +++ b/services/core/jni/gnss/MeasurementCorrections.cpp @@ -44,6 +44,7 @@ using SingleSatCorrection_Aidl = using ReflectingPlane_V1_0 = android::hardware::gnss::measurement_corrections::V1_0::ReflectingPlane; using ReflectingPlane_Aidl = android::hardware::gnss::measurement_corrections::ReflectingPlane; +using ExcessPathInfo = SingleSatCorrection_Aidl::ExcessPathInfo; using GnssConstellationType_V1_0 = android::hardware::gnss::V1_0::GnssConstellationType; using GnssConstellationType_V2_0 = android::hardware::gnss::V2_0::GnssConstellationType; using GnssConstellationType_Aidl = android::hardware::gnss::GnssConstellationType; @@ -62,7 +63,7 @@ jmethodID method_correctionsHasEnvironmentBearing; jmethodID method_correctionsGetEnvironmentBearingDegrees; jmethodID method_correctionsGetEnvironmentBearingUncertaintyDegrees; jmethodID method_listSize; -jmethodID method_correctionListGet; +jmethodID method_listGet; jmethodID method_correctionSatFlags; jmethodID method_correctionSatConstType; jmethodID method_correctionSatId; @@ -71,10 +72,17 @@ jmethodID method_correctionSatIsLosProb; jmethodID method_correctionSatEpl; jmethodID method_correctionSatEplUnc; jmethodID method_correctionSatRefPlane; +jmethodID method_correctionSatAttenuation; +jmethodID method_correctionSatExcessPathInfoList; jmethodID method_correctionPlaneLatDeg; jmethodID method_correctionPlaneLngDeg; jmethodID method_correctionPlaneAltDeg; jmethodID method_correctionPlaneAzimDeg; +jmethodID method_excessPathInfoFlags; +jmethodID method_excessPathInfoEpl; +jmethodID method_excessPathInfoEplUnc; +jmethodID method_excessPathInfoRefPlane; +jmethodID method_excessPathInfoAttenuation; } // anonymous namespace void MeasurementCorrections_class_init_once(JNIEnv* env, jclass clazz) { @@ -103,7 +111,7 @@ void MeasurementCorrections_class_init_once(JNIEnv* env, jclass clazz) { jclass corrListClass = env->FindClass("java/util/List"); method_listSize = env->GetMethodID(corrListClass, "size", "()I"); - method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;"); + method_listGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;"); jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection"); method_correctionSatFlags = @@ -121,12 +129,27 @@ void MeasurementCorrections_class_init_once(JNIEnv* env, jclass clazz) { env->GetMethodID(singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F"); method_correctionSatRefPlane = env->GetMethodID(singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;"); + method_correctionSatAttenuation = + env->GetMethodID(singleSatCorrClass, "getCombinedAttenuationDb", "()F"); + method_correctionSatExcessPathInfoList = + env->GetMethodID(singleSatCorrClass, "getGnssExcessPathInfoList", "()Ljava/util/List;"); jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane"); method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D"); method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D"); method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D"); method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D"); + + jclass excessPathInfoClass = env->FindClass("android/location/GnssExcessPathInfo"); + method_excessPathInfoFlags = env->GetMethodID(excessPathInfoClass, "getFlags", "()I"); + method_excessPathInfoEpl = + env->GetMethodID(excessPathInfoClass, "getExcessPathLengthMeters", "()F"); + method_excessPathInfoEplUnc = + env->GetMethodID(excessPathInfoClass, "getExcessPathLengthUncertaintyMeters", "()F"); + method_excessPathInfoRefPlane = env->GetMethodID(excessPathInfoClass, "getReflectingPlane", + "()Landroid/location/GnssReflectingPlane;"); + method_excessPathInfoAttenuation = + env->GetMethodID(excessPathInfoClass, "getAttenuationDb", "()F"); } template <> @@ -324,7 +347,8 @@ jboolean MeasurementCorrectionsIface_V1_1::setCallback( SingleSatCorrection_V1_0 MeasurementCorrectionsUtil::getSingleSatCorrection_1_0_withoutConstellation( JNIEnv* env, jobject singleSatCorrectionObj) { - jint correctionFlags = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags); + uint16_t corrFlags = static_cast( + env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags)); jint satId = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId); jfloat carrierFreqHz = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatCarrierFreq); @@ -332,14 +356,16 @@ MeasurementCorrectionsUtil::getSingleSatCorrection_1_0_withoutConstellation( env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatIsLosProb); jfloat eplMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl); jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEplUnc); - uint16_t corrFlags = static_cast(correctionFlags); ReflectingPlane_V1_0 reflectingPlane; - if ((corrFlags & GnssSingleSatCorrectionFlags_V1_0::HAS_REFLECTING_PLANE) != 0) - MeasurementCorrectionsUtil::getReflectingPlane(env, - singleSatCorrectionObj, + if ((corrFlags & GnssSingleSatCorrectionFlags_V1_0::HAS_REFLECTING_PLANE) != 0) { + jobject reflectingPlaneObj = + env->CallObjectMethod(singleSatCorrectionObj, method_correctionSatRefPlane); + MeasurementCorrectionsUtil::setReflectingPlane(env, + reflectingPlaneObj, reflectingPlane); - + env->DeleteLocalRef(reflectingPlaneObj); + } SingleSatCorrection_V1_0 singleSatCorrection = { .singleSatCorrectionFlags = corrFlags, .svid = static_cast(satId), @@ -349,13 +375,14 @@ MeasurementCorrectionsUtil::getSingleSatCorrection_1_0_withoutConstellation( .excessPathLengthUncertaintyMeters = eplUncMeters, .reflectingPlane = reflectingPlane, }; - return singleSatCorrection; } SingleSatCorrection_Aidl MeasurementCorrectionsUtil::getSingleSatCorrection_Aidl( JNIEnv* env, jobject singleSatCorrectionObj) { - jint correctionFlags = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags); + int32_t corrFlags = static_cast( + env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags)); + jint constType = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatConstType); jint satId = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatId); jfloat carrierFreqHz = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatCarrierFreq); @@ -363,15 +390,10 @@ SingleSatCorrection_Aidl MeasurementCorrectionsUtil::getSingleSatCorrection_Aidl env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatIsLosProb); jfloat eplMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl); jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEplUnc); - int32_t corrFlags = static_cast(correctionFlags); - - ReflectingPlane_Aidl reflectingPlane; - if ((corrFlags & SingleSatCorrection_Aidl::SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE) != 0) - MeasurementCorrectionsUtil::getReflectingPlane(env, - singleSatCorrectionObj, - reflectingPlane); - - jint constType = env->CallIntMethod(singleSatCorrectionObj, method_correctionSatConstType); + jfloat attenuationDb = + env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatAttenuation); + std::vector excessPathInfos = + MeasurementCorrectionsUtil::getExcessPathInfoList(env, singleSatCorrectionObj); SingleSatCorrection_Aidl singleSatCorrection; singleSatCorrection.singleSatCorrectionFlags = corrFlags; @@ -379,9 +401,10 @@ SingleSatCorrection_Aidl MeasurementCorrectionsUtil::getSingleSatCorrection_Aidl singleSatCorrection.svid = static_cast(satId); singleSatCorrection.carrierFrequencyHz = carrierFreqHz; singleSatCorrection.probSatIsLos = probSatIsLos; - singleSatCorrection.excessPathLengthMeters = eplMeters; - singleSatCorrection.excessPathLengthUncertaintyMeters = eplUncMeters; - singleSatCorrection.reflectingPlane = reflectingPlane; + singleSatCorrection.combinedExcessPathLengthMeters = eplMeters; + singleSatCorrection.combinedExcessPathLengthUncertaintyMeters = eplUncMeters; + singleSatCorrection.combinedAttenuationDb = attenuationDb; + singleSatCorrection.excessPathInfos = excessPathInfos; return singleSatCorrection; } @@ -391,8 +414,7 @@ void MeasurementCorrectionsUtil::getSingleSatCorrectionList_1_0( hardware::hidl_vec& list) { for (uint16_t i = 0; i < list.size(); ++i) { jobject singleSatCorrectionObj = - env->CallObjectMethod(singleSatCorrectionList, method_correctionListGet, i); - + env->CallObjectMethod(singleSatCorrectionList, method_listGet, i); SingleSatCorrection_V1_0 singleSatCorrection = getSingleSatCorrection_1_0_withoutConstellation(env, singleSatCorrectionObj); @@ -410,7 +432,7 @@ void MeasurementCorrectionsUtil::getSingleSatCorrectionList_1_1( hardware::hidl_vec& list) { for (uint16_t i = 0; i < list.size(); ++i) { jobject singleSatCorrectionObj = - env->CallObjectMethod(singleSatCorrectionList, method_correctionListGet, i); + env->CallObjectMethod(singleSatCorrectionList, method_listGet, i); SingleSatCorrection_V1_0 singleSatCorrection_1_0 = getSingleSatCorrection_1_0_withoutConstellation(env, singleSatCorrectionObj); @@ -431,7 +453,7 @@ void MeasurementCorrectionsUtil::getSingleSatCorrectionList_Aidl( JNIEnv* env, jobject singleSatCorrectionList, std::vector& list) { for (uint16_t i = 0; i < list.size(); ++i) { jobject singleSatCorrectionObj = - env->CallObjectMethod(singleSatCorrectionList, method_correctionListGet, i); + env->CallObjectMethod(singleSatCorrectionList, method_listGet, i); SingleSatCorrection_Aidl singleSatCorrection_Aidl = getSingleSatCorrection_Aidl(env, singleSatCorrectionObj); @@ -441,4 +463,63 @@ void MeasurementCorrectionsUtil::getSingleSatCorrectionList_Aidl( } } +template <> +void MeasurementCorrectionsUtil::setReflectingPlaneAzimuthDegrees( + ReflectingPlane_V1_0& reflectingPlane, double azimuthDegreeRefPlane) { + reflectingPlane.azimuthDegrees = azimuthDegreeRefPlane; +} + +template <> +void MeasurementCorrectionsUtil::setReflectingPlaneAzimuthDegrees( + ReflectingPlane_Aidl& reflectingPlane, double azimuthDegreeRefPlane) { + reflectingPlane.reflectingPlaneAzimuthDegrees = azimuthDegreeRefPlane; +} + +std::vector MeasurementCorrectionsUtil::getExcessPathInfoList( + JNIEnv* env, jobject singleSatCorrectionObj) { + jobject excessPathInfoListObj = + env->CallObjectMethod(singleSatCorrectionObj, method_correctionSatExcessPathInfoList); + + int len = env->CallIntMethod(excessPathInfoListObj, method_listSize); + std::vector list(len); + for (int i = 0; i < len; ++i) { + jobject excessPathInfoObj = env->CallObjectMethod(excessPathInfoListObj, method_listGet, i); + list[i] = getExcessPathInfo(env, excessPathInfoObj); + env->DeleteLocalRef(excessPathInfoObj); + } + env->DeleteLocalRef(excessPathInfoListObj); + return list; +} + +ExcessPathInfo MeasurementCorrectionsUtil::getExcessPathInfo(JNIEnv* env, + jobject excessPathInfoObj) { + ExcessPathInfo excessPathInfo; + jint flags = env->CallIntMethod(excessPathInfoObj, method_excessPathInfoFlags); + excessPathInfo.excessPathInfoFlags = flags; + if ((flags & ExcessPathInfo::EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH) != 0) { + jfloat epl = env->CallFloatMethod(excessPathInfoObj, method_excessPathInfoEpl); + excessPathInfo.excessPathLengthMeters = epl; + } + if ((flags & ExcessPathInfo::EXCESS_PATH_INFO_HAS_EXCESS_PATH_LENGTH_UNC) != 0) { + jfloat eplUnc = env->CallFloatMethod(excessPathInfoObj, method_excessPathInfoEplUnc); + excessPathInfo.excessPathLengthUncertaintyMeters = eplUnc; + } + if ((flags & ExcessPathInfo::EXCESS_PATH_INFO_HAS_REFLECTING_PLANE) != 0) { + ReflectingPlane_Aidl reflectingPlane; + jobject reflectingPlaneObj = + env->CallObjectMethod(excessPathInfoObj, method_excessPathInfoRefPlane); + MeasurementCorrectionsUtil::setReflectingPlane(env, + reflectingPlaneObj, + reflectingPlane); + env->DeleteLocalRef(reflectingPlaneObj); + excessPathInfo.reflectingPlane = reflectingPlane; + } + if ((flags & ExcessPathInfo::EXCESS_PATH_INFO_HAS_ATTENUATION) != 0) { + jfloat attenuation = + env->CallFloatMethod(excessPathInfoObj, method_excessPathInfoAttenuation); + excessPathInfo.attenuationDb = attenuation; + } + return excessPathInfo; +} + } // namespace android::gnss diff --git a/services/core/jni/gnss/MeasurementCorrections.h b/services/core/jni/gnss/MeasurementCorrections.h index a2e602714326c..598ad48d6ac16 100644 --- a/services/core/jni/gnss/MeasurementCorrections.h +++ b/services/core/jni/gnss/MeasurementCorrections.h @@ -43,7 +43,7 @@ extern jmethodID method_correctionsHasEnvironmentBearing; extern jmethodID method_correctionsGetEnvironmentBearingDegrees; extern jmethodID method_correctionsGetEnvironmentBearingUncertaintyDegrees; extern jmethodID method_listSize; -extern jmethodID method_correctionListGet; +extern jmethodID method_listGet; extern jmethodID method_correctionSatFlags; extern jmethodID method_correctionSatConstType; extern jmethodID method_correctionSatId; @@ -52,6 +52,7 @@ extern jmethodID method_correctionSatIsLosProb; extern jmethodID method_correctionSatEpl; extern jmethodID method_correctionSatEplUnc; extern jmethodID method_correctionSatRefPlane; +extern jmethodID method_correctionSatExcessPathInfos; extern jmethodID method_correctionPlaneLatDeg; extern jmethodID method_correctionPlaneLngDeg; extern jmethodID method_correctionPlaneAltDeg; @@ -130,14 +131,20 @@ struct MeasurementCorrectionsUtil { static bool translateMeasurementCorrections(JNIEnv* env, jobject correctionsObj, T& corrections); template - static void getReflectingPlane(JNIEnv* env, jobject singleSatCorrectionObj, T& reflectingPlane); + static void setReflectingPlane(JNIEnv* env, jobject reflectingPlaneObj, T& reflectingPlane); + template + static void setReflectingPlaneAzimuthDegrees(T& reflectingPlane, double azimuthDegreeRefPlane); + + static std::vector< + android::hardware::gnss::measurement_corrections::SingleSatCorrection::ExcessPathInfo> + getExcessPathInfoList(JNIEnv* env, jobject correctionsObj); + static android::hardware::gnss::measurement_corrections::SingleSatCorrection::ExcessPathInfo + getExcessPathInfo(JNIEnv* env, jobject correctionsObj); }; template -void MeasurementCorrectionsUtil::getReflectingPlane(JNIEnv* env, jobject singleSatCorrectionObj, +void MeasurementCorrectionsUtil::setReflectingPlane(JNIEnv* env, jobject reflectingPlaneObj, T& reflectingPlane) { - jobject reflectingPlaneObj = - env->CallObjectMethod(singleSatCorrectionObj, method_correctionSatRefPlane); jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(reflectingPlaneObj, method_correctionPlaneLatDeg); jdouble longitudeDegreesRefPlane = @@ -149,8 +156,7 @@ void MeasurementCorrectionsUtil::getReflectingPlane(JNIEnv* env, jobject singleS reflectingPlane.latitudeDegrees = latitudeDegreesRefPlane; reflectingPlane.longitudeDegrees = longitudeDegreesRefPlane; reflectingPlane.altitudeMeters = altitudeDegreesRefPlane; - reflectingPlane.azimuthDegrees = azimuthDegreeRefPlane; - env->DeleteLocalRef(reflectingPlaneObj); + setReflectingPlaneAzimuthDegrees(reflectingPlane, azimuthDegreeRefPlane); } } // namespace android::gnss