summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Soonil Nagarkar <sooniln@google.com> 2021-01-05 13:12:14 -0800
committer Soonil Nagarkar <sooniln@google.com> 2021-01-06 11:29:47 -0800
commit7a46eda83ee043d516467182bf49a3d55106e58f (patch)
tree40a6332cc9fd8e956d8b6fea912b253f5ef95030
parentba3c0ce56bc23f47dbeb60796a156ffa45addd6a (diff)
Add GNSS capabilities and antenna broadcasts
Provide a system wide broadcast when GNSS capabilities change and when GNSS antenna infos change so that clients have some way to detect this. Antenna info was previously implemented as a listener, but after evaluating the information, it is not protected, changes infrequently with device configuration (if a foldable is unfolded for instance), and clients need to see every change (not the previous model of only sending changes while the client is foreground and GPS is enabled). As a corollary, deprecate GNSS status events. These status messages contain duplicate, inconsistent information, and do not scale for new APIs. In addition, we don't have any clients that use these status messages for any real purpose. Bug: 153129152 Test: atest CtsLocationFineTestCases Change-Id: Icc5bed8e37c7e8f168de57d2a019e94d96c0d3f2
-rw-r--r--core/api/current.txt35
-rw-r--r--location/java/android/location/GnssAntennaInfo.java223
-rw-r--r--location/java/android/location/GnssMeasurementsEvent.java22
-rw-r--r--location/java/android/location/GnssNavigationMessage.java16
-rw-r--r--location/java/android/location/GnssStatus.java20
-rw-r--r--location/java/android/location/IGnssAntennaInfoListener.aidl26
-rw-r--r--location/java/android/location/ILocationManager.aidl7
-rw-r--r--location/java/android/location/LocationManager.java108
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java16
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java101
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssGeofenceProxy.java5
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java19
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java1
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssManagerService.java139
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java15
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java26
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNmeaProvider.java5
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssStatusProvider.java5
-rw-r--r--services/core/java/com/android/server/location/gnss/hal/GnssNative.java12
19 files changed, 463 insertions, 338 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index ea00427fb64b..a565e7b8fedd 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -18940,7 +18940,9 @@ package android.location {
}
public static class GnssAntennaInfo.Builder {
- ctor public GnssAntennaInfo.Builder();
+ ctor @Deprecated public GnssAntennaInfo.Builder();
+ ctor public GnssAntennaInfo.Builder(double, @NonNull android.location.GnssAntennaInfo.PhaseCenterOffset);
+ ctor public GnssAntennaInfo.Builder(@NonNull android.location.GnssAntennaInfo);
method @NonNull public android.location.GnssAntennaInfo build();
method @NonNull public android.location.GnssAntennaInfo.Builder setCarrierFrequencyMHz(@FloatRange(from=0.0f) double);
method @NonNull public android.location.GnssAntennaInfo.Builder setPhaseCenterOffset(@NonNull android.location.GnssAntennaInfo.PhaseCenterOffset);
@@ -18948,8 +18950,8 @@ package android.location {
method @NonNull public android.location.GnssAntennaInfo.Builder setSignalGainCorrections(@Nullable android.location.GnssAntennaInfo.SphericalCorrections);
}
- public static interface GnssAntennaInfo.Listener {
- method public void onGnssAntennaInfoReceived(@NonNull java.util.List<android.location.GnssAntennaInfo>);
+ @Deprecated public static interface GnssAntennaInfo.Listener {
+ method @Deprecated public void onGnssAntennaInfoReceived(@NonNull java.util.List<android.location.GnssAntennaInfo>);
}
public static final class GnssAntennaInfo.PhaseCenterOffset implements android.os.Parcelable {
@@ -19122,11 +19124,11 @@ package android.location {
public abstract static class GnssMeasurementsEvent.Callback {
ctor public GnssMeasurementsEvent.Callback();
method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
- method public void onStatusChanged(int);
- field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
- field public static final int STATUS_NOT_ALLOWED = 3; // 0x3
- field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
- field public static final int STATUS_READY = 1; // 0x1
+ method @Deprecated public void onStatusChanged(int);
+ field @Deprecated public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field @Deprecated public static final int STATUS_NOT_ALLOWED = 3; // 0x3
+ field @Deprecated public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field @Deprecated public static final int STATUS_READY = 1; // 0x1
}
public final class GnssNavigationMessage implements android.os.Parcelable {
@@ -19162,10 +19164,10 @@ package android.location {
public abstract static class GnssNavigationMessage.Callback {
ctor public GnssNavigationMessage.Callback();
method public void onGnssNavigationMessageReceived(android.location.GnssNavigationMessage);
- method public void onStatusChanged(int);
- field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
- field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
- field public static final int STATUS_READY = 1; // 0x1
+ method @Deprecated public void onStatusChanged(int);
+ field @Deprecated public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field @Deprecated public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
+ field @Deprecated public static final int STATUS_READY = 1; // 0x1
}
public final class GnssStatus implements android.os.Parcelable {
@@ -19323,6 +19325,7 @@ package android.location {
method @Nullable public String getBestProvider(@NonNull android.location.Criteria, boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void getCurrentLocation(@NonNull String, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Location>);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void getCurrentLocation(@NonNull String, @NonNull android.location.LocationRequest, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Location>);
+ method @Nullable public java.util.List<android.location.GnssAntennaInfo> getGnssAntennaInfos();
method @NonNull public android.location.GnssCapabilities getGnssCapabilities();
method @Nullable public String getGnssHardwareModelName();
method public int getGnssYearOfHardware();
@@ -19335,7 +19338,7 @@ package android.location {
method public boolean hasProvider(@NonNull String);
method public boolean isLocationEnabled();
method public boolean isProviderEnabled(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerAntennaInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssAntennaInfo.Listener);
+ method @Deprecated public boolean registerAntennaInfoListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssAntennaInfo.Listener);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback, @Nullable android.os.Handler);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.location.GnssMeasurementsEvent.Callback);
@@ -19372,10 +19375,14 @@ package android.location {
method public void setTestProviderEnabled(@NonNull String, boolean);
method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location);
method @Deprecated public void setTestProviderStatus(@NonNull String, int, @Nullable android.os.Bundle, long);
- method public void unregisterAntennaInfoListener(@NonNull android.location.GnssAntennaInfo.Listener);
+ method @Deprecated public void unregisterAntennaInfoListener(@NonNull android.location.GnssAntennaInfo.Listener);
method public void unregisterGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
method public void unregisterGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
method public void unregisterGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
+ field public static final String ACTION_GNSS_ANTENNA_INFOS_CHANGED = "android.location.action.GNSS_ANTENNA_INFOS_CHANGED";
+ field public static final String ACTION_GNSS_CAPABILITIES_CHANGED = "android.location.action.GNSS_CAPABILITIES_CHANGED";
+ field public static final String EXTRA_GNSS_ANTENNA_INFOS = "android.location.extra.GNSS_ANTENNA_INFOS";
+ field public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES";
field public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED";
field public static final String EXTRA_PROVIDER_ENABLED = "android.location.extra.PROVIDER_ENABLED";
field public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME";
diff --git a/location/java/android/location/GnssAntennaInfo.java b/location/java/android/location/GnssAntennaInfo.java
index 23977f18f749..f1eb8fccdd3c 100644
--- a/location/java/android/location/GnssAntennaInfo.java
+++ b/location/java/android/location/GnssAntennaInfo.java
@@ -34,17 +34,19 @@ import java.util.Objects;
public final class GnssAntennaInfo implements Parcelable {
private final double mCarrierFrequencyMHz;
private final PhaseCenterOffset mPhaseCenterOffset;
- private final SphericalCorrections mPhaseCenterVariationCorrections;
- private final SphericalCorrections mSignalGainCorrections;
+ private final @Nullable SphericalCorrections mPhaseCenterVariationCorrections;
+ private final @Nullable SphericalCorrections mSignalGainCorrections;
/**
- * Used for receiving GNSS antenna info from the GNSS engine. You can implement this interface
- * and call {@link LocationManager#registerAntennaInfoListener};
+ * Used for receiving GNSS antenna info from the GNSS engine.
+ *
+ * @deprecated Prefer to use a broadcast receiver for
+ * {@link LocationManager#ACTION_GNSS_ANTENNA_INFOS_CHANGED}.
*/
+ @Deprecated
public interface Listener {
/**
- * Returns the latest GNSS antenna info. This event is triggered when a listener is
- * registered, and whenever the antenna info changes (due to a device configuration change).
+ * Invoked on a change to GNSS antenna info.
*/
void onGnssAntennaInfoReceived(@NonNull List<GnssAntennaInfo> gnssAntennaInfos);
}
@@ -172,6 +174,28 @@ public final class GnssAntennaInfo implements Parcelable {
+ ", OffsetZMm=" + mOffsetZMm + " +/-" + mOffsetZUncertaintyMm
+ '}';
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof PhaseCenterOffset)) {
+ return false;
+ }
+ PhaseCenterOffset that = (PhaseCenterOffset) o;
+ return Double.compare(that.mOffsetXMm, mOffsetXMm) == 0
+ && Double.compare(that.mOffsetXUncertaintyMm, mOffsetXUncertaintyMm) == 0
+ && Double.compare(that.mOffsetYMm, mOffsetYMm) == 0
+ && Double.compare(that.mOffsetYUncertaintyMm, mOffsetYUncertaintyMm) == 0
+ && Double.compare(that.mOffsetZMm, mOffsetZMm) == 0
+ && Double.compare(that.mOffsetZUncertaintyMm, mOffsetZUncertaintyMm) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mOffsetXMm, mOffsetYMm, mOffsetZMm);
+ }
}
/**
@@ -190,38 +214,34 @@ public final class GnssAntennaInfo implements Parcelable {
* i.e., deltaPhi = 180 / (number of columns - 1).
*/
public static final class SphericalCorrections implements Parcelable {
- private final double[][] mCorrections;
- private final double[][] mCorrectionUncertainties;
- private final double mDeltaTheta;
- private final double mDeltaPhi;
+
private final int mNumRows;
private final int mNumColumns;
+ private final double[][] mCorrections;
+ private final double[][] mCorrectionUncertainties;
public SphericalCorrections(@NonNull double[][] corrections,
@NonNull double[][] correctionUncertainties) {
- if (corrections.length != correctionUncertainties.length
- || corrections[0].length != correctionUncertainties[0].length) {
- throw new IllegalArgumentException("Correction and correction uncertainty arrays "
- + "must have the same dimensions.");
+ if (corrections.length != correctionUncertainties.length || corrections.length < 1) {
+ throw new IllegalArgumentException("correction and uncertainty arrays must have "
+ + "the same (non-zero) dimensions");
}
mNumRows = corrections.length;
- if (mNumRows < 1) {
- throw new IllegalArgumentException("Arrays must have at least one row.");
- }
-
mNumColumns = corrections[0].length;
- if (mNumColumns < 2) {
- throw new IllegalArgumentException("Arrays must have at least two columns.");
+ for (int i = 0; i < corrections.length; i++) {
+ if (corrections[i].length != mNumColumns
+ || correctionUncertainties[i].length != mNumColumns || mNumColumns < 2) {
+ throw new IllegalArgumentException("correction and uncertainty arrays must all "
+ + " have the same (greater than 2) number of columns");
+ }
}
mCorrections = corrections;
mCorrectionUncertainties = correctionUncertainties;
- mDeltaTheta = 360.0d / mNumRows;
- mDeltaPhi = 180.0d / (mNumColumns - 1);
}
- SphericalCorrections(Parcel in) {
+ private SphericalCorrections(Parcel in) {
int numRows = in.readInt();
int numColumns = in.readInt();
@@ -231,19 +251,16 @@ public final class GnssAntennaInfo implements Parcelable {
new double[numRows][numColumns];
for (int row = 0; row < numRows; row++) {
- in.readDoubleArray(corrections[row]);
- }
-
- for (int row = 0; row < numRows; row++) {
- in.readDoubleArray(correctionUncertainties[row]);
+ for (int col = 0; col < numColumns; col++) {
+ corrections[row][col] = in.readDouble();
+ correctionUncertainties[row][col] = in.readDouble();
+ }
}
mNumRows = numRows;
mNumColumns = numColumns;
mCorrections = corrections;
mCorrectionUncertainties = correctionUncertainties;
- mDeltaTheta = 360.0d / mNumRows;
- mDeltaPhi = 180.0d / (mNumColumns - 1);
}
/**
@@ -286,7 +303,7 @@ public final class GnssAntennaInfo implements Parcelable {
*/
@FloatRange(from = 0.0f, to = 360.0f)
public double getDeltaTheta() {
- return mDeltaTheta;
+ return 360.0D / mNumRows;
}
/**
@@ -294,7 +311,7 @@ public final class GnssAntennaInfo implements Parcelable {
*/
@FloatRange(from = 0.0f, to = 180.0f)
public double getDeltaPhi() {
- return mDeltaPhi;
+ return 180.0D / (mNumColumns - 1);
}
@@ -320,11 +337,11 @@ public final class GnssAntennaInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mNumRows);
dest.writeInt(mNumColumns);
- for (double[] row : mCorrections) {
- dest.writeDoubleArray(row);
- }
- for (double[] row : mCorrectionUncertainties) {
- dest.writeDoubleArray(row);
+ for (int row = 0; row < mNumRows; row++) {
+ for (int col = 0; col < mNumColumns; col++) {
+ dest.writeDouble(mCorrections[row][col]);
+ dest.writeDouble(mCorrectionUncertainties[row][col]);
+ }
}
}
@@ -333,22 +350,41 @@ public final class GnssAntennaInfo implements Parcelable {
return "SphericalCorrections{"
+ "Corrections=" + Arrays.toString(mCorrections)
+ ", CorrectionUncertainties=" + Arrays.toString(mCorrectionUncertainties)
- + ", DeltaTheta=" + mDeltaTheta
- + ", DeltaPhi=" + mDeltaPhi
+ + ", DeltaTheta=" + getDeltaTheta()
+ + ", DeltaPhi=" + getDeltaPhi()
+ '}';
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SphericalCorrections)) {
+ return false;
+ }
+ SphericalCorrections that = (SphericalCorrections) o;
+ return mNumRows == that.mNumRows
+ && mNumColumns == that.mNumColumns
+ && Arrays.deepEquals(mCorrections, that.mCorrections)
+ && Arrays.deepEquals(mCorrectionUncertainties, that.mCorrectionUncertainties);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Arrays.deepHashCode(mCorrections);
+ result = 31 * result + Arrays.deepHashCode(mCorrectionUncertainties);
+ return result;
+ }
}
private GnssAntennaInfo(
double carrierFrequencyMHz,
- @NonNull PhaseCenterOffset phaseCenterOffset,
+ PhaseCenterOffset phaseCenterOffset,
@Nullable SphericalCorrections phaseCenterVariationCorrections,
@Nullable SphericalCorrections signalGainCorrectionDbi) {
- if (phaseCenterOffset == null) {
- throw new IllegalArgumentException("Phase Center Offset Coordinates cannot be null.");
- }
mCarrierFrequencyMHz = carrierFrequencyMHz;
- mPhaseCenterOffset = phaseCenterOffset;
+ mPhaseCenterOffset = Objects.requireNonNull(phaseCenterOffset);
mPhaseCenterVariationCorrections = phaseCenterVariationCorrections;
mSignalGainCorrections = signalGainCorrectionDbi;
}
@@ -359,8 +395,28 @@ public final class GnssAntennaInfo implements Parcelable {
public static class Builder {
private double mCarrierFrequencyMHz;
private PhaseCenterOffset mPhaseCenterOffset;
- private SphericalCorrections mPhaseCenterVariationCorrections;
- private SphericalCorrections mSignalGainCorrections;
+ private @Nullable SphericalCorrections mPhaseCenterVariationCorrections;
+ private @Nullable SphericalCorrections mSignalGainCorrections;
+
+ /**
+ * @deprecated Prefer {@link #Builder(double, PhaseCenterOffset)}.
+ */
+ @Deprecated
+ public Builder() {
+ this(0, new PhaseCenterOffset(0, 0, 0, 0, 0, 0));
+ }
+
+ public Builder(double carrierFrequencyMHz, @NonNull PhaseCenterOffset phaseCenterOffset) {
+ mCarrierFrequencyMHz = carrierFrequencyMHz;
+ mPhaseCenterOffset = Objects.requireNonNull(phaseCenterOffset);
+ }
+
+ public Builder(@NonNull GnssAntennaInfo antennaInfo) {
+ mCarrierFrequencyMHz = antennaInfo.mCarrierFrequencyMHz;
+ mPhaseCenterOffset = antennaInfo.mPhaseCenterOffset;
+ mPhaseCenterVariationCorrections = antennaInfo.mPhaseCenterVariationCorrections;
+ mSignalGainCorrections = antennaInfo.mSignalGainCorrections;
+ }
/**
* Set antenna carrier frequency (MHz).
@@ -462,32 +518,29 @@ public final class GnssAntennaInfo implements Parcelable {
return mSignalGainCorrections;
}
- public static final @android.annotation.NonNull Creator<GnssAntennaInfo> CREATOR =
- new Creator<GnssAntennaInfo>() {
- @Override
- public GnssAntennaInfo createFromParcel(Parcel in) {
- double carrierFrequencyMHz = in.readDouble();
-
- ClassLoader classLoader = getClass().getClassLoader();
- PhaseCenterOffset phaseCenterOffset =
- in.readParcelable(classLoader);
- SphericalCorrections phaseCenterVariationCorrections =
- in.readParcelable(classLoader);
- SphericalCorrections signalGainCorrections =
- in.readParcelable(classLoader);
-
- return new GnssAntennaInfo(
- carrierFrequencyMHz,
- phaseCenterOffset,
- phaseCenterVariationCorrections,
- signalGainCorrections);
- }
+ public static final @NonNull Creator<GnssAntennaInfo> CREATOR = new Creator<GnssAntennaInfo>() {
+ @Override
+ public GnssAntennaInfo createFromParcel(Parcel in) {
+ double carrierFrequencyMHz = in.readDouble();
+ PhaseCenterOffset phaseCenterOffset =
+ in.readTypedObject(PhaseCenterOffset.CREATOR);
+ SphericalCorrections phaseCenterVariationCorrections =
+ in.readTypedObject(SphericalCorrections.CREATOR);
+ SphericalCorrections signalGainCorrections =
+ in.readTypedObject(SphericalCorrections.CREATOR);
+
+ return new GnssAntennaInfo(
+ carrierFrequencyMHz,
+ phaseCenterOffset,
+ phaseCenterVariationCorrections,
+ signalGainCorrections);
+ }
- @Override
- public GnssAntennaInfo[] newArray(int size) {
- return new GnssAntennaInfo[size];
- }
- };
+ @Override
+ public GnssAntennaInfo[] newArray(int size) {
+ return new GnssAntennaInfo[size];
+ }
+ };
@Override
public int describeContents() {
@@ -497,9 +550,9 @@ public final class GnssAntennaInfo implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeDouble(mCarrierFrequencyMHz);
- parcel.writeParcelable(mPhaseCenterOffset, flags);
- parcel.writeParcelable(mPhaseCenterVariationCorrections, flags);
- parcel.writeParcelable(mSignalGainCorrections, flags);
+ parcel.writeTypedObject(mPhaseCenterOffset, flags);
+ parcel.writeTypedObject(mPhaseCenterVariationCorrections, flags);
+ parcel.writeTypedObject(mSignalGainCorrections, flags);
}
@Override
@@ -511,4 +564,26 @@ public final class GnssAntennaInfo implements Parcelable {
+ ", SignalGainCorrections=" + mSignalGainCorrections
+ '}';
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof GnssAntennaInfo)) {
+ return false;
+ }
+ GnssAntennaInfo that = (GnssAntennaInfo) o;
+ return Double.compare(that.mCarrierFrequencyMHz, mCarrierFrequencyMHz) == 0
+ && mPhaseCenterOffset.equals(that.mPhaseCenterOffset)
+ && Objects.equals(mPhaseCenterVariationCorrections,
+ that.mPhaseCenterVariationCorrections)
+ && Objects.equals(mSignalGainCorrections, that.mSignalGainCorrections);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCarrierFrequencyMHz, mPhaseCenterOffset,
+ mPhaseCenterVariationCorrections, mSignalGainCorrections);
+ }
}
diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java
index 98ef2d4a6c9f..a07a64acb6e6 100644
--- a/location/java/android/location/GnssMeasurementsEvent.java
+++ b/location/java/android/location/GnssMeasurementsEvent.java
@@ -16,9 +16,9 @@
package android.location;
-import android.annotation.TestApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -46,8 +46,10 @@ public final class GnssMeasurementsEvent implements Parcelable {
public static abstract class Callback {
/**
* The status of the GNSS measurements event.
+ * @deprecated Do not use.
* @hide
*/
+ @Deprecated
@Retention(RetentionPolicy.SOURCE)
@IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED, STATUS_NOT_ALLOWED})
public @interface GnssMeasurementsStatus {}
@@ -56,19 +58,28 @@ public final class GnssMeasurementsEvent implements Parcelable {
* The system does not support tracking of GNSS Measurements.
*
* <p>This status will not change in the future.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_NOT_SUPPORTED = 0;
/**
* GNSS Measurements are successfully being tracked, it will receive updates once they are
* available.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_READY = 1;
/**
* GPS provider or Location is disabled, updates will not be received until they are
* enabled.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_LOCATION_DISABLED = 2;
/**
@@ -81,7 +92,10 @@ public final class GnssMeasurementsEvent implements Parcelable {
*
* <p>If such a status is received, one would try again at a later time point where no
* other client is having a conflicting request.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_NOT_ALLOWED = 3;
/**
@@ -91,7 +105,13 @@ public final class GnssMeasurementsEvent implements Parcelable {
/**
* Reports the latest status of the GNSS Measurements sub-system.
+ *
+ * @deprecated Do not rely on this callback. From Android S onwards this callback will be
+ * invoked once with {@link #STATUS_READY} in all cases for backwards compatibility, and
+ * then never invoked again. Use LocationManager APIs if you need to determine if
+ * GNSS measurements are supported or if location is off, etc...
*/
+ @Deprecated
public void onStatusChanged(@GnssMeasurementsStatus int status) {}
}
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index aade5ac63317..84a363d25c63 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -110,6 +110,7 @@ public final class GnssNavigationMessage implements Parcelable {
public static abstract class Callback {
/**
* The status of GNSS Navigation Message event.
+ * @deprecated Do not use.
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@@ -120,19 +121,28 @@ public final class GnssNavigationMessage implements Parcelable {
* The system does not support tracking of GNSS Navigation Messages.
*
* This status will not change in the future.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_NOT_SUPPORTED = 0;
/**
* GNSS Navigation Messages are successfully being tracked, it will receive updates once
* they are available.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_READY = 1;
/**
* GNSS provider or Location is disabled, updated will not be received until they are
* enabled.
+ *
+ * @deprecated Do not use.
*/
+ @Deprecated
public static final int STATUS_LOCATION_DISABLED = 2;
/**
@@ -142,7 +152,13 @@ public final class GnssNavigationMessage implements Parcelable {
/**
* Returns the latest status of the GNSS Navigation Messages sub-system.
+ *
+ * @deprecated Do not rely on this callback. From Android S onwards this callback will be
+ * invoked once with {@link #STATUS_READY} in all cases for backwards compatibility, and
+ * then never invoked again. Use LocationManager APIs if you need to determine if
+ * GNSS navigation messages are supported or if location is off, etc...
*/
+ @Deprecated
public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
}
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index c5b4c1667831..b46e8ce2f605 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -391,20 +391,10 @@ public final class GnssStatus implements Parcelable {
float[] basebandCn0DbHzs = new float[svCount];
for (int i = 0; i < svCount; i++) {
svidWithFlags[i] = in.readInt();
- }
- for (int i = 0; i < svCount; i++) {
cn0DbHzs[i] = in.readFloat();
- }
- for (int i = 0; i < svCount; i++) {
elevations[i] = in.readFloat();
- }
- for (int i = 0; i < svCount; i++) {
azimuths[i] = in.readFloat();
- }
- for (int i = 0; i < svCount; i++) {
carrierFrequencies[i] = in.readFloat();
- }
- for (int i = 0; i < svCount; i++) {
basebandCn0DbHzs[i] = in.readFloat();
}
@@ -428,20 +418,10 @@ public final class GnssStatus implements Parcelable {
parcel.writeInt(mSvCount);
for (int i = 0; i < mSvCount; i++) {
parcel.writeInt(mSvidWithFlags[i]);
- }
- for (int i = 0; i < mSvCount; i++) {
parcel.writeFloat(mCn0DbHzs[i]);
- }
- for (int i = 0; i < mSvCount; i++) {
parcel.writeFloat(mElevations[i]);
- }
- for (int i = 0; i < mSvCount; i++) {
parcel.writeFloat(mAzimuths[i]);
- }
- for (int i = 0; i < mSvCount; i++) {
parcel.writeFloat(mCarrierFrequencies[i]);
- }
- for (int i = 0; i < mSvCount; i++) {
parcel.writeFloat(mBasebandCn0DbHzs[i]);
}
}
diff --git a/location/java/android/location/IGnssAntennaInfoListener.aidl b/location/java/android/location/IGnssAntennaInfoListener.aidl
deleted file mode 100644
index 603ed6a2614e..000000000000
--- a/location/java/android/location/IGnssAntennaInfoListener.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.location.GnssAntennaInfo;
-
-/**
- * {@hide}
- */
-oneway interface IGnssAntennaInfoListener {
- void onGnssAntennaInfoReceived(in List<GnssAntennaInfo> gnssAntennaInfo);
-} \ No newline at end of file
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 621fe1ba1432..c50904cad4e2 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -21,11 +21,11 @@ import android.location.Address;
import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.Geofence;
+import android.location.GnssAntennaInfo;
import android.location.GnssCapabilities;
import android.location.GnssMeasurementCorrections;
import android.location.GnssMeasurementRequest;
import android.location.IGeocodeListener;
-import android.location.IGnssAntennaInfoListener;
import android.location.IGnssMeasurementsListener;
import android.location.IGnssStatusListener;
import android.location.IGnssNavigationMessageListener;
@@ -76,6 +76,8 @@ interface ILocationManager
int getGnssYearOfHardware();
String getGnssHardwareModelName();
+ @nullable List<GnssAntennaInfo> getGnssAntennaInfos();
+
void registerGnssStatusCallback(in IGnssStatusListener callback, String packageName, String attributionTag);
void unregisterGnssStatusCallback(in IGnssStatusListener callback);
@@ -86,9 +88,6 @@ interface ILocationManager
void removeGnssMeasurementsListener(in IGnssMeasurementsListener listener);
void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections);
- void addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, String attributionTag);
- void removeGnssAntennaInfoListener(in IGnssAntennaInfoListener listener);
-
void addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, String attributionTag);
void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 00381a68a2a2..1d3e8ebaa0ab 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -44,7 +44,10 @@ import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
@@ -64,6 +67,7 @@ import com.android.internal.listeners.ListenerTransportMultiplexer;
import com.android.internal.util.Preconditions;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -312,6 +316,48 @@ public class LocationManager {
"android.location.HIGH_POWER_REQUEST_CHANGE";
/**
+ * Broadcast intent action when GNSS capabilities change. This is most common at boot time as
+ * GNSS capabilities are queried from the chipset. Includes an intent extra,
+ * {@link #EXTRA_GNSS_CAPABILITIES}, with the new {@link GnssCapabilities}.
+ *
+ * @see #EXTRA_GNSS_CAPABILITIES
+ * @see #getGnssCapabilities()
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_GNSS_CAPABILITIES_CHANGED =
+ "android.location.action.GNSS_CAPABILITIES_CHANGED";
+
+ /**
+ * Intent extra included with {@link #ACTION_GNSS_CAPABILITIES_CHANGED} broadcasts, containing
+ * the new {@link GnssCapabilities}.
+ *
+ * @see #ACTION_GNSS_CAPABILITIES_CHANGED
+ */
+ public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES";
+
+ /**
+ * Broadcast intent action when GNSS antenna infos change. Includes an intent extra,
+ * {@link #EXTRA_GNSS_ANTENNA_INFOS}, with an ArrayList of the new {@link GnssAntennaInfo}. This
+ * may be read via {@link android.content.Intent#getParcelableArrayListExtra(String)}.
+ *
+ * @see #EXTRA_GNSS_ANTENNA_INFOS
+ * @see #getGnssAntennaInfos()
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_GNSS_ANTENNA_INFOS_CHANGED =
+ "android.location.action.GNSS_ANTENNA_INFOS_CHANGED";
+
+ /**
+ * Intent extra included with {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED} broadcasts, containing
+ * the new ArrayList of {@link GnssAntennaInfo}. This may be read via
+ * {@link android.content.Intent#getParcelableArrayListExtra(String)}.
+ *
+ * @see #ACTION_GNSS_ANTENNA_INFOS_CHANGED
+ */
+ public static final String EXTRA_GNSS_ANTENNA_INFOS =
+ "android.location.extra.GNSS_ANTENNA_INFOS";
+
+ /**
* Broadcast intent action for Settings app to inject a footer at the bottom of location
* settings. This is for use only by apps that are included in the system image.
*
@@ -2137,6 +2183,20 @@ public class LocationManager {
}
/**
+ * Returns the current list of GNSS antenna infos, or null if unknown or unsupported.
+ *
+ * @see #getGnssCapabilities()
+ */
+ @Nullable
+ public List<GnssAntennaInfo> getGnssAntennaInfos() {
+ try {
+ return mService.getGnssAntennaInfos();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Retrieves information about the current status of the GPS engine. This should only be called
* from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the
* data is copied atomically.
@@ -2559,15 +2619,19 @@ public class LocationManager {
*
* <p>Not all GNSS chipsets support antenna info updates, see {@link #getGnssCapabilities()}.
*
+ * <p>Prior to Android S, this requires the {@link Manifest.permission#ACCESS_FINE_LOCATION}
+ * permission.
+ *
* @param executor the executor that the listener runs on
* @param listener the listener to register
* @return {@code true} always
*
* @throws IllegalArgumentException if executor is null
* @throws IllegalArgumentException if listener is null
- * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+ *
+ * @deprecated Prefer to use a receiver for {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED}.
*/
- @RequiresPermission(ACCESS_FINE_LOCATION)
+ @Deprecated
public boolean registerAntennaInfoListener(
@NonNull @CallbackExecutor Executor executor,
@NonNull GnssAntennaInfo.Listener listener) {
@@ -2579,7 +2643,10 @@ public class LocationManager {
* Unregisters a GNSS Antenna Info listener.
*
* @param listener a {@link GnssAntennaInfo.Listener} object to remove
+ *
+ * @deprecated Prefer to use a receiver for {@link #ACTION_GNSS_ANTENNA_INFOS_CHANGED}.
*/
+ @Deprecated
public void unregisterAntennaInfoListener(@NonNull GnssAntennaInfo.Listener listener) {
getGnssAntennaInfoTransportMultiplexer().removeListener(listener);
}
@@ -3153,40 +3220,41 @@ public class LocationManager {
private class GnssAntennaInfoTransportMultiplexer extends
ListenerTransportMultiplexer<Void, GnssAntennaInfo.Listener> {
- private @Nullable IGnssAntennaInfoListener mListenerTransport;
+ private @Nullable BroadcastReceiver mListenerTransport;
GnssAntennaInfoTransportMultiplexer() {}
@Override
- protected void registerWithServer(Void ignored) throws RemoteException {
- IGnssAntennaInfoListener transport = mListenerTransport;
- if (transport == null) {
- transport = new GnssAntennaInfoListener();
+ protected void registerWithServer(Void ignored) {
+ if (mListenerTransport == null) {
+ // if an exception is thrown the transport should not be set
+ BroadcastReceiver transport = new GnssAntennaInfoReceiver();
+ mContext.registerReceiver(transport,
+ new IntentFilter(ACTION_GNSS_ANTENNA_INFOS_CHANGED));
+ mListenerTransport = transport;
}
-
- // if a remote exception is thrown the transport should not be set
- mListenerTransport = null;
- mService.addGnssAntennaInfoListener(transport, mContext.getPackageName(),
- mContext.getAttributionTag());
- mListenerTransport = transport;
}
@Override
- protected void unregisterWithServer() throws RemoteException {
+ protected void unregisterWithServer() {
if (mListenerTransport != null) {
- IGnssAntennaInfoListener transport = mListenerTransport;
+ BroadcastReceiver transport = mListenerTransport;
mListenerTransport = null;
- mService.removeGnssAntennaInfoListener(transport);
+ mContext.unregisterReceiver(transport);
}
}
- private class GnssAntennaInfoListener extends IGnssAntennaInfoListener.Stub {
+ private class GnssAntennaInfoReceiver extends BroadcastReceiver {
- GnssAntennaInfoListener() {}
+ GnssAntennaInfoReceiver() {}
@Override
- public void onGnssAntennaInfoReceived(List<GnssAntennaInfo> infos) {
- deliverToListeners(callback -> callback.onGnssAntennaInfoReceived(infos));
+ public void onReceive(Context context, Intent intent) {
+ ArrayList<GnssAntennaInfo> infos = intent.getParcelableArrayListExtra(
+ EXTRA_GNSS_ANTENNA_INFOS);
+ if (infos != null) {
+ deliverToListeners(callback -> callback.onGnssAntennaInfoReceived(infos));
+ }
}
}
}
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 372bceeea3c4..9ab30b403044 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -45,11 +45,11 @@ import android.content.Intent;
import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.Geofence;
+import android.location.GnssAntennaInfo;
import android.location.GnssCapabilities;
import android.location.GnssMeasurementCorrections;
import android.location.GnssMeasurementRequest;
import android.location.IGeocodeListener;
-import android.location.IGnssAntennaInfoListener;
import android.location.IGnssMeasurementsListener;
import android.location.IGnssNavigationMessageListener;
import android.location.IGnssNmeaListener;
@@ -913,18 +913,8 @@ public class LocationManagerService extends ILocationManager.Stub {
}
@Override
- public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener,
- String packageName, String attributionTag) {
- if (mGnssManagerService != null) {
- mGnssManagerService.addGnssAntennaInfoListener(listener, packageName, attributionTag);
- }
- }
-
- @Override
- public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) {
- if (mGnssManagerService != null) {
- mGnssManagerService.removeGnssAntennaInfoListener(listener);
- }
+ public List<GnssAntennaInfo> getGnssAntennaInfos() {
+ return mGnssManagerService == null ? null : mGnssManagerService.getGnssAntennaInfos();
}
@Override
diff --git a/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java b/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java
deleted file mode 100644
index e9f79efb0513..000000000000
--- a/services/core/java/com/android/server/location/gnss/GnssAntennaInfoProvider.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 com.android.server.location.gnss;
-
-import static com.android.server.location.gnss.GnssManagerService.D;
-import static com.android.server.location.gnss.GnssManagerService.TAG;
-
-import android.location.GnssAntennaInfo;
-import android.location.GnssCapabilities;
-import android.location.IGnssAntennaInfoListener;
-import android.location.util.identity.CallerIdentity;
-import android.util.Log;
-
-import com.android.server.location.gnss.hal.GnssNative;
-import com.android.server.location.injector.Injector;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Provides GNSS antenna information to clients.
- */
-public class GnssAntennaInfoProvider extends
- GnssListenerMultiplexer<Void, IGnssAntennaInfoListener, Void> implements
- GnssNative.BaseCallbacks, GnssNative.AntennaInfoCallbacks {
-
- private final GnssNative mGnssNative;
-
- public GnssAntennaInfoProvider(Injector injector, GnssNative gnssNative) {
- super(injector);
- mGnssNative = gnssNative;
-
- mGnssNative.addBaseCallbacks(this);
- mGnssNative.addAntennaInfoCallbacks(this);
- }
-
- @Override
- protected boolean isServiceSupported() {
- return mGnssNative.isAntennaInfoListeningSupported();
- }
-
- @Override
- public void addListener(CallerIdentity identity, IGnssAntennaInfoListener listener) {
- super.addListener(identity, listener);
- }
-
- @Override
- protected boolean registerWithService(Void ignored,
- Collection<GnssListenerRegistration> registrations) {
- if (mGnssNative.startAntennaInfoListening()) {
- if (D) {
- Log.d(TAG, "starting gnss antenna info");
- }
- return true;
- } else {
- Log.e(TAG, "error starting gnss antenna info");
- return false;
- }
- }
-
- @Override
- protected void unregisterWithService() {
- if (mGnssNative.stopAntennaInfoListening()) {
- if (D) {
- Log.d(TAG, "stopping gnss antenna info");
- }
- } else {
- Log.e(TAG, "error stopping gnss antenna info");
- }
- }
-
- @Override
- public void onHalRestarted() {
- resetService();
- }
-
- @Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
-
- @Override
- public void onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos) {
- deliverToListeners(listener -> {
- listener.onGnssAntennaInfoReceived(antennaInfos);
- });
- }
-}
diff --git a/services/core/java/com/android/server/location/gnss/GnssGeofenceProxy.java b/services/core/java/com/android/server/location/gnss/GnssGeofenceProxy.java
index 32a7952b14d1..f40ded98166c 100644
--- a/services/core/java/com/android/server/location/gnss/GnssGeofenceProxy.java
+++ b/services/core/java/com/android/server/location/gnss/GnssGeofenceProxy.java
@@ -16,7 +16,6 @@
package com.android.server.location.gnss;
-import android.location.GnssCapabilities;
import android.location.IGpsGeofenceHardware;
import android.util.SparseArray;
@@ -141,8 +140,4 @@ class GnssGeofenceProxy extends IGpsGeofenceHardware.Stub implements GnssNative.
}
}
}
-
- @Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
}
diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
index 7e848e03c3a0..87e6ef4110ee 100644
--- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
+++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java
@@ -96,12 +96,29 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
}
@Override
- protected void onBinderListenerRegister() {
+ protected final void onBinderListenerRegister() {
mPermitted = mLocationPermissionsHelper.hasLocationPermissions(PERMISSION_FINE,
getIdentity());
mForeground = mAppForegroundHelper.isAppForeground(getIdentity().getUid());
+
+ onGnssListenerRegister();
}
+ @Override
+ protected final void onBinderListenerUnregister() {
+ onGnssListenerUnregister();
+ }
+
+ /**
+ * May be overridden in place of {@link #onBinderListenerRegister()}.
+ */
+ protected void onGnssListenerRegister() {}
+
+ /**
+ * May be overridden in place of {@link #onBinderListenerUnregister()}.
+ */
+ protected void onGnssListenerUnregister() {}
+
boolean onLocationPermissionsChanged(String packageName) {
if (getIdentity().getPackageName().equals(packageName)) {
return onLocationPermissionsChanged();
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index afe75674647f..477c037befc4 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -50,7 +50,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
-import android.location.Criteria;
import android.location.GnssCapabilities;
import android.location.GnssStatus;
import android.location.INetInitiatedListener;
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 ff9244464069..92957aaf2976 100644
--- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java
+++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
@@ -19,23 +19,27 @@ package com.android.server.location.gnss;
import android.Manifest;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.Intent;
import android.hardware.location.GeofenceHardware;
import android.hardware.location.GeofenceHardwareImpl;
import android.location.FusedBatchOptions;
+import android.location.GnssAntennaInfo;
import android.location.GnssCapabilities;
import android.location.GnssMeasurementCorrections;
import android.location.GnssMeasurementRequest;
-import android.location.IGnssAntennaInfoListener;
import android.location.IGnssMeasurementsListener;
import android.location.IGnssNavigationMessageListener;
import android.location.IGnssNmeaListener;
import android.location.IGnssStatusListener;
import android.location.IGpsGeofenceHardware;
import android.location.Location;
+import android.location.LocationManager;
import android.location.util.identity.CallerIdentity;
import android.os.BatteryStats;
+import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.util.IndentingPrintWriter;
import android.util.Log;
@@ -45,6 +49,8 @@ import com.android.server.location.gnss.hal.GnssNative;
import com.android.server.location.injector.Injector;
import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.List;
/** Manages Gnss providers and related Gnss functions for LocationManagerService. */
public class GnssManagerService {
@@ -61,10 +67,13 @@ public class GnssManagerService {
private final GnssStatusProvider mGnssStatusProvider;
private final GnssNmeaProvider mGnssNmeaProvider;
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
- private final GnssAntennaInfoProvider mGnssAntennaInfoProvider;
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
private final IGpsGeofenceHardware mGnssGeofenceProxy;
+ private final GnssGeofenceHalModule mGeofenceHalModule;
+ private final GnssCapabilitiesHalModule mCapabilitiesHalModule;
+ private final GnssAntennaInfoHalModule mAntennaInfoHalModule;
+
private final GnssMetrics mGnssMetrics;
public GnssManagerService(Context context, Injector injector, GnssNative gnssNative) {
@@ -79,11 +88,12 @@ public class GnssManagerService {
mGnssStatusProvider = new GnssStatusProvider(injector, mGnssNative);
mGnssNmeaProvider = new GnssNmeaProvider(injector, mGnssNative);
mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector, mGnssNative);
- mGnssAntennaInfoProvider = new GnssAntennaInfoProvider(injector, mGnssNative);
mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(injector, mGnssNative);
mGnssGeofenceProxy = new GnssGeofenceProxy(mGnssNative);
- mGnssNative.setGeofenceCallbacks(new GnssGeofenceHalModule());
+ mGeofenceHalModule = new GnssGeofenceHalModule(mGnssNative);
+ mCapabilitiesHalModule = new GnssCapabilitiesHalModule(mGnssNative);
+ mAntennaInfoHalModule = new GnssAntennaInfoHalModule(mGnssNative);
// allow gnss access to begin - we must assume that callbacks can start immediately
mGnssNative.register();
@@ -120,14 +130,20 @@ public class GnssManagerService {
}
/**
- * Get GNSS hardware capabilities. The capabilities returned are a bitfield as described in
- * {@link android.location.GnssCapabilities}.
+ * Get GNSS hardware capabilities.
*/
public GnssCapabilities getGnssCapabilities() {
return mGnssNative.getCapabilities();
}
/**
+ * Get GNSS antenna information.
+ */
+ public @Nullable List<GnssAntennaInfo> getGnssAntennaInfos() {
+ return mAntennaInfoHalModule.getAntennaInfos();
+ }
+
+ /**
* Get size of GNSS batch (GNSS location results are batched together for power savings).
*/
public int getGnssBatchSize() {
@@ -202,29 +218,6 @@ public class GnssManagerService {
}
/**
- * Adds a GNSS Antenna Info listener.
- *
- * @param listener called when GNSS antenna info is received
- * @param packageName name of requesting package
- */
- public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName,
- @Nullable String attributionTag) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
-
- CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag);
- mGnssAntennaInfoProvider.addListener(identity, listener);
- }
-
- /**
- * Removes a GNSS Antenna Info listener.
- *
- * @param listener called when GNSS antenna info is received
- */
- public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) {
- mGnssAntennaInfoProvider.removeListener(listener);
- }
-
- /**
* Adds a GNSS navigation message listener.
*/
public void addGnssNavigationMessageListener(IGnssNavigationMessageListener listener,
@@ -264,12 +257,12 @@ public class GnssManagerService {
ipw.println("Capabilities: " + mGnssNative.getCapabilities());
- ipw.println("Antenna Info Provider:");
- ipw.increaseIndent();
- mGnssAntennaInfoProvider.dump(fd, ipw, args);
- ipw.decreaseIndent();
+ List<GnssAntennaInfo> infos = mAntennaInfoHalModule.getAntennaInfos();
+ if (infos != null) {
+ ipw.println("Antenna Infos: " + infos);
+ }
- ipw.println("Measurement Provider:");
+ ipw.println("Measurements Provider:");
ipw.increaseIndent();
mGnssMeasurementsProvider.dump(fd, ipw, args);
ipw.decreaseIndent();
@@ -293,10 +286,39 @@ public class GnssManagerService {
}
}
+ private class GnssCapabilitiesHalModule implements GnssNative.BaseCallbacks {
+
+ GnssCapabilitiesHalModule(GnssNative gnssNative) {
+ gnssNative.addBaseCallbacks(this);
+ }
+
+ @Override
+ public void onHalRestarted() {}
+
+ @Override
+ public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
+ GnssCapabilities newCapabilities) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(LocationManager.ACTION_GNSS_CAPABILITIES_CHANGED)
+ .putExtra(LocationManager.EXTRA_GNSS_CAPABILITIES, newCapabilities)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
private class GnssGeofenceHalModule implements GnssNative.GeofenceCallbacks {
private GeofenceHardwareImpl mGeofenceHardwareImpl;
+ GnssGeofenceHalModule(GnssNative gnssNative) {
+ gnssNative.setGeofenceCallbacks(this);
+ }
+
private synchronized GeofenceHardwareImpl getGeofenceHardware() {
if (mGeofenceHardwareImpl == null) {
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
@@ -371,4 +393,53 @@ public class GnssManagerService {
}
}
}
+
+ private class GnssAntennaInfoHalModule implements GnssNative.BaseCallbacks,
+ GnssNative.AntennaInfoCallbacks {
+
+ private final GnssNative mGnssNative;
+
+ private volatile @Nullable List<GnssAntennaInfo> mAntennaInfos;
+
+ GnssAntennaInfoHalModule(GnssNative gnssNative) {
+ mGnssNative = gnssNative;
+ mGnssNative.addBaseCallbacks(this);
+ mGnssNative.addAntennaInfoCallbacks(this);
+ }
+
+ @Nullable List<GnssAntennaInfo> getAntennaInfos() {
+ return mAntennaInfos;
+ }
+
+ @Override
+ public void onHalStarted() {
+ mGnssNative.startAntennaInfoListening();
+ }
+
+ @Override
+ public void onHalRestarted() {
+ mGnssNative.startAntennaInfoListening();
+ }
+
+ @Override
+ public void onReportAntennaInfo(List<GnssAntennaInfo> antennaInfos) {
+ if (antennaInfos.equals(mAntennaInfos)) {
+ return;
+ }
+
+ mAntennaInfos = antennaInfos;
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ Intent intent = new Intent(LocationManager.ACTION_GNSS_ANTENNA_INFOS_CHANGED)
+ .putParcelableArrayListExtra(LocationManager.EXTRA_GNSS_ANTENNA_INFOS,
+ new ArrayList<>(antennaInfos))
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
}
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 b7cc9f51bfec..b623e279d9ae 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
@@ -21,7 +21,6 @@ import static com.android.server.location.gnss.GnssManagerService.TAG;
import android.annotation.Nullable;
import android.app.AppOpsManager;
-import android.location.GnssCapabilities;
import android.location.GnssMeasurementRequest;
import android.location.GnssMeasurementsEvent;
import android.location.IGnssMeasurementsListener;
@@ -58,8 +57,14 @@ public final class GnssMeasurementsProvider extends
protected GnssMeasurementListenerRegistration(
@Nullable GnssMeasurementRequest request,
CallerIdentity callerIdentity,
- IGnssMeasurementsListener iGnssMeasurementsListener) {
- super(request, callerIdentity, iGnssMeasurementsListener);
+ IGnssMeasurementsListener listener) {
+ super(request, callerIdentity, listener);
+ }
+
+ @Override
+ protected void onGnssListenerRegister() {
+ executeOperation(listener -> listener.onStatusChanged(
+ GnssMeasurementsEvent.Callback.STATUS_READY));
}
@Nullable
@@ -201,10 +206,6 @@ public final class GnssMeasurementsProvider extends
}
@Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
-
- @Override
public void onReportMeasurements(GnssMeasurementsEvent event) {
deliverToListeners(registration -> {
if (mAppOpsHelper.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION,
diff --git a/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java b/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java
index 9b1cde0d967c..ff9ad65b4ca5 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNavigationMessageProvider.java
@@ -20,7 +20,6 @@ import static com.android.server.location.gnss.GnssManagerService.D;
import static com.android.server.location.gnss.GnssManagerService.TAG;
import android.app.AppOpsManager;
-import android.location.GnssCapabilities;
import android.location.GnssNavigationMessage;
import android.location.IGnssNavigationMessageListener;
import android.location.util.identity.CallerIdentity;
@@ -43,6 +42,21 @@ public class GnssNavigationMessageProvider extends
GnssListenerMultiplexer<Void, IGnssNavigationMessageListener, Void> implements
GnssNative.BaseCallbacks, GnssNative.NavigationMessageCallbacks {
+ private class GnssNavigationMessageListenerRegistration extends GnssListenerRegistration {
+
+ protected GnssNavigationMessageListenerRegistration(
+ CallerIdentity callerIdentity,
+ IGnssNavigationMessageListener listener) {
+ super(null, callerIdentity, listener);
+ }
+
+ @Override
+ protected void onGnssListenerRegister() {
+ executeOperation(listener -> listener.onStatusChanged(
+ GnssNavigationMessage.Callback.STATUS_READY));
+ }
+ }
+
private final AppOpsHelper mAppOpsHelper;
private final GnssNative mGnssNative;
@@ -66,6 +80,12 @@ public class GnssNavigationMessageProvider extends
}
@Override
+ protected GnssListenerRegistration createRegistration(Void request,
+ CallerIdentity callerIdentity, IGnssNavigationMessageListener listener) {
+ return new GnssNavigationMessageListenerRegistration(callerIdentity, listener);
+ }
+
+ @Override
protected boolean registerWithService(Void ignored,
Collection<GnssListenerRegistration> registrations) {
if (mGnssNative.startNavigationMessageCollection()) {
@@ -96,10 +116,6 @@ public class GnssNavigationMessageProvider extends
}
@Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
-
- @Override
public void onReportNavigationMessage(GnssNavigationMessage event) {
deliverToListeners(registration -> {
if (mAppOpsHelper.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION,
diff --git a/services/core/java/com/android/server/location/gnss/GnssNmeaProvider.java b/services/core/java/com/android/server/location/gnss/GnssNmeaProvider.java
index bad1b79e3568..5036a6e7edf5 100644
--- a/services/core/java/com/android/server/location/gnss/GnssNmeaProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssNmeaProvider.java
@@ -21,7 +21,6 @@ import static com.android.server.location.gnss.GnssManagerService.TAG;
import android.annotation.Nullable;
import android.app.AppOpsManager;
-import android.location.GnssCapabilities;
import android.location.IGnssNmeaListener;
import android.location.util.identity.CallerIdentity;
import android.util.Log;
@@ -83,10 +82,6 @@ class GnssNmeaProvider extends GnssListenerMultiplexer<Void, IGnssNmeaListener,
}
@Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
-
- @Override
public void onReportNmea(long timestamp) {
deliverToListeners(
new Function<GnssListenerRegistration,
diff --git a/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java b/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
index e0673db274e5..1eb16184685d 100644
--- a/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssStatusProvider.java
@@ -20,7 +20,6 @@ import static com.android.server.location.gnss.GnssManagerService.D;
import static com.android.server.location.gnss.GnssManagerService.TAG;
import android.app.AppOpsManager;
-import android.location.GnssCapabilities;
import android.location.GnssStatus;
import android.location.IGnssStatusListener;
import android.location.util.identity.CallerIdentity;
@@ -111,10 +110,6 @@ public class GnssStatusProvider extends
}
@Override
- public void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities) {}
-
- @Override
public void onReportStatus(@GnssNative.StatusCallbacks.GnssStatusValue int gnssStatus) {
boolean isNavigating;
switch (gnssStatus) {
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 89d82495dca3..65384d7d4a2f 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
@@ -141,9 +141,10 @@ public class GnssNative {
/** Callbacks relevant to the entire HAL. */
public interface BaseCallbacks {
+ default void onHalStarted() {}
void onHalRestarted();
- void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
- GnssCapabilities newCapabilities);
+ default void onCapabilitiesChanged(GnssCapabilities oldCapabilities,
+ GnssCapabilities newCapabilities) {}
}
/** Callbacks for status events. */
@@ -480,6 +481,11 @@ public class GnssNative {
mRegistered = true;
initializeGnss(false);
+ Log.i(TAG, "gnss hal started");
+
+ for (int i = 0; i < mBaseCallbacks.length; i++) {
+ mBaseCallbacks[i].onHalStarted();
+ }
}
private void initializeGnss(boolean restart) {
@@ -1413,6 +1419,8 @@ public class GnssNative {
private static native boolean native_stop_navigation_message_collection();
// antenna info APIS
+ // TODO: in a next version of the HAL, consider removing the necessity for listening to antenna
+ // info changes, and simply report them always, same as capabilities.
private static native boolean native_is_antenna_info_supported();