summaryrefslogtreecommitdiff
path: root/location/java
diff options
context:
space:
mode:
author Shinru Han <shinruhan@google.com> 2020-12-21 21:11:33 +0800
committer Shinru Han <shinruhan@google.com> 2021-01-14 15:59:00 +0800
commitdaffd228199ed35d890dae22b440ea1c66eadf4e (patch)
treea8b0b1a1eaa2d1b69e99a8d07de0a652006a4735 /location/java
parente61c0ceb8d0ade26d15e41e4c3ec42694ca64fa2 (diff)
Add CorrelationVector AIDL (framework/base)
Test: on cuttlefish Bug: 171516016 Change-Id: Ib214c52701e0d0139083e8e3bb3c5862d29da48a
Diffstat (limited to 'location/java')
-rw-r--r--location/java/android/location/CorrelationVector.java228
-rw-r--r--location/java/android/location/GnssCapabilities.java30
-rw-r--r--location/java/android/location/GnssMeasurement.java83
-rw-r--r--location/java/android/location/GnssMeasurementRequest.java50
-rw-r--r--location/java/android/location/LocationManager.java4
5 files changed, 388 insertions, 7 deletions
diff --git a/location/java/android/location/CorrelationVector.java b/location/java/android/location/CorrelationVector.java
new file mode 100644
index 000000000000..eca35dd69362
--- /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.
+ *
+ * <p>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.
+ *
+ * <p>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<CorrelationVector> CREATOR =
+ new Parcelable.Creator<CorrelationVector>() {
+ @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 b650a9fd0416..a5e28158ab78 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 {}
@@ -337,6 +340,17 @@ public final class GnssCapabilities implements Parcelable {
}
/**
+ * 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 ");
}
@@ -720,6 +737,17 @@ public final class GnssCapabilities implements Parcelable {
}
/**
+ * 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.
*
* @hide
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 5509a6c65614..c3615fed3a0e 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<CorrelationVector> 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 {
*
* <p>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.
+ *
+ * <p>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<CorrelationVector> getCorrelationVectors() {
+ return mReadOnlyCorrelationVectors;
+ }
+
+ /**
+ * Sets the CorrelationVectors.
+ *
+ * @hide
+ */
+ @TestApi
+ public void setCorrelationVectors(@Nullable Collection<CorrelationVector> 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<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
@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<CorrelationVector> 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 613f5918b708..f509252e7542 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.
+ *
+ * <p>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,10 +143,25 @@ 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.
+ *
+ * <p>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.
*
* <p>If true, GNSS chipset switches off duty cycling. In such a mode, no clock
@@ -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 2dc9eb44236f..0ce1ad0d9380 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);
}
}