diff options
author | 2020-12-23 08:25:13 -0800 | |
---|---|---|
committer | 2020-12-28 10:50:50 -0800 | |
commit | b76a3541a1036484a52d6171c0823cb70b21e193 (patch) | |
tree | 886a0c725ddfb4fdc7d40dab9d78bfdaa76dcde5 | |
parent | 36ca6d3452868f9076c2a76c6a3d00a31bf17440 (diff) |
Replace LocationProvider with ProviderProperties
LocationProvider cannot represent unknown properties, which is currently
causing problems with getProvider() which may return null even when a
particular provider exists. Instead provide isProvider() to query
whether a provider exists, and getProviderProperties() to query a
provider's properties.
Bug: 176232308
Test: atest CtsLocationNoneTestCases
Change-Id: Ic42cc953624be116616b0b997e18356247fdf288
21 files changed, 295 insertions, 205 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 1c50e14d0caa..3dcdff213819 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -19300,9 +19300,11 @@ package android.location { method public int getGnssYearOfHardware(); method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(@NonNull String); - method @Nullable public android.location.LocationProvider getProvider(@NonNull String); + method @Deprecated @Nullable public android.location.LocationProvider getProvider(@NonNull String); + method @Nullable public android.location.ProviderProperties getProviderProperties(@NonNull String); method @NonNull public java.util.List<java.lang.String> getProviders(boolean); method @NonNull public java.util.List<java.lang.String> getProviders(@NonNull android.location.Criteria, boolean); + 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); @@ -19363,18 +19365,18 @@ package android.location { field public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED"; } - public class LocationProvider { - method public int getAccuracy(); - method public String getName(); - method public int getPowerRequirement(); - method public boolean hasMonetaryCost(); - method public boolean meetsCriteria(android.location.Criteria); - method public boolean requiresCell(); - method public boolean requiresNetwork(); - method public boolean requiresSatellite(); - method public boolean supportsAltitude(); - method public boolean supportsBearing(); - method public boolean supportsSpeed(); + @Deprecated public class LocationProvider { + method @Deprecated public int getAccuracy(); + method @Deprecated public String getName(); + method @Deprecated public int getPowerRequirement(); + method @Deprecated public boolean hasMonetaryCost(); + method @Deprecated public boolean meetsCriteria(android.location.Criteria); + method @Deprecated public boolean requiresCell(); + method @Deprecated public boolean requiresNetwork(); + method @Deprecated public boolean requiresSatellite(); + method @Deprecated public boolean supportsAltitude(); + method @Deprecated public boolean supportsBearing(); + method @Deprecated public boolean supportsSpeed(); field @Deprecated public static final int AVAILABLE = 2; // 0x2 field @Deprecated public static final int OUT_OF_SERVICE = 0; // 0x0 field @Deprecated public static final int TEMPORARILY_UNAVAILABLE = 1; // 0x1 @@ -19427,6 +19429,26 @@ package android.location { method public void onNmeaMessage(String, long); } + public final class ProviderProperties implements android.os.Parcelable { + method public int describeContents(); + method public int getAccuracy(); + method public int getPowerUsage(); + method public boolean hasAltitudeSupport(); + method public boolean hasBearingSupport(); + method public boolean hasCellRequirement(); + method public boolean hasMonetaryCost(); + method public boolean hasNetworkRequirement(); + method public boolean hasSatelliteRequirement(); + method public boolean hasSpeedSupport(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int ACCURACY_COARSE = 2; // 0x2 + field public static final int ACCURACY_FINE = 1; // 0x1 + field @NonNull public static final android.os.Parcelable.Creator<android.location.ProviderProperties> CREATOR; + field public static final int POWER_USAGE_HIGH = 3; // 0x3 + field public static final int POWER_USAGE_LOW = 1; // 0x1 + field public static final int POWER_USAGE_MEDIUM = 2; // 0x2 + } + public abstract class SettingInjectorService extends android.app.Service { ctor public SettingInjectorService(String); method public final android.os.IBinder onBind(android.content.Intent); diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index a666eb4cb74a..1dbc98d6c996 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -34,11 +34,10 @@ import android.location.LastLocationRequest; import android.location.Location; import android.location.LocationRequest; import android.location.LocationTime; +import android.location.ProviderProperties; import android.os.Bundle; import android.os.ICancellationSignal; -import com.android.internal.location.ProviderProperties; - /** * System private API for talking with the location service. * @@ -93,6 +92,7 @@ interface ILocationManager void flushGnssBatch(); void stopGnssBatch(); + boolean hasProvider(String provider); List<String> getAllProviders(); List<String> getProviders(in Criteria criteria, boolean enabledOnly); String getBestProvider(in Criteria criteria, boolean enabledOnly); diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index ecdba1fe5b12..c5e5b4177858 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -61,7 +61,6 @@ import android.os.UserHandle; import com.android.internal.annotations.GuardedBy; import com.android.internal.listeners.ListenerExecutor; import com.android.internal.listeners.ListenerTransportMultiplexer; -import com.android.internal.location.ProviderProperties; import com.android.internal.util.Preconditions; import java.lang.ref.WeakReference; @@ -1616,6 +1615,25 @@ public class LocationManager { } /** + * Returns true if the given location provider exists on this device, irrespective of whether + * it is currently enabled or not. + * + * @param provider a potential location provider + * @return true if the location provider exists, false otherwise + * + * @throws IllegalArgumentException if provider is null + */ + public boolean hasProvider(@NonNull String provider) { + Preconditions.checkArgument(provider != null, "invalid null provider"); + + try { + return mService.hasProvider(provider); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns a list of the names of all available location providers. All providers are returned, * including those that are currently disabled. * @@ -1703,7 +1721,12 @@ public class LocationManager { * @return location provider information, or null if provider does not exist * * @throws IllegalArgumentException if provider is null + * + * @deprecated This method has no way to indicate that a provider's properties are unknown, and + * so may return incorrect results on rare occasions. Use {@link #getProviderProperties(String)} + * instead. */ + @Deprecated public @Nullable LocationProvider getProvider(@NonNull String provider) { Preconditions.checkArgument(provider != null, "invalid null provider"); @@ -1723,11 +1746,33 @@ public class LocationManager { } try { + ProviderProperties properties = mService.getProviderProperties(provider); - if (properties == null) { - return null; - } return new LocationProvider(provider, properties); + } catch (IllegalArgumentException e) { + // provider does not exist + return null; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns the properties of the given provider, or null if the properties are currently + * unknown. Provider properties may change over time, although this is discouraged, and should + * be rare. The most common transition is when provider properties go from being unknown to + * known, which is most common near boot time. + * + * @param provider a provider listed by {@link #getAllProviders()} + * @return location provider properties, or null if properties are currently unknown + * + * @throws IllegalArgumentException if provider is null or does not exist + */ + public @Nullable ProviderProperties getProviderProperties(@NonNull String provider) { + Preconditions.checkArgument(provider != null, "invalid null provider"); + + try { + return mService.getProviderProperties(provider); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1826,12 +1871,14 @@ public class LocationManager { public void addTestProvider( @NonNull String provider, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, - boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { + boolean supportsSpeed, boolean supportsBearing, + @ProviderProperties.PowerUsage int powerUsage, + @ProviderProperties.Accuracy int accuracy) { Preconditions.checkArgument(provider != null, "invalid null provider"); ProviderProperties properties = new ProviderProperties(requiresNetwork, requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed, - supportsBearing, powerRequirement, accuracy); + supportsBearing, powerUsage, accuracy); try { mService.addTestProvider(provider, properties, mContext.getOpPackageName(), mContext.getFeatureId()); diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java index b9506041554b..6d2bfed99fb7 100644 --- a/location/java/android/location/LocationProvider.java +++ b/location/java/android/location/LocationProvider.java @@ -16,23 +16,15 @@ package android.location; - -import com.android.internal.location.ProviderProperties; +import android.annotation.Nullable; /** - * An abstract superclass for location providers. A location provider - * provides periodic reports on the geographical location of the - * device. + * Information about the properties of a location provider. * - * <p> Each provider has a set of criteria under which it may be used; - * for example, some providers require GPS hardware and visibility to - * a number of satellites; others require the use of the cellular - * radio, or access to a specific carrier's network, or to the - * internet. They may also have different battery consumption - * characteristics or monetary costs to the user. The {@link - * Criteria} class allows providers to be selected based on - * user-specified criteria. + * @deprecated This class is incapable of representing unknown provider properties and may return + * incorrect results when the properties are unknown. */ +@Deprecated public class LocationProvider { /** @@ -54,9 +46,9 @@ public class LocationProvider { public static final int AVAILABLE = 2; private final String mName; - private final ProviderProperties mProperties; + private final @Nullable ProviderProperties mProperties; - LocationProvider(String name, ProviderProperties properties) { + LocationProvider(String name, @Nullable ProviderProperties properties) { mName = name; mProperties = properties; } @@ -96,7 +88,7 @@ public class LocationProvider { return false; } if (criteria.getPowerRequirement() != Criteria.NO_REQUIREMENT && - criteria.getPowerRequirement() < properties.getPowerRequirement()) { + criteria.getPowerRequirement() < properties.getPowerUsage()) { return false; } if (criteria.isAltitudeRequired() && !properties.hasAltitudeSupport()) { @@ -119,7 +111,11 @@ public class LocationProvider { * data network (e.g., the Internet), false otherwise. */ public boolean requiresNetwork() { - return mProperties.hasNetworkRequirement(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasNetworkRequirement(); + } } /** @@ -128,7 +124,11 @@ public class LocationProvider { * otherwise. */ public boolean requiresSatellite() { - return mProperties.hasSatelliteRequirement(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasSatelliteRequirement(); + } } /** @@ -137,7 +137,11 @@ public class LocationProvider { * otherwise. */ public boolean requiresCell() { - return mProperties.hasCellRequirement(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasCellRequirement(); + } } /** @@ -146,7 +150,11 @@ public class LocationProvider { * each provider to give accurate information. */ public boolean hasMonetaryCost() { - return mProperties.hasMonetaryCost(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasMonetaryCost(); + } } /** @@ -156,7 +164,11 @@ public class LocationProvider { * should return true. */ public boolean supportsAltitude() { - return mProperties.hasAltitudeSupport(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasAltitudeSupport(); + } } /** @@ -166,7 +178,11 @@ public class LocationProvider { * should return true. */ public boolean supportsSpeed() { - return mProperties.hasSpeedSupport(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasSpeedSupport(); + } } /** @@ -176,27 +192,39 @@ public class LocationProvider { * should return true. */ public boolean supportsBearing() { - return mProperties.hasBearingSupport(); + if (mProperties == null) { + return false; + } else { + return mProperties.hasBearingSupport(); + } } /** * Returns the power requirement for this provider. * * @return the power requirement for this provider, as one of the - * constants Criteria.POWER_REQUIREMENT_*. + * constants ProviderProperties.POWER_USAGE_*. */ public int getPowerRequirement() { - return mProperties.getPowerRequirement(); + if (mProperties == null) { + return ProviderProperties.POWER_USAGE_HIGH; + } else { + return mProperties.getPowerUsage(); + } } /** * Returns a constant describing horizontal accuracy of this provider. * If the provider returns finer grain or exact location, - * {@link Criteria#ACCURACY_FINE} is returned, otherwise if the - * location is only approximate then {@link Criteria#ACCURACY_COARSE} + * {@link ProviderProperties#ACCURACY_FINE} is returned, otherwise if the + * location is only approximate then {@link ProviderProperties#ACCURACY_COARSE} * is returned. */ public int getAccuracy() { - return mProperties.getAccuracy(); + if (mProperties == null) { + return ProviderProperties.ACCURACY_COARSE; + } else { + return mProperties.getAccuracy(); + } } } diff --git a/location/java/com/android/internal/location/ProviderProperties.aidl b/location/java/android/location/ProviderProperties.aidl index b90144442a07..8b1d79f90233 100644 --- a/location/java/com/android/internal/location/ProviderProperties.aidl +++ b/location/java/android/location/ProviderProperties.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location; parcelable ProviderProperties; diff --git a/location/java/com/android/internal/location/ProviderProperties.java b/location/java/android/location/ProviderProperties.java index dbb61d2305f0..8fa8c984b172 100644 --- a/location/java/com/android/internal/location/ProviderProperties.java +++ b/location/java/android/location/ProviderProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * 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. @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.android.internal.location; +package android.location; import android.annotation.IntDef; -import android.location.Criteria; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; @@ -29,18 +29,43 @@ import java.util.Objects; /** * Location provider properties. - * @hide */ public final class ProviderProperties implements Parcelable { + /** + * A constant indicating low power usage. + */ + public static final int POWER_USAGE_LOW = 1; + + /** + * A constant indicating a medium power usage. + */ + public static final int POWER_USAGE_MEDIUM = 2; + + /** + * A constant indicating high power usage. + */ + public static final int POWER_USAGE_HIGH = 3; + /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef({Criteria.POWER_LOW, Criteria.POWER_MEDIUM, Criteria.POWER_HIGH}) - public @interface PowerRequirement {} + @IntDef(prefix = "POWER_USAGE_", value = {POWER_USAGE_LOW, POWER_USAGE_MEDIUM, + POWER_USAGE_HIGH}) + public @interface PowerUsage {} + + /** + * A constant indicating a finer location accuracy. + */ + public static final int ACCURACY_FINE = 1; + + /** + * A constant indicating a coarser location accuracy. + */ + public static final int ACCURACY_COARSE = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef({Criteria.ACCURACY_FINE, Criteria.ACCURACY_COARSE}) + @IntDef(prefix = "ACCURACY_", value = {ACCURACY_FINE, ACCURACY_COARSE}) public @interface Accuracy {} private final boolean mHasNetworkRequirement; @@ -50,13 +75,16 @@ public final class ProviderProperties implements Parcelable { private final boolean mHasAltitudeSupport; private final boolean mHasSpeedSupport; private final boolean mHasBearingSupport; - private final @PowerRequirement int mPowerRequirement; + private final @PowerUsage int mPowerUsage; private final @Accuracy int mAccuracy; + /** + * @hide + */ public ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement, boolean hasCellRequirement, boolean hasMonetaryCost, boolean hasAltitudeSupport, boolean hasSpeedSupport, boolean hasBearingSupport, - @PowerRequirement int powerRequirement, @Accuracy int accuracy) { + @PowerUsage int powerUsage, @Accuracy int accuracy) { mHasNetworkRequirement = hasNetworkRequirement; mHasSatelliteRequirement = hasSatelliteRequirement; mHasCellRequirement = hasCellRequirement; @@ -64,10 +92,10 @@ public final class ProviderProperties implements Parcelable { mHasAltitudeSupport = hasAltitudeSupport; mHasSpeedSupport = hasSpeedSupport; mHasBearingSupport = hasBearingSupport; - mPowerRequirement = Preconditions.checkArgumentInRange(powerRequirement, Criteria.POWER_LOW, - Criteria.POWER_HIGH, "powerRequirement"); - mAccuracy = Preconditions.checkArgumentInRange(accuracy, Criteria.ACCURACY_FINE, - Criteria.ACCURACY_COARSE, "accuracy"); + mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW, + POWER_USAGE_HIGH, "powerUsage"); + mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE, + ACCURACY_COARSE, "locationAccuracy"); } /** @@ -121,22 +149,22 @@ public final class ProviderProperties implements Parcelable { } /** - * Power requirement for this provider. + * Power usage for this provider. */ - public @PowerRequirement int getPowerRequirement() { - return mPowerRequirement; + public @PowerUsage int getPowerUsage() { + return mPowerUsage; } /** - * Constant describing the horizontal accuracy returned - * by this provider. + * Rough location accuracy for this provider, primarily with respect to horizontal location + * accuracy. */ public @Accuracy int getAccuracy() { return mAccuracy; } - public static final Parcelable.Creator<ProviderProperties> CREATOR = - new Parcelable.Creator<ProviderProperties>() { + public static final @NonNull Creator<ProviderProperties> CREATOR = + new Creator<ProviderProperties>() { @Override public ProviderProperties createFromParcel(Parcel in) { return new ProviderProperties( @@ -147,7 +175,7 @@ public final class ProviderProperties implements Parcelable { /* hasAltitudeSupport= */ in.readBoolean(), /* hasSpeedSupport= */ in.readBoolean(), /* hasBearingSupport= */ in.readBoolean(), - /* powerRequirement= */ in.readInt(), + /* powerUsage= */ in.readInt(), /* accuracy= */ in.readInt()); } @@ -163,7 +191,7 @@ public final class ProviderProperties implements Parcelable { } @Override - public void writeToParcel(Parcel parcel, int flags) { + public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeBoolean(mHasNetworkRequirement); parcel.writeBoolean(mHasSatelliteRequirement); parcel.writeBoolean(mHasCellRequirement); @@ -171,7 +199,7 @@ public final class ProviderProperties implements Parcelable { parcel.writeBoolean(mHasAltitudeSupport); parcel.writeBoolean(mHasSpeedSupport); parcel.writeBoolean(mHasBearingSupport); - parcel.writeInt(mPowerRequirement); + parcel.writeInt(mPowerUsage); parcel.writeInt(mAccuracy); } @@ -191,7 +219,7 @@ public final class ProviderProperties implements Parcelable { && mHasAltitudeSupport == that.mHasAltitudeSupport && mHasSpeedSupport == that.mHasSpeedSupport && mHasBearingSupport == that.mHasBearingSupport - && mPowerRequirement == that.mPowerRequirement + && mPowerUsage == that.mPowerUsage && mAccuracy == that.mAccuracy; } @@ -199,13 +227,13 @@ public final class ProviderProperties implements Parcelable { public int hashCode() { return Objects.hash(mHasNetworkRequirement, mHasSatelliteRequirement, mHasCellRequirement, mHasMonetaryCost, mHasAltitudeSupport, mHasSpeedSupport, mHasBearingSupport, - mPowerRequirement, mAccuracy); + mPowerUsage, mAccuracy); } @Override public String toString() { StringBuilder b = new StringBuilder("ProviderProperties["); - b.append("power=").append(powerToString(mPowerRequirement)).append(", "); + b.append("power=").append(powerToString(mPowerUsage)).append(", "); b.append("accuracy=").append(accuracyToString(mAccuracy)); if (mHasNetworkRequirement || mHasSatelliteRequirement || mHasCellRequirement) { b.append(", requires="); @@ -226,42 +254,42 @@ public final class ProviderProperties implements Parcelable { if (mHasBearingSupport || mHasSpeedSupport || mHasAltitudeSupport) { b.append(", supports=["); if (mHasBearingSupport) { - b.append("bearing, "); + b.append("bearing,"); } if (mHasSpeedSupport) { - b.append("speed, "); + b.append("speed,"); } if (mHasAltitudeSupport) { - b.append("altitude, "); + b.append("altitude,"); } - b.setLength(b.length() - 2); + b.setLength(b.length() - 1); b.append("]"); } b.append("]"); return b.toString(); } - private static String powerToString(@PowerRequirement int power) { + private static String powerToString(@PowerUsage int power) { switch (power) { - case Criteria.POWER_LOW: + case POWER_USAGE_LOW: return "Low"; - case Criteria.POWER_MEDIUM: + case POWER_USAGE_MEDIUM: return "Medium"; - case Criteria.POWER_HIGH: + case POWER_USAGE_HIGH: return "High"; default: - return "???"; + throw new AssertionError(); } } private static String accuracyToString(@Accuracy int accuracy) { switch (accuracy) { - case Criteria.ACCURACY_COARSE: + case ACCURACY_COARSE: return "Coarse"; - case Criteria.ACCURACY_FINE: + case ACCURACY_FINE: return "Fine"; default: - return "???"; + throw new AssertionError(); } } } diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/com/android/internal/location/ILocationProviderManager.aidl index a74538b0334e..a5b22b2c07d3 100644 --- a/location/java/com/android/internal/location/ILocationProviderManager.aidl +++ b/location/java/com/android/internal/location/ILocationProviderManager.aidl @@ -17,17 +17,17 @@ package com.android.internal.location; import android.location.LocationResult; - -import com.android.internal.location.ProviderProperties; +import android.location.ProviderProperties; /** * Binder interface for manager of all location providers. * @hide */ interface ILocationProviderManager { - void onSetIdentity(@nullable String packageName, @nullable String attributionTag); + void onInitialize(boolean allowed, in ProviderProperties properties, @nullable String packageName, @nullable String attributionTag); void onSetAllowed(boolean allowed); void onSetProperties(in ProviderProperties properties); + void onReportLocation(in LocationResult locationResult); void onFlushComplete(); } diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java index 54d806671e86..47e425629783 100644 --- a/location/lib/java/com/android/location/provider/LocationProviderBase.java +++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java @@ -23,6 +23,7 @@ import android.location.Location; import android.location.LocationManager; import android.location.LocationProvider; import android.location.LocationResult; +import android.location.ProviderProperties; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.IBinder; @@ -35,7 +36,6 @@ import androidx.annotation.RequiresApi; import com.android.internal.location.ILocationProvider; import com.android.internal.location.ILocationProviderManager; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import java.io.FileDescriptor; @@ -372,11 +372,7 @@ public abstract class LocationProviderBase { public void setLocationProviderManager(ILocationProviderManager manager) { synchronized (mBinder) { try { - if (mPackageName != null || mAttributionTag != null) { - manager.onSetIdentity(mPackageName, mAttributionTag); - } - manager.onSetProperties(mProperties); - manager.onSetAllowed(mAllowed); + manager.onInitialize(mAllowed, mProperties, mPackageName, mAttributionTag); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (RuntimeException e) { diff --git a/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java b/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java index 21ee5f465c48..9d8ccdf62ca5 100644 --- a/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java +++ b/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java @@ -17,8 +17,7 @@ package com.android.location.provider; import android.annotation.NonNull; - -import com.android.internal.location.ProviderProperties; +import android.location.ProviderProperties; import java.util.Objects; diff --git a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java index f9f1607dfc95..2bda530b83d4 100644 --- a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java +++ b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java @@ -27,6 +27,7 @@ import android.location.Location; import android.location.LocationManager; import android.location.LocationRequest; import android.location.LocationResult; +import android.location.ProviderProperties; import android.os.ParcelFileDescriptor; import android.os.SystemClock; import android.os.WorkSource; @@ -37,7 +38,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.location.ILocationProvider; import com.android.internal.location.ILocationProviderManager; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.location.fused.FusedLocationProvider; @@ -153,7 +153,8 @@ public class FusedLocationServiceTest { } @Override - public void onSetIdentity(String packageName, String attributionTag) { + public void onInitialize(boolean allowed, ProviderProperties properties, String packageName, + String attributionTag) { } diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 9068287148b0..0de2ae24bad7 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -64,6 +64,7 @@ import android.location.LocationManagerInternal; import android.location.LocationProvider; import android.location.LocationRequest; import android.location.LocationTime; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.Bundle; @@ -80,7 +81,6 @@ import android.util.IndentingPrintWriter; import android.util.Log; import com.android.internal.annotations.GuardedBy; -import com.android.internal.location.ProviderProperties; import com.android.internal.util.DumpUtils; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; @@ -414,7 +414,7 @@ public class LocationManagerService extends ILocationManager.Stub { Boolean.parseBoolean(fragments[5]) /* supportsAltitude */, Boolean.parseBoolean(fragments[6]) /* supportsSpeed */, Boolean.parseBoolean(fragments[7]) /* supportsBearing */, - Integer.parseInt(fragments[8]) /* powerRequirement */, + Integer.parseInt(fragments[8]) /* powerUsage */, Integer.parseInt(fragments[9]) /* accuracy */); getOrAddLocationProviderManager(name).setMockProvider( new MockLocationProvider(properties, CallerIdentity.fromContext(mContext))); @@ -516,6 +516,11 @@ public class LocationManagerService extends ILocationManager.Stub { } @Override + public boolean hasProvider(String provider) { + return getLocationProviderManager(provider) != null; + } + + @Override public List<String> getAllProviders() { ArrayList<String> providers = new ArrayList<>(mProviderManagers.size()); for (LocationProviderManager manager : mProviderManagers) { @@ -944,11 +949,10 @@ public class LocationManagerService extends ILocationManager.Stub { } @Override - public ProviderProperties getProviderProperties(String providerName) { - LocationProviderManager manager = getLocationProviderManager(providerName); - if (manager == null) { - return null; - } + public ProviderProperties getProviderProperties(String provider) { + LocationProviderManager manager = getLocationProviderManager(provider); + Preconditions.checkArgument(manager != null, + "provider \"" + provider + "\" does not exist"); return manager.getProperties(); } 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 9e126673637f..a17a75d0f9dc 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -30,7 +30,6 @@ import android.content.IntentFilter; import android.database.ContentObserver; import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; -import android.location.Criteria; import android.location.FusedBatchOptions; import android.location.GnssAntennaInfo; import android.location.GnssMeasurementsEvent; @@ -43,6 +42,7 @@ import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationRequest; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.AsyncTask; import android.os.BatteryStats; @@ -72,7 +72,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.util.FrameworkStatsLog; @@ -113,8 +112,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements /* supportAltitude = */true, /* supportsSpeed = */true, /* supportsBearing = */true, - Criteria.POWER_HIGH, - Criteria.ACCURACY_FINE); + ProviderProperties.POWER_USAGE_HIGH, + ProviderProperties.ACCURACY_FINE); // these need to match GnssPositionMode enum in IGnss.hal private static final int GPS_POSITION_MODE_STANDALONE = 0; @@ -487,7 +486,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } public GnssLocationProvider(Context context, Injector injector) { - super(FgThread.getExecutor(), CallerIdentity.fromContext(context)); + super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES); mContext = context; @@ -544,7 +543,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mHandler.getLooper(), this); mGnssGeofenceProvider = new GnssGeofenceProvider(); - setProperties(PROPERTIES); setAllowed(true); } diff --git a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java index d06f54dd7a8a..5364feb67fa4 100644 --- a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java @@ -18,11 +18,11 @@ package com.android.server.location.provider; import android.annotation.Nullable; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.Bundle; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.util.Preconditions; @@ -90,7 +90,10 @@ public abstract class AbstractLocationProvider { this.identity = identity; } - State withAllowed(boolean allowed) { + /** + * Returns a state the same as the current but with allowed set as specified. + */ + public State withAllowed(boolean allowed) { if (allowed == this.allowed) { return this; } else { @@ -98,7 +101,10 @@ public abstract class AbstractLocationProvider { } } - State withProperties(@Nullable ProviderProperties properties) { + /** + * Returns a state the same as the current but with properties set as specified. + */ + public State withProperties(@Nullable ProviderProperties properties) { if (Objects.equals(properties, this.properties)) { return this; } else { @@ -106,7 +112,10 @@ public abstract class AbstractLocationProvider { } } - State withIdentity(@Nullable CallerIdentity identity) { + /** + * Returns a state the same as the current but with an identity set as specified. + */ + public State withIdentity(@Nullable CallerIdentity identity) { if (Objects.equals(identity, this.identity)) { return this; } else { @@ -175,28 +184,21 @@ public abstract class AbstractLocationProvider { private final LocationProviderController mController; - - /** - * See {@link #AbstractLocationProvider(Executor, CallerIdentity)}. - */ - protected AbstractLocationProvider(Executor executor) { - this(executor, null); - } - /** * Creates a new location provider. * * All callback methods will be invoked on the given executor. A direct executor may be provided * only if the provider can guarantee that all callback methods will never synchronously invoke - * any command method (that changes provider state, or reports a location, etc...). If this - * invariant is not held, use a normal executor or risk deadlock. + * any {@link LocationProviderController} methods. If this invariant is not held, use a normal + * executor or risk deadlock. * - * An optional identity may be provided to initialize the location provider. + * An optional identity and properties may be provided to initialize the location provider. */ - protected AbstractLocationProvider(Executor executor, CallerIdentity identity) { + protected AbstractLocationProvider(Executor executor, @Nullable CallerIdentity identity, + @Nullable ProviderProperties properties) { mExecutor = executor; - mInternalState = new AtomicReference<>( - new InternalState(null, State.EMPTY_STATE.withIdentity(identity))); + mInternalState = new AtomicReference<>(new InternalState(null, + State.EMPTY_STATE.withIdentity(identity).withProperties(properties))); mController = new Controller(); } @@ -209,46 +211,23 @@ public abstract class AbstractLocationProvider { return mController; } - /** - * Sets the state of the provider to the new state. - */ - protected void setState(State newState) { - InternalState oldInternalState = mInternalState.getAndUpdate( - internalState -> internalState.withState(newState)); - if (newState.equals(oldInternalState.state)) { - return; - } - - // we know that we only updated the state, so the listener for the old state is the same as - // the listener for the new state. - if (oldInternalState.listener != null) { - final long identity = Binder.clearCallingIdentity(); - try { - oldInternalState.listener.onStateChanged(oldInternalState.state, newState); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - } - - private void setState(UnaryOperator<State> operator) { - InternalState oldInternalState = mInternalState.getAndUpdate( - internalState -> internalState.withState(operator)); - - // recreate the new state from our knowledge of the old state - unfortunately may result in - // an extra allocation, but oh well... - State newState = operator.apply(oldInternalState.state); + protected void setState(UnaryOperator<State> operator) { + AtomicReference<State> oldStateRef = new AtomicReference<>(); + InternalState newInternalState = mInternalState.updateAndGet( + internalState -> { + oldStateRef.set(internalState.state); + return internalState.withState(operator); + }); + State oldState = oldStateRef.get(); - if (newState.equals(oldInternalState.state)) { + if (oldState.equals(newInternalState.state)) { return; } - // we know that we only updated the state, so the listener for the old state is the same as - // the listener for the new state. - if (oldInternalState.listener != null) { + if (newInternalState.listener != null) { final long identity = Binder.clearCallingIdentity(); try { - oldInternalState.listener.onStateChanged(oldInternalState.state, newState); + newInternalState.listener.onStateChanged(oldState, newInternalState.state); } finally { Binder.restoreCallingIdentity(identity); } @@ -279,7 +258,7 @@ public abstract class AbstractLocationProvider { /** * Call this method to report a change in provider properties. */ - protected void setProperties(ProviderProperties properties) { + protected void setProperties(@Nullable ProviderProperties properties) { setState(state -> state.withProperties(properties)); } @@ -293,7 +272,7 @@ public abstract class AbstractLocationProvider { /** * Call this method to report a change in provider packages. */ - protected void setIdentity(CallerIdentity identity) { + protected void setIdentity(@Nullable CallerIdentity identity) { setState(state -> state.withIdentity(identity)); } diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java index 2fe8bcc9140a..49cf6f85855d 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -46,7 +46,6 @@ import android.app.AlarmManager.OnAlarmListener; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.location.Criteria; import android.location.ILocationCallback; import android.location.ILocationListener; import android.location.LastLocationRequest; @@ -56,6 +55,7 @@ import android.location.LocationManagerInternal; import android.location.LocationManagerInternal.ProviderEnabledListener; import android.location.LocationRequest; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.Build; @@ -82,7 +82,6 @@ import android.util.SparseBooleanArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.util.Preconditions; import com.android.server.FgThread; @@ -452,7 +451,7 @@ public class LocationProviderManager extends return isActive() && getRequest().getIntervalMillis() < MAX_HIGH_POWER_INTERVAL_MS - && getProperties().getPowerRequirement() == Criteria.POWER_HIGH; + && getProperties().getPowerUsage() == ProviderProperties.POWER_USAGE_HIGH; } @GuardedBy("mLock") diff --git a/services/core/java/com/android/server/location/provider/MockLocationProvider.java b/services/core/java/com/android/server/location/provider/MockLocationProvider.java index 0c6d5dc44e2d..f9aa4020b522 100644 --- a/services/core/java/com/android/server/location/provider/MockLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/MockLocationProvider.java @@ -21,10 +21,10 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import android.annotation.Nullable; import android.location.Location; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Bundle; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import java.io.FileDescriptor; @@ -41,8 +41,7 @@ public class MockLocationProvider extends AbstractLocationProvider { public MockLocationProvider(ProviderProperties properties, CallerIdentity identity) { // using a direct executor is ok because this class has no locks that could deadlock - super(DIRECT_EXECUTOR, identity); - setProperties(properties); + super(DIRECT_EXECUTOR, identity, properties); } /** Sets the allowed state of this mock provider. */ diff --git a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java index 79f641f89ca0..c1b0abf64820 100644 --- a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java @@ -21,11 +21,11 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import android.annotation.Nullable; import android.location.Location; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Bundle; import com.android.internal.annotations.GuardedBy; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.util.Preconditions; @@ -75,7 +75,7 @@ public class MockableLocationProvider extends AbstractLocationProvider { public MockableLocationProvider(Object ownerLock) { // using a direct executor is acceptable because all inbound calls are delegated to the // actual provider implementations which will use their own executors - super(DIRECT_EXECUTOR); + super(DIRECT_EXECUTOR, null, null); mOwnerLock = ownerLock; mRequest = ProviderRequest.EMPTY_REQUEST; } @@ -167,7 +167,7 @@ public class MockableLocationProvider extends AbstractLocationProvider { newState = State.EMPTY_STATE; } - setState(newState); + setState(prevState -> newState); } /** @@ -325,7 +325,7 @@ public class MockableLocationProvider extends AbstractLocationProvider { return; } - setState(newState); + setState(prevState -> newState); } } diff --git a/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java b/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java index 0e8b40b3ef02..1f4c4cf2a0ac 100644 --- a/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java @@ -19,12 +19,11 @@ package com.android.server.location.provider; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import android.content.Context; -import android.location.Criteria; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Bundle; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import java.io.FileDescriptor; @@ -47,14 +46,12 @@ public class PassiveLocationProvider extends AbstractLocationProvider { /* supportsAltitude = */false, /* supportsSpeed = */false, /* supportsBearing = */false, - Criteria.POWER_LOW, - Criteria.ACCURACY_COARSE); + ProviderProperties.POWER_USAGE_LOW, + ProviderProperties.ACCURACY_COARSE); public PassiveLocationProvider(Context context) { // using a direct executor is ok because this class has no locks that could deadlock - super(DIRECT_EXECUTOR, CallerIdentity.fromContext(context)); - - setProperties(PROPERTIES); + super(DIRECT_EXECUTOR, CallerIdentity.fromContext(context), PROPERTIES); setAllowed(true); } diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java index 6e92c8da9fe3..345fdc00ff85 100644 --- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.Bundle; @@ -31,7 +32,6 @@ import android.os.RemoteException; import com.android.internal.annotations.GuardedBy; import com.android.internal.location.ILocationProvider; import com.android.internal.location.ILocationProviderManager; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.util.ArrayUtils; import com.android.server.ServiceWatcher; @@ -82,7 +82,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider { int nonOverlayPackageResId) { // safe to use direct executor since our locks are not acquired in a code path invoked by // our owning provider - super(DIRECT_EXECUTOR); + super(DIRECT_EXECUTOR, null, null); mContext = context; mServiceWatcher = new ServiceWatcher(context, action, this::onBind, @@ -116,7 +116,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider { synchronized (mLock) { mProxy = null; mService = null; - setState(State.EMPTY_STATE); + setState(prevState -> State.EMPTY_STATE); flushListeners = mFlushListeners.toArray(new Runnable[0]); mFlushListeners.clear(); } @@ -210,7 +210,8 @@ public class ProxyLocationProvider extends AbstractLocationProvider { // executed on binder thread @Override - public void onSetIdentity(@Nullable String packageName, @Nullable String attributionTag) { + public void onInitialize(boolean allowed, ProviderProperties properties, + @Nullable String packageName, @Nullable String attributionTag) { synchronized (mLock) { if (mProxy != this) { return; @@ -226,7 +227,10 @@ public class ProxyLocationProvider extends AbstractLocationProvider { identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); } - setIdentity(identity); + setState(prevState -> prevState + .withAllowed(allowed) + .withProperties(properties) + .withIdentity(identity)); } } @@ -238,14 +242,6 @@ public class ProxyLocationProvider extends AbstractLocationProvider { return; } - // if no identity is set yet, set it now - if (getIdentity() == null) { - String packageName = guessPackageName(mContext, Binder.getCallingUid(), - Objects.requireNonNull(mService).getPackageName()); - // unsafe is ok since the package is coming direct from the package manager here - setIdentity(CallerIdentity.fromBinderUnsafe(packageName, null)); - } - setProperties(properties); } } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java index 63b36fc68fcd..df7a445a068f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java @@ -66,6 +66,7 @@ import android.location.LocationManagerInternal; import android.location.LocationManagerInternal.ProviderEnabledListener; import android.location.LocationRequest; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.os.Bundle; import android.os.ICancellationSignal; @@ -80,7 +81,6 @@ import android.util.Log; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.server.FgThread; import com.android.server.LocalServices; @@ -1016,8 +1016,7 @@ public class LocationProviderManagerTest { private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>(); TestProvider(ProviderProperties properties, CallerIdentity identity) { - super(DIRECT_EXECUTOR, identity); - setProperties(properties); + super(DIRECT_EXECUTOR, identity, properties); } public void setProviderAllowed(boolean allowed) { diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java index bcf65d3c6c64..daa8a22ccebb 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java @@ -15,8 +15,6 @@ */ package com.android.server.location.provider; -import static androidx.test.ext.truth.location.LocationSubject.assertThat; - import static com.android.internal.location.ProviderRequest.EMPTY_REQUEST; import static com.google.common.truth.Truth.assertThat; @@ -29,13 +27,13 @@ import static org.testng.Assert.assertThrows; import android.location.Criteria; import android.location.Location; import android.location.LocationResult; +import android.location.ProviderProperties; import android.location.util.identity.CallerIdentity; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.server.location.test.FakeProvider; import com.android.server.location.test.ProviderListenerCapture; diff --git a/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java b/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java index 9266d6f81db2..1eb03862f09c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java @@ -40,7 +40,7 @@ public class FakeProvider extends AbstractLocationProvider { private final FakeProviderInterface mFakeInterface; public FakeProvider(FakeProviderInterface fakeInterface) { - super(Runnable::run); + super(Runnable::run, null, null); mFakeInterface = fakeInterface; } |