summaryrefslogtreecommitdiff
path: root/location/java/android
diff options
context:
space:
mode:
author Yu-Han Yang <yuhany@google.com> 2021-12-29 15:58:42 -0800
committer Yu-Han Yang <yuhany@google.com> 2022-01-14 09:54:38 -0800
commitaf90af79315d30ce62131bc43a828b57bade78ba (patch)
tree395ec1472ab3f7bdb384e61b2ef49c1e85c78349 /location/java/android
parentb559ac4e9f3a52f07c9977fb27e2087141780f74 (diff)
Add GnssAutomaticGainControl to GnssMeasurementsEvent (frameworks/base)
AgcLevelDb has been a subfield of GnssMeasurement. However, GnssMeasurement is only reported by the chipset when there is GNSS signal. For example, in deep indoor, or when there is strong jamming signal, no GnssMeasurement can be reported, and thus no AGC value can be reported. To resolve that, we are adding this GnssAgc to GnssMeasurementsEvent directly, so that the client can get AGC values even without GNSS signal (i.e., without GnssMeasurement). Bug: 206670536 Test: atest GnssAutomaticGainControlTest atest GnssMeasurementsEventTest Change-Id: I97c7ec98b6e8cc977c6e879b52a8cf75c355ae33
Diffstat (limited to 'location/java/android')
-rw-r--r--location/java/android/location/GnssAutomaticGainControl.aidl19
-rw-r--r--location/java/android/location/GnssAutomaticGainControl.java215
-rw-r--r--location/java/android/location/GnssMeasurement.java8
-rw-r--r--location/java/android/location/GnssMeasurementsEvent.java161
4 files changed, 362 insertions, 41 deletions
diff --git a/location/java/android/location/GnssAutomaticGainControl.aidl b/location/java/android/location/GnssAutomaticGainControl.aidl
new file mode 100644
index 000000000000..8298cb711064
--- /dev/null
+++ b/location/java/android/location/GnssAutomaticGainControl.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable GnssAutomaticGainControl;
diff --git a/location/java/android/location/GnssAutomaticGainControl.java b/location/java/android/location/GnssAutomaticGainControl.java
new file mode 100644
index 000000000000..e4f7304a8c9d
--- /dev/null
+++ b/location/java/android/location/GnssAutomaticGainControl.java
@@ -0,0 +1,215 @@
+/*
+ * 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 android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * A class that contains GNSS Automatic Gain Control (AGC) information.
+ *
+ * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal. The AGC
+ * level may be used to indicate potential interference. Higher gain (and/or lower input power)
+ * shall be output as a positive number. Hence in cases of strong jamming, in the band of this
+ * signal, this value will go more negative. This value must be consistent given the same level
+ * of the incoming signal power.
+ *
+ * <p> Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
+ * components) may also affect the typical output of this value on any given hardware design
+ * in an open sky test - the important aspect of this output is that changes in this value are
+ * indicative of changes on input signal power in the frequency band for this measurement.
+ */
+public final class GnssAutomaticGainControl implements Parcelable {
+ private final double mLevelDb;
+ private final int mConstellationType;
+ private final long mCarrierFrequencyHz;
+
+ /**
+ * Creates a {@link GnssAutomaticGainControl} with a full list of parameters.
+ */
+ private GnssAutomaticGainControl(double levelDb, int constellationType,
+ long carrierFrequencyHz) {
+ mLevelDb = levelDb;
+ mConstellationType = constellationType;
+ mCarrierFrequencyHz = carrierFrequencyHz;
+ }
+
+ /**
+ * Gets the Automatic Gain Control level in dB.
+ */
+ @FloatRange(from = -10000, to = 10000)
+ public double getLevelDb() {
+ return mLevelDb;
+ }
+
+ /**
+ * Gets the constellation type.
+ *
+ * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+ * {@link GnssStatus}.
+ */
+ @GnssStatus.ConstellationType
+ public int getConstellationType() {
+ return mConstellationType;
+ }
+
+ /**
+ * Gets the carrier frequency of the tracked signal.
+ *
+ * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
+ * L5 = 1176.45 MHz, varying GLO channels, etc.
+ *
+ * @return the carrier frequency of the signal tracked in Hz.
+ */
+ @IntRange(from = 0)
+ public long getCarrierFrequencyHz() {
+ return mCarrierFrequencyHz;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flag) {
+ parcel.writeDouble(mLevelDb);
+ parcel.writeInt(mConstellationType);
+ parcel.writeLong(mCarrierFrequencyHz);
+ }
+
+ @NonNull
+ public static final Creator<GnssAutomaticGainControl> CREATOR =
+ new Creator<GnssAutomaticGainControl>() {
+ @Override
+ @NonNull
+ public GnssAutomaticGainControl createFromParcel(@NonNull Parcel parcel) {
+ return new GnssAutomaticGainControl(parcel.readDouble(), parcel.readInt(),
+ parcel.readLong());
+ }
+
+ @Override
+ public GnssAutomaticGainControl[] newArray(int i) {
+ return new GnssAutomaticGainControl[i];
+ }
+ };
+
+ @NonNull
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("GnssAutomaticGainControl[");
+ s.append("Level=").append(mLevelDb).append(" dB");
+ s.append(" Constellation=").append(
+ GnssStatus.constellationTypeToString(mConstellationType));
+ s.append(" CarrierFrequency=").append(mCarrierFrequencyHz).append(" Hz");
+ s.append(']');
+ return s.toString();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof GnssAutomaticGainControl)) {
+ return false;
+ }
+
+ GnssAutomaticGainControl other = (GnssAutomaticGainControl) obj;
+ if (Double.compare(mLevelDb, other.mLevelDb)
+ != 0) {
+ return false;
+ }
+ if (mConstellationType != other.mConstellationType) {
+ return false;
+ }
+ if (mCarrierFrequencyHz != other.mCarrierFrequencyHz) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mLevelDb, mConstellationType, mCarrierFrequencyHz);
+ }
+
+ /** Builder for {@link GnssAutomaticGainControl} */
+ public static final class Builder {
+ private double mLevelDb;
+ private int mConstellationType;
+ private long mCarrierFrequencyHz;
+
+ /**
+ * Constructs a {@link GnssAutomaticGainControl.Builder} instance.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Constructs a {@link GnssAutomaticGainControl.Builder} instance by copying a
+ * {@link GnssAutomaticGainControl}.
+ */
+ public Builder(@NonNull GnssAutomaticGainControl agc) {
+ mLevelDb = agc.getLevelDb();
+ mConstellationType = agc.getConstellationType();
+ mCarrierFrequencyHz = agc.getCarrierFrequencyHz();
+ }
+
+ /**
+ * Sets the Automatic Gain Control level in dB.
+ */
+ @NonNull
+ public Builder setLevelDb(@FloatRange(from = -10000, to = 10000) double levelDb) {
+ Preconditions.checkArgument(levelDb >= -10000 && levelDb <= 10000);
+ mLevelDb = levelDb;
+ return this;
+ }
+
+ /**
+ * Sets the constellation type.
+ */
+ @NonNull
+ public Builder setConstellationType(@GnssStatus.ConstellationType int constellationType) {
+ mConstellationType = constellationType;
+ return this;
+ }
+
+ /**
+ * Sets the Carrier frequency in Hz.
+ */
+ @NonNull public Builder setCarrierFrequencyHz(@IntRange(from = 0) long carrierFrequencyHz) {
+ Preconditions.checkArgumentNonnegative(carrierFrequencyHz);
+ mCarrierFrequencyHz = carrierFrequencyHz;
+ return this;
+ }
+
+ /** Builds a {@link GnssAutomaticGainControl} instance as specified by this builder. */
+ @NonNull
+ public GnssAutomaticGainControl build() {
+ return new GnssAutomaticGainControl(mLevelDb, mConstellationType, mCarrierFrequencyHz);
+ }
+ }
+}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index ecdd4b616e0f..cdfa02c8b28f 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -1381,7 +1381,10 @@ public final class GnssMeasurement implements Parcelable {
/**
* Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
* {@code false} otherwise.
+ *
+ * @deprecated Use {@link GnssMeasurementsEvent#getGnssAutomaticGainControls()} instead.
*/
+ @Deprecated
public boolean hasAutomaticGainControlLevelDb() {
return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
}
@@ -1401,7 +1404,10 @@ public final class GnssMeasurement implements Parcelable {
* indicative of changes on input signal power in the frequency band for this measurement.
*
* <p> The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
+ *
+ * @deprecated Use {@link GnssMeasurementsEvent#getGnssAutomaticGainControls()} instead.
*/
+ @Deprecated
public double getAutomaticGainControlLevelDb() {
return mAutomaticGainControlLevelInDb;
}
@@ -1409,7 +1415,9 @@ public final class GnssMeasurement implements Parcelable {
/**
* Sets the Automatic Gain Control level in dB.
* @hide
+ * @deprecated Use {@link GnssMeasurementsEvent.Builder#setGnssAutomaticGainControls()} instead.
*/
+ @Deprecated
@TestApi
public void setAutomaticGainControlLevelInDb(double agcLevelDb) {
setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index a07a64acb6e6..075ddebc859f 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -18,16 +18,19 @@ package android.location;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.TestApi;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.security.InvalidParameterException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
/**
* A class implementing a container for data associated with a measurement event.
@@ -35,7 +38,8 @@ import java.util.Collections;
*/
public final class GnssMeasurementsEvent implements Parcelable {
private final GnssClock mClock;
- private final Collection<GnssMeasurement> mReadOnlyMeasurements;
+ private final List<GnssMeasurement> mMeasurements;
+ private final List<GnssAutomaticGainControl> mGnssAgcs;
/**
* Used for receiving GNSS satellite measurements from the GNSS engine.
@@ -116,20 +120,13 @@ public final class GnssMeasurementsEvent implements Parcelable {
}
/**
- * @hide
+ * Create a {@link GnssMeasurementsEvent} instance with a full list of parameters.
*/
- @TestApi
- public GnssMeasurementsEvent(GnssClock clock, GnssMeasurement[] measurements) {
- if (clock == null) {
- throw new InvalidParameterException("Parameter 'clock' must not be null.");
- }
- if (measurements == null || measurements.length == 0) {
- mReadOnlyMeasurements = Collections.emptyList();
- } else {
- Collection<GnssMeasurement> measurementCollection = Arrays.asList(measurements);
- mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
- }
-
+ private GnssMeasurementsEvent(@NonNull GnssClock clock,
+ @NonNull List<GnssMeasurement> measurements,
+ @NonNull List<GnssAutomaticGainControl> agcs) {
+ mMeasurements = measurements;
+ mGnssAgcs = agcs;
mClock = clock;
}
@@ -143,26 +140,31 @@ public final class GnssMeasurementsEvent implements Parcelable {
}
/**
- * Gets a read-only collection of measurements associated with the current event.
+ * Gets the collection of measurements associated with the current event.
*/
@NonNull
public Collection<GnssMeasurement> getMeasurements() {
- return mReadOnlyMeasurements;
+ return mMeasurements;
+ }
+
+ /**
+ * Gets the collection of {@link GnssAutomaticGainControl} associated with the
+ * current event.
+ */
+ @NonNull
+ public Collection<GnssAutomaticGainControl> getGnssAutomaticGainControls() {
+ return mGnssAgcs;
}
public static final @android.annotation.NonNull Creator<GnssMeasurementsEvent> CREATOR =
new Creator<GnssMeasurementsEvent>() {
@Override
public GnssMeasurementsEvent createFromParcel(Parcel in) {
- ClassLoader classLoader = getClass().getClassLoader();
-
- GnssClock clock = in.readParcelable(classLoader);
-
- int measurementsLength = in.readInt();
- GnssMeasurement[] measurementsArray = new GnssMeasurement[measurementsLength];
- in.readTypedArray(measurementsArray, GnssMeasurement.CREATOR);
-
- return new GnssMeasurementsEvent(clock, measurementsArray);
+ GnssClock clock = in.readParcelable(getClass().getClassLoader());
+ List<GnssMeasurement> measurements = in.createTypedArrayList(GnssMeasurement.CREATOR);
+ List<GnssAutomaticGainControl> agcs = in.createTypedArrayList(
+ GnssAutomaticGainControl.CREATOR);
+ return new GnssMeasurementsEvent(clock, measurements, agcs);
}
@Override
@@ -179,28 +181,105 @@ public final class GnssMeasurementsEvent implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeParcelable(mClock, flags);
-
- int measurementsCount = mReadOnlyMeasurements.size();
- GnssMeasurement[] measurementsArray =
- mReadOnlyMeasurements.toArray(new GnssMeasurement[measurementsCount]);
- parcel.writeInt(measurementsArray.length);
- parcel.writeTypedArray(measurementsArray, flags);
+ parcel.writeTypedList(mMeasurements);
+ parcel.writeTypedList(mGnssAgcs);
}
@Override
public String toString() {
- StringBuilder builder = new StringBuilder("[ GnssMeasurementsEvent:\n\n");
+ StringBuilder builder = new StringBuilder("GnssMeasurementsEvent[");
+ builder.append(mClock);
+ builder.append(' ').append(mMeasurements.toString());
+ builder.append(' ').append(mGnssAgcs.toString());
+ builder.append("]");
+ return builder.toString();
+ }
- builder.append(mClock.toString());
- builder.append("\n");
+ /** Builder for {@link GnssMeasurementsEvent} */
+ public static final class Builder {
+ private GnssClock mClock;
+ private List<GnssMeasurement> mMeasurements;
+ private List<GnssAutomaticGainControl> mGnssAgcs;
- for (GnssMeasurement measurement : mReadOnlyMeasurements) {
- builder.append(measurement.toString());
- builder.append("\n");
+ /**
+ * Constructs a {@link GnssMeasurementsEvent.Builder} instance.
+ */
+ public Builder() {
+ mClock = new GnssClock();
+ mMeasurements = new ArrayList<>();
+ mGnssAgcs = new ArrayList<>();
}
- builder.append("]");
+ /**
+ * Constructs a {@link GnssMeasurementsEvent.Builder} instance by copying a
+ * {@link GnssMeasurementsEvent}.
+ */
+ public Builder(@NonNull GnssMeasurementsEvent event) {
+ mClock = event.getClock();
+ mMeasurements = (List<GnssMeasurement>) event.getMeasurements();
+ mGnssAgcs = (List<GnssAutomaticGainControl>) event.getGnssAutomaticGainControls();
+ }
- return builder.toString();
+ /**
+ * Sets the {@link GnssClock}.
+ */
+ @NonNull
+ public Builder setClock(@NonNull GnssClock clock) {
+ Preconditions.checkNotNull(clock);
+ mClock = clock;
+ return this;
+ }
+
+ /**
+ * Sets the collection of {@link GnssMeasurement}.
+ *
+ * This API exists for JNI since it is easier for JNI to work with an array than a
+ * collection.
+ * @hide
+ */
+ @NonNull
+ public Builder setMeasurements(@Nullable GnssMeasurement... measurements) {
+ mMeasurements = measurements == null ? Collections.emptyList() : Arrays.asList(
+ measurements);
+ return this;
+ }
+
+ /**
+ * Sets the collection of {@link GnssMeasurement}.
+ */
+ @NonNull
+ public Builder setMeasurements(@NonNull Collection<GnssMeasurement> measurements) {
+ mMeasurements = new ArrayList<>(measurements);
+ return this;
+ }
+
+ /**
+ * Sets the collection of {@link GnssAutomaticGainControl}.
+ *
+ * This API exists for JNI since it is easier for JNI to work with an array than a
+ * collection.
+ * @hide
+ */
+ @NonNull
+ public Builder setGnssAutomaticGainControls(@Nullable GnssAutomaticGainControl... agcs) {
+ mGnssAgcs = agcs == null ? Collections.emptyList() : Arrays.asList(agcs);
+ return this;
+ }
+
+ /**
+ * Sets the collection of {@link GnssAutomaticGainControl}.
+ */
+ @NonNull
+ public Builder setGnssAutomaticGainControls(
+ @NonNull Collection<GnssAutomaticGainControl> agcs) {
+ mGnssAgcs = new ArrayList<>(agcs);
+ return this;
+ }
+
+ /** Builds a {@link GnssMeasurementsEvent} instance as specified by this builder. */
+ @NonNull
+ public GnssMeasurementsEvent build() {
+ return new GnssMeasurementsEvent(mClock, mMeasurements, mGnssAgcs);
+ }
}
}