diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 730fce7c049a2..7f75ee312b6f4 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3975,6 +3975,25 @@ package android.location { method public void onLocationBatch(java.util.List); } + public final class CorrelationVector implements android.os.Parcelable { + method public int describeContents(); + method @IntRange(from=0) public int getFrequencyOffsetMetersPerSecond(); + method @NonNull public int[] getMagnitude(); + method @FloatRange(from=0.0f) public double getSamplingStartMeters(); + method @FloatRange(from=0.0f, fromInclusive=false) public double getSamplingWidthMeters(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + + public static final class CorrelationVector.Builder { + ctor public CorrelationVector.Builder(); + method @NonNull public android.location.CorrelationVector build(); + method @NonNull public android.location.CorrelationVector.Builder setFrequencyOffsetMetersPerSecond(@IntRange(from=0) int); + method @NonNull public android.location.CorrelationVector.Builder setMagnitude(@NonNull int[]); + method @NonNull public android.location.CorrelationVector.Builder setSamplingStartMeters(@FloatRange(from=0.0f) double); + method @NonNull public android.location.CorrelationVector.Builder setSamplingWidthMeters(@FloatRange(from=0.0f, fromInclusive=false) double); + } + public final class GnssCapabilities implements android.os.Parcelable { method public boolean hasGeofencing(); method public boolean hasLowPowerMode(); @@ -3983,6 +4002,7 @@ package android.location { method public boolean hasMeasurementCorrectionsLosSats(); method @Deprecated public boolean hasMeasurementCorrectionsReflectingPane(); method public boolean hasMeasurementCorrectionsReflectingPlane(); + method public boolean hasMeasurementCorrelationVectors(); method @Deprecated public boolean hasNavMessages(); method @Deprecated public boolean hasSatelliteBlacklist(); method public boolean hasSatelliteBlocklist(); @@ -3996,12 +4016,15 @@ package android.location { method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsExcessPathLength(boolean); method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsLosSats(boolean); method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrectionsReflectingPlane(boolean); + method @NonNull public android.location.GnssCapabilities.Builder setHasMeasurementCorrelationVectors(boolean); method @NonNull public android.location.GnssCapabilities.Builder setHasSatelliteBlocklist(boolean); method @NonNull public android.location.GnssCapabilities.Builder setHasSatellitePvt(boolean); } public final class GnssMeasurement implements android.os.Parcelable { + method @Nullable public java.util.Collection getCorrelationVectors(); method @Nullable public android.location.SatellitePvt getSatellitePvt(); + method public boolean hasCorrelationVectors(); method public boolean hasSatellitePvt(); } @@ -4035,6 +4058,14 @@ package android.location { method @NonNull public android.location.GnssMeasurementCorrections.Builder setVerticalPositionUncertaintyMeters(@FloatRange(from=0.0f) double); } + public final class GnssMeasurementRequest implements android.os.Parcelable { + method public boolean isCorrelationVectorOutputsEnabled(); + } + + public static final class GnssMeasurementRequest.Builder { + method @NonNull public android.location.GnssMeasurementRequest.Builder setCorrelationVectorOutputsEnabled(boolean); + } + public final class GnssReflectingPlane implements android.os.Parcelable { method public int describeContents(); method @FloatRange(from=-1000.0F, to=10000.0f) public double getAltitudeMeters(); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 62c660cbcb6cd..6e1ce1b6891c6 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -929,6 +929,7 @@ package android.location { method @Deprecated public void resetCarrierPhase(); method @Deprecated public void resetCarrierPhaseUncertainty(); method public void resetCodeType(); + method public void resetCorrelationVectors(); method public void resetFullInterSignalBiasNanos(); method public void resetFullInterSignalBiasUncertaintyNanos(); method public void resetSatelliteInterSignalBiasNanos(); @@ -948,6 +949,7 @@ package android.location { method public void setCn0DbHz(double); method public void setCodeType(@NonNull String); method public void setConstellationType(int); + method public void setCorrelationVectors(@Nullable java.util.Collection); method public void setFullInterSignalBiasNanos(double); method public void setFullInterSignalBiasUncertaintyNanos(@FloatRange(from=0.0) double); method public void setMultipathIndicator(int); diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt index 3bd88a47f30d6..216d340690833 100644 --- a/core/api/test-lint-baseline.txt +++ b/core/api/test-lint-baseline.txt @@ -468,6 +468,8 @@ GetterSetterNames: android.location.GnssMeasurement#setBasebandCn0DbHz(double): GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float): GetterSetterNames: android.location.GnssMeasurement#setCodeType(String): + +GetterSetterNames: android.location.GnssMeasurement#setCorrelationVectors(java.util.Collection): GetterSetterNames: android.location.GnssMeasurement#setFullInterSignalBiasNanos(double): diff --git a/location/java/android/location/CorrelationVector.java b/location/java/android/location/CorrelationVector.java new file mode 100644 index 0000000000000..eca35dd69362f --- /dev/null +++ b/location/java/android/location/CorrelationVector.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2020 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.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.Arrays; +import java.util.Objects; + +/** + * Contains info about the correlation output of incoming GNSS signal and a local copy of + * its corresponding spreading code at a given frequency offset. + * + * @hide + */ +@SystemApi +public final class CorrelationVector implements Parcelable { + + private final double mSamplingWidthMeters; + private final double mSamplingStartMeters; + private final int mFrequencyOffsetMetersPerSecond; + @NonNull private final int[] mMagnitude; + + /** + * Returns the space between correlation samples in meters. + */ + @FloatRange(from = 0.0f, fromInclusive = false) + public double getSamplingWidthMeters() { + return mSamplingWidthMeters; + } + + /** + * Returns the offset of the first sampling bin in meters. + * + *

The following sampling bins are located at positive offsets from this value as follows: + * samplingStartMeters, samplingStartMeters + samplingWidthMeters, ... , samplingStartMeters + + * (magnitude.size-1) * samplingWidthMeters. + * + */ + @FloatRange(from = 0.0f) + public double getSamplingStartMeters() { + return mSamplingStartMeters; + } + + /** + * Returns the frequency offset from reported pseudorange rate for this CorrelationVector. + */ + @IntRange(from = 0) + public int getFrequencyOffsetMetersPerSecond() { + return mFrequencyOffsetMetersPerSecond; + } + + /** + * Returns the data array representing normalized correlation magnitude values. + * + *

The data are normalized correlation magnitude values from -1 to 1, the reported value must + * be encoded as signed 16 bit integer where 1 is represented by 32767 and -1 is represented + * by -32768. + * + */ + @NonNull + public int[] getMagnitude() { + return mMagnitude.clone(); + } + + private CorrelationVector(Builder builder) { + Preconditions.checkNotNull(builder.mMagnitude, "Magnitude array must not be null"); + Preconditions.checkArgumentPositive(builder.mMagnitude.length, + "Magnitude array must have non-zero length"); + Preconditions.checkArgumentNonNegative(builder.mFrequencyOffsetMetersPerSecond, + "FrequencyOffsetMetersPerSecond must be non-negative (greater than or equal to 0)"); + Preconditions.checkArgument(builder.mSamplingWidthMeters > 0.0, + "SamplingWidthMeters must be positive (greater than 0)"); + Preconditions.checkArgument(builder.mSamplingStartMeters >= 0.0, + "SamplingStartMeters must be non-negative (greater than or equal to 0)"); + mMagnitude = builder.mMagnitude; + mFrequencyOffsetMetersPerSecond = builder.mFrequencyOffsetMetersPerSecond; + mSamplingWidthMeters = builder.mSamplingWidthMeters; + mSamplingStartMeters = builder.mSamplingStartMeters; + } + + private CorrelationVector(Parcel in) { + mSamplingWidthMeters = in.readDouble(); + mSamplingStartMeters = in.readDouble(); + mFrequencyOffsetMetersPerSecond = in.readInt(); + mMagnitude = new int[in.readInt()]; + in.readIntArray(mMagnitude); + } + + /* + * Method definitions to support Parcelable operations. + */ + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + @Override + public CorrelationVector createFromParcel(Parcel parcel) { + return new CorrelationVector(parcel); + } + + @Override + public CorrelationVector[] newArray(int size) { + return new CorrelationVector[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @NonNull + @Override + public String toString() { + return "CorrelationVector{" + + "FrequencyOffsetMetersPerSecond=" + mFrequencyOffsetMetersPerSecond + + ", SamplingWidthMeters=" + mSamplingWidthMeters + + ", SamplingStartMeters=" + mSamplingStartMeters + + ", Magnitude=" + Arrays.toString(mMagnitude) + + '}'; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeDouble(mSamplingWidthMeters); + dest.writeDouble(mSamplingStartMeters); + dest.writeInt(mFrequencyOffsetMetersPerSecond); + dest.writeInt(mMagnitude.length); + dest.writeIntArray(mMagnitude); + } + + /** + * Returns true if this {@link CorrelationVector} is equivalent to the given object. + * Returns false otherwise. + */ + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof CorrelationVector)) { + return false; + } + CorrelationVector c = (CorrelationVector) object; + return Arrays.equals(mMagnitude, c.getMagnitude()) + && Double.compare(mSamplingWidthMeters, c.getSamplingWidthMeters()) == 0 + && Double.compare(mSamplingStartMeters, c.getSamplingStartMeters()) == 0 + && Integer.compare(mFrequencyOffsetMetersPerSecond, + c.getFrequencyOffsetMetersPerSecond()) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(mSamplingWidthMeters, mSamplingStartMeters, + mFrequencyOffsetMetersPerSecond, Arrays.hashCode(mMagnitude)); + } + + /** + * Builder class for CorrelationVector. + */ + public static final class Builder { + + private double mSamplingWidthMeters; + private double mSamplingStartMeters; + private int mFrequencyOffsetMetersPerSecond; + @NonNull private int[] mMagnitude; + + /** Sets the space between correlation samples in meters. */ + @NonNull + public Builder setSamplingWidthMeters( + @FloatRange(from = 0.0f, fromInclusive = false) double samplingWidthMeters) { + mSamplingWidthMeters = samplingWidthMeters; + return this; + } + + /** Sets the offset of the first sampling bin in meters. */ + @NonNull + public Builder setSamplingStartMeters(@FloatRange(from = 0.0f) double samplingStartMeters) { + mSamplingStartMeters = samplingStartMeters; + return this; + } + + /** Sets the frequency offset from reported pseudorange rate for this CorrelationVector */ + @NonNull + public Builder setFrequencyOffsetMetersPerSecond( + @IntRange(from = 0) int frequencyOffsetMetersPerSecond) { + mFrequencyOffsetMetersPerSecond = frequencyOffsetMetersPerSecond; + return this; + } + + /** Sets the data array representing normalized correlation magnitude values. */ + @NonNull + public Builder setMagnitude(@NonNull int[] magnitude) { + mMagnitude = magnitude; + return this; + } + + /** + * Build CorrelationVector object. + * + * @return instance of CorrelationVector + */ + @NonNull + public CorrelationVector build() { + return new CorrelationVector(this); + } + } +} diff --git a/location/java/android/location/GnssCapabilities.java b/location/java/android/location/GnssCapabilities.java index b650a9fd0416d..a5e28158ab788 100644 --- a/location/java/android/location/GnssCapabilities.java +++ b/location/java/android/location/GnssCapabilities.java @@ -58,6 +58,8 @@ public final class GnssCapabilities implements Parcelable { /** @hide */ public static final int TOP_HAL_CAPABILITY_ANTENNA_INFO = 2048; /** @hide */ + public static final int TOP_HAL_CAPABILITY_CORRELATION_VECTOR = 4096; + /** @hide */ public static final int TOP_HAL_CAPABILITY_SATELLITE_PVT = 8192; /** @hide */ @@ -67,7 +69,8 @@ public final class GnssCapabilities implements Parcelable { TOP_HAL_CAPABILITY_MEASUREMENTS, TOP_HAL_CAPABILITY_NAV_MESSAGES, TOP_HAL_CAPABILITY_LOW_POWER_MODE, TOP_HAL_CAPABILITY_SATELLITE_BLOCKLIST, TOP_HAL_CAPABILITY_MEASUREMENT_CORRECTIONS, TOP_HAL_CAPABILITY_ANTENNA_INFO, - TOP_HAL_CAPABILITY_SATELLITE_PVT}) + TOP_HAL_CAPABILITY_CORRELATION_VECTOR, TOP_HAL_CAPABILITY_SATELLITE_PVT}) + @Retention(RetentionPolicy.SOURCE) public @interface TopHalCapabilityFlags {} @@ -336,6 +339,17 @@ public final class GnssCapabilities implements Parcelable { return (mTopFlags & TOP_HAL_CAPABILITY_ANTENNA_INFO) != 0; } + /** + * Returns {@code true} if GNSS chipset supports correlation vectors as part of measurements + * outputs, {@code false} otherwise. + * + * @hide + */ + @SystemApi + public boolean hasMeasurementCorrelationVectors() { + return (mTopFlags & TOP_HAL_CAPABILITY_CORRELATION_VECTOR) != 0; + } + /** * Returns {@code true} if GNSS chipset supports line-of-sight satellite identification * measurement corrections, {@code false} otherwise. @@ -533,6 +547,9 @@ public final class GnssCapabilities implements Parcelable { if (hasAntennaInfo()) { builder.append("ANTENNA_INFO "); } + if (hasMeasurementCorrelationVectors()) { + builder.append("MEASUREMENT_CORRELATION_VECTORS "); + } if (hasMeasurementCorrectionsLosSats()) { builder.append("LOS_SATS "); } @@ -719,6 +736,17 @@ public final class GnssCapabilities implements Parcelable { return this; } + /** + * Sets correlation vector capability. + * + * @hide + */ + @SystemApi + public @NonNull Builder setHasMeasurementCorrelationVectors(boolean capable) { + mTopFlags = setFlag(mTopFlags, TOP_HAL_CAPABILITY_CORRELATION_VECTOR, capable); + return this; + } + /** * Sets measurement corrections line-of-sight satellites capabilitity. * diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java index 5509a6c656148..c3615fed3a0e7 100644 --- a/location/java/android/location/GnssMeasurement.java +++ b/location/java/android/location/GnssMeasurement.java @@ -38,6 +38,9 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; /** * A class representing a GNSS satellite measurement, containing raw and computed information. @@ -70,6 +73,7 @@ public final class GnssMeasurement implements Parcelable { private double mSatelliteInterSignalBiasNanos; private double mSatelliteInterSignalBiasUncertaintyNanos; @Nullable private SatellitePvt mSatellitePvt; + @Nullable private Collection mReadOnlyCorrelationVectors; // The following enumerations must be in sync with the values declared in GNSS HAL. @@ -77,6 +81,7 @@ public final class GnssMeasurement implements Parcelable { private static final int HAS_CODE_TYPE = (1 << 14); private static final int HAS_BASEBAND_CN0 = (1 << 15); private static final int HAS_SATELLITE_PVT = (1 << 20); + private static final int HAS_CORRELATION_VECTOR = (1 << 21); /** * The status of the multipath indicator. @@ -279,6 +284,7 @@ public final class GnssMeasurement implements Parcelable { mSatelliteInterSignalBiasUncertaintyNanos = measurement.mSatelliteInterSignalBiasUncertaintyNanos; mSatellitePvt = measurement.mSatellitePvt; + mReadOnlyCorrelationVectors = measurement.mReadOnlyCorrelationVectors; } /** @@ -1712,6 +1718,7 @@ public final class GnssMeasurement implements Parcelable { * *

The value is only available if {@link #hasSatellitePvt()} is * {@code true}. + * * @hide */ @Nullable @@ -1745,6 +1752,58 @@ public final class GnssMeasurement implements Parcelable { resetFlag(HAS_SATELLITE_PVT); } + /** + * Returns {@code true} if {@link #getCorrelationVectors()} is available, + * {@code false} otherwise. + * + * @hide + */ + @SystemApi + public boolean hasCorrelationVectors() { + return isFlagSet(HAS_CORRELATION_VECTOR); + } + + /** + * Gets read-only collection of CorrelationVector with each CorrelationVector corresponding to a + * frequency offset. + * + *

To represent correlation values over a 2D spaces (delay and frequency), a + * CorrelationVector is required per frequency offset, and each CorrelationVector contains + * correlation values at equally spaced spatial offsets. + * + * @hide + */ + @Nullable + @SystemApi + public Collection getCorrelationVectors() { + return mReadOnlyCorrelationVectors; + } + + /** + * Sets the CorrelationVectors. + * + * @hide + */ + @TestApi + public void setCorrelationVectors(@Nullable Collection correlationVectors) { + if (correlationVectors == null || correlationVectors.isEmpty()) { + resetCorrelationVectors(); + } else { + setFlag(HAS_CORRELATION_VECTOR); + mReadOnlyCorrelationVectors = Collections.unmodifiableCollection(correlationVectors); + } + } + + /** + * Resets the CorrelationVectors. + * + * @hide + */ + @TestApi + public void resetCorrelationVectors() { + resetFlag(HAS_CORRELATION_VECTOR); + mReadOnlyCorrelationVectors = null; + } public static final @NonNull Creator CREATOR = new Creator() { @Override @@ -1781,6 +1840,15 @@ public final class GnssMeasurement implements Parcelable { ClassLoader classLoader = getClass().getClassLoader(); gnssMeasurement.mSatellitePvt = parcel.readParcelable(classLoader); } + if (gnssMeasurement.hasCorrelationVectors()) { + CorrelationVector[] correlationVectorsArray = + new CorrelationVector[parcel.readInt()]; + parcel.readTypedArray(correlationVectorsArray, CorrelationVector.CREATOR); + Collection corrVecCollection = + Arrays.asList(correlationVectorsArray); + gnssMeasurement.mReadOnlyCorrelationVectors = + Collections.unmodifiableCollection(corrVecCollection); + } return gnssMeasurement; } @@ -1821,6 +1889,13 @@ public final class GnssMeasurement implements Parcelable { if (hasSatellitePvt()) { parcel.writeParcelable(mSatellitePvt, flags); } + if (hasCorrelationVectors()) { + int correlationVectorCount = mReadOnlyCorrelationVectors.size(); + CorrelationVector[] correlationVectorArray = + mReadOnlyCorrelationVectors.toArray(new CorrelationVector[correlationVectorCount]); + parcel.writeInt(correlationVectorArray.length); + parcel.writeTypedArray(correlationVectorArray, flags); + } } @Override @@ -1928,6 +2003,13 @@ public final class GnssMeasurement implements Parcelable { builder.append(mSatellitePvt.toString()); } + if (hasCorrelationVectors()) { + for (CorrelationVector correlationVector : mReadOnlyCorrelationVectors) { + builder.append(correlationVector.toString()); + builder.append("\n"); + } + } + return builder.toString(); } @@ -1958,6 +2040,7 @@ public final class GnssMeasurement implements Parcelable { resetSatelliteInterSignalBiasNanos(); resetSatelliteInterSignalBiasUncertaintyNanos(); resetSatellitePvt(); + resetCorrelationVectors(); } private void setFlag(int flag) { diff --git a/location/java/android/location/GnssMeasurementRequest.java b/location/java/android/location/GnssMeasurementRequest.java index 613f5918b7085..f509252e7542e 100644 --- a/location/java/android/location/GnssMeasurementRequest.java +++ b/location/java/android/location/GnssMeasurementRequest.java @@ -17,20 +17,38 @@ package android.location; import android.annotation.NonNull; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + /** * This class contains extra parameters to pass in a GNSS measurement request. */ public final class GnssMeasurementRequest implements Parcelable { + private final boolean mCorrelationVectorOutputsEnabled; private final boolean mFullTracking; /** * Creates a {@link GnssMeasurementRequest} with a full list of parameters. */ - private GnssMeasurementRequest(boolean fullTracking) { + private GnssMeasurementRequest(boolean fullTracking, boolean correlationVectorOutputsEnabled) { mFullTracking = fullTracking; + mCorrelationVectorOutputsEnabled = correlationVectorOutputsEnabled; + } + + /** + * Represents whether to enable correlation vector outputs. + * + *

If true, enable correlation vectors as part of the raw GNSS measurements outputs. + * If false, disable correlation vectors. + * + * @hide + */ + @SystemApi + public boolean isCorrelationVectorOutputsEnabled() { + return mCorrelationVectorOutputsEnabled; } /** @@ -56,7 +74,7 @@ public final class GnssMeasurementRequest implements Parcelable { @Override @NonNull public GnssMeasurementRequest createFromParcel(@NonNull Parcel parcel) { - return new GnssMeasurementRequest(parcel.readBoolean()); + return new GnssMeasurementRequest(parcel.readBoolean(), parcel.readBoolean()); } @Override @@ -68,6 +86,7 @@ public final class GnssMeasurementRequest implements Parcelable { @Override public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeBoolean(mFullTracking); + parcel.writeBoolean(mCorrelationVectorOutputsEnabled); } @NonNull @@ -78,6 +97,9 @@ public final class GnssMeasurementRequest implements Parcelable { if (mFullTracking) { s.append("FullTracking"); } + if (mCorrelationVectorOutputsEnabled) { + s.append(", CorrelationVectorOutPuts"); + } s.append(']'); return s.toString(); } @@ -90,13 +112,15 @@ public final class GnssMeasurementRequest implements Parcelable { GnssMeasurementRequest other = (GnssMeasurementRequest) obj; if (mFullTracking != other.mFullTracking) return false; - + if (mCorrelationVectorOutputsEnabled != other.mCorrelationVectorOutputsEnabled) { + return false; + } return true; } @Override public int hashCode() { - return mFullTracking ? 1 : 0; + return Objects.hash(mFullTracking, mCorrelationVectorOutputsEnabled); } @Override @@ -106,6 +130,7 @@ public final class GnssMeasurementRequest implements Parcelable { /** Builder for {@link GnssMeasurementRequest} */ public static final class Builder { + private boolean mCorrelationVectorOutputsEnabled; private boolean mFullTracking; /** @@ -118,9 +143,24 @@ public final class GnssMeasurementRequest implements Parcelable { * Constructs a {@link Builder} instance by copying a {@link GnssMeasurementRequest}. */ public Builder(@NonNull GnssMeasurementRequest request) { + mCorrelationVectorOutputsEnabled = request.isCorrelationVectorOutputsEnabled(); mFullTracking = request.isFullTracking(); } + /** + * Set the value of whether to enable correlation vector outputs, which is false by default. + * + *

If true, enable correlation vectors as part of the raw GNSS measurements outputs. + * If false, disable correlation vectors. + * + * @hide + */ + @SystemApi + @NonNull public Builder setCorrelationVectorOutputsEnabled(boolean value) { + mCorrelationVectorOutputsEnabled = value; + return this; + } + /** * Set the value of whether to enable full GNSS tracking, which is false by default. * @@ -146,7 +186,7 @@ public final class GnssMeasurementRequest implements Parcelable { /** Builds a {@link GnssMeasurementRequest} instance as specified by this builder. */ @NonNull public GnssMeasurementRequest build() { - return new GnssMeasurementRequest(mFullTracking); + return new GnssMeasurementRequest(mFullTracking, mCorrelationVectorOutputsEnabled); } } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 2dc9eb44236f5..0ce1ad0d93807 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -3171,7 +3171,9 @@ public class LocationManager { for (GnssMeasurementRequest request : requests) { if (request.isFullTracking()) { builder.setFullTracking(true); - break; + } + if (request.isCorrelationVectorOutputsEnabled()) { + builder.setCorrelationVectorOutputsEnabled(true); } } diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 92957aaf29768..b6695c20bd975 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -193,7 +193,9 @@ public class GnssManagerService { IGnssMeasurementsListener listener, String packageName, @Nullable String attributionTag) { mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION, null); - + if (request.isCorrelationVectorOutputsEnabled()) { + mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null); + } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); mGnssMeasurementsProvider.addListener(request, identity, listener); } diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java index b623e279d9ae5..305bc9b69e394 100644 --- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java @@ -118,7 +118,8 @@ public final class GnssMeasurementsProvider extends @Override protected boolean registerWithService(GnssMeasurementRequest request, Collection registrations) { - if (mGnssNative.startMeasurementCollection(request.isFullTracking())) { + if (mGnssNative.startMeasurementCollection(request.isFullTracking(), + request.isCorrelationVectorOutputsEnabled())) { if (D) { Log.d(TAG, "starting gnss measurements (" + request + ")"); } @@ -160,18 +161,26 @@ public final class GnssMeasurementsProvider extends protected GnssMeasurementRequest mergeRegistrations( Collection registrations) { boolean fullTracking = false; + boolean enableCorrVecOutputs = false; + if (mSettingsHelper.isGnssMeasurementsFullTrackingEnabled()) { fullTracking = true; - } else { - for (GnssListenerRegistration registration : registrations) { - if (registration.getRequest().isFullTracking()) { - fullTracking = true; - break; - } + } + + for (GnssListenerRegistration registration : registrations) { + GnssMeasurementRequest request = registration.getRequest(); + if (request.isFullTracking()) { + fullTracking = true; + } + if (request.isCorrelationVectorOutputsEnabled()) { + enableCorrVecOutputs = true; } } - return new GnssMeasurementRequest.Builder().setFullTracking(fullTracking).build(); + return new GnssMeasurementRequest.Builder() + .setFullTracking(fullTracking) + .setCorrelationVectorOutputsEnabled(enableCorrVecOutputs) + .build(); } @Override diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java index 402e84b959c6a..7e2f089d32c90 100644 --- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java @@ -733,9 +733,10 @@ public class GnssNative { /** * Starts measurement collection. */ - public boolean startMeasurementCollection(boolean enableFullTracking) { + public boolean startMeasurementCollection(boolean enableFullTracking, + boolean enableCorrVecOutputs) { Preconditions.checkState(mRegistered); - return mGnssHal.startMeasurementCollection(enableFullTracking); + return mGnssHal.startMeasurementCollection(enableFullTracking, enableCorrVecOutputs); } /** @@ -1274,8 +1275,9 @@ public class GnssNative { return native_is_measurement_supported(); } - protected boolean startMeasurementCollection(boolean enableFullTracking) { - return native_start_measurement_collection(enableFullTracking); + protected boolean startMeasurementCollection(boolean enableFullTracking, + boolean enableCorrVecOutputs) { + return native_start_measurement_collection(enableFullTracking, enableCorrVecOutputs); } protected boolean stopMeasurementCollection() { @@ -1438,7 +1440,8 @@ public class GnssNative { private static native boolean native_is_measurement_supported(); - private static native boolean native_start_measurement_collection(boolean enableFullTracking); + private static native boolean native_start_measurement_collection(boolean enableFullTracking, + boolean enableCorrVecOutputs); private static native boolean native_stop_measurement_collection(); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java index 675274bf82c4e..69fe140a7863b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/gnss/hal/FakeGnssHal.java @@ -233,6 +233,7 @@ public final class FakeGnssHal extends GnssNative.GnssHal { private boolean mAntennaInfoListeningStarted = false; private boolean mMeasurementCollectionStarted = false; private boolean mMeasurementCollectionFullTracking = false; + private boolean mMeasurementCollectionCorrVecOutputsEnabled = false; private GnssHalPositionMode mPositionMode = new GnssHalPositionMode(); private GnssHalBatchingMode mBatchingMode = new GnssHalBatchingMode(); private final ArrayList mBatchedLocations = new ArrayList<>(); @@ -521,9 +522,11 @@ public final class FakeGnssHal extends GnssNative.GnssHal { } @Override - protected boolean startMeasurementCollection(boolean enableFullTracking) { + protected boolean startMeasurementCollection(boolean enableFullTracking, + boolean enableCorrVecOutputs) { mState.mMeasurementCollectionStarted = true; mState.mMeasurementCollectionFullTracking = enableFullTracking; + mState.mMeasurementCollectionCorrVecOutputsEnabled = enableCorrVecOutputs; return true; } @@ -531,6 +534,7 @@ public final class FakeGnssHal extends GnssNative.GnssHal { protected boolean stopMeasurementCollection() { mState.mMeasurementCollectionStarted = false; mState.mMeasurementCollectionFullTracking = false; + mState.mMeasurementCollectionCorrVecOutputsEnabled = false; return true; }