Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1257c410 authored by Yu-Han Yang's avatar Yu-Han Yang Committed by Android (Google) Code Review
Browse files

Merge "Add GnssExcessPathInfo (frameworks/base)" into tm-dev

parents f9975966 97f3b91c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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",
+35 −3
Original line number Diff line number Diff line
@@ -5490,6 +5490,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<android.location.GnssExcessPathInfo> 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<android.location.CorrelationVector> getCorrelationVectors();
    method @Nullable public android.location.SatellitePvt getSatellitePvt();
@@ -5571,15 +5597,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<android.location.GnssExcessPathInfo> 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<android.location.GnssSingleSatCorrection> CREATOR;
@@ -5588,15 +5617,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<android.location.GnssExcessPathInfo>);
    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);
  }
+375 −0
Original line number Diff line number Diff line
/*
 * 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.
     *
     * <p>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.
     *
     * <p>{@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.
     *
     * <p>{@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.
     *
     * <p>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.
     *
     * <p>{@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.
     *
     * <p>{@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<GnssExcessPathInfo> CREATOR =
            new Creator<GnssExcessPathInfo>() {
                @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.
         *
         * <p>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
         *
         * <p>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.
         *
         * <p>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);
        }
    }
}
+33 −11
Original line number Diff line number Diff line
@@ -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.
 *
 * <p>Starting with Android T, this class supports {@link #equals} and {@link #hashCode}, which
 * are not supported before that.
 *
 * @hide
 */
@SystemApi
@@ -107,24 +112,41 @@ public final class GnssReflectingPlane implements Parcelable {
                }
            };

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int flags) {
        parcel.writeDouble(mLatitudeDegrees);
        parcel.writeDouble(mLongitudeDegrees);
        parcel.writeDouble(mAltitudeMeters);
        parcel.writeDouble(mAzimuthDegrees);
    }

    @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));
        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 void writeToParcel(@NonNull Parcel parcel, int flags) {
        parcel.writeDouble(mLatitudeDegrees);
        parcel.writeDouble(mLongitudeDegrees);
        parcel.writeDouble(mAltitudeMeters);
        parcel.writeDouble(mAzimuthDegrees);
    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} */
+188 −207

File changed.

Preview size limit exceeded, changes collapsed.

Loading