summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/hiddenapi-temp-blocklist.txt3
-rw-r--r--config/hiddenapi-unsupported.txt1
-rw-r--r--core/api/current.txt48
-rw-r--r--core/api/system-current.txt50
-rw-r--r--location/java/android/location/ILocationManager.aidl2
-rw-r--r--location/java/android/location/LocationManager.java32
-rw-r--r--location/java/android/location/LocationProvider.java14
-rw-r--r--location/java/android/location/provider/ILocationProvider.aidl (renamed from location/java/com/android/internal/location/ILocationProvider.aidl)15
-rw-r--r--location/java/android/location/provider/ILocationProviderManager.aidl (renamed from location/java/com/android/internal/location/ILocationProviderManager.aidl)4
-rw-r--r--location/java/android/location/provider/LocationProviderBase.java307
-rw-r--r--location/java/android/location/provider/ProviderProperties.aidl (renamed from location/java/android/location/ProviderProperties.aidl)2
-rw-r--r--location/java/android/location/provider/ProviderProperties.java (renamed from location/java/android/location/ProviderProperties.java)141
-rw-r--r--location/java/android/location/provider/ProviderRequest.aidl (renamed from location/java/com/android/internal/location/ProviderRequest.aidl)2
-rw-r--r--location/java/android/location/provider/ProviderRequest.java (renamed from location/java/com/android/internal/location/ProviderRequest.java)104
-rw-r--r--location/lib/api/current.txt30
-rw-r--r--location/lib/api/system-current.txt61
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardware.java80
-rw-r--r--location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java73
-rw-r--r--location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java89
-rw-r--r--location/lib/java/com/android/location/provider/LocationProviderBase.java17
-rw-r--r--location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java18
-rw-r--r--location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java3
-rw-r--r--packages/FusedLocation/AndroidManifest.xml2
-rw-r--r--packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java285
-rw-r--r--packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java20
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java36
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java25
-rw-r--r--services/core/java/com/android/server/location/injector/LocationEventLog.java2
-rw-r--r--services/core/java/com/android/server/location/provider/AbstractLocationProvider.java4
-rw-r--r--services/core/java/com/android/server/location/provider/LocationProviderController.java2
-rw-r--r--services/core/java/com/android/server/location/provider/LocationProviderManager.java4
-rw-r--r--services/core/java/com/android/server/location/provider/MockLocationProvider.java5
-rw-r--r--services/core/java/com/android/server/location/provider/MockableLocationProvider.java4
-rw-r--r--services/core/java/com/android/server/location/provider/PassiveLocationProvider.java22
-rw-r--r--services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java2
-rw-r--r--services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java12
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java27
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/provider/MockableLocationProviderTest.java27
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/test/FakeProvider.java2
39 files changed, 1206 insertions, 371 deletions
diff --git a/config/hiddenapi-temp-blocklist.txt b/config/hiddenapi-temp-blocklist.txt
index 246eeea35a19..753bc69be95b 100644
--- a/config/hiddenapi-temp-blocklist.txt
+++ b/config/hiddenapi-temp-blocklist.txt
@@ -47,9 +47,6 @@ Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
-Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
-Lcom/android/internal/location/ILocationProviderManager$Stub;-><init>()V
-Lcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProviderManager;
Lcom/android/internal/telephony/ITelephony$Stub;->DESCRIPTOR:Ljava/lang/String;
Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_dial:I
Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory;
diff --git a/config/hiddenapi-unsupported.txt b/config/hiddenapi-unsupported.txt
index 8a377ac051b0..90a526bcfaf7 100644
--- a/config/hiddenapi-unsupported.txt
+++ b/config/hiddenapi-unsupported.txt
@@ -269,7 +269,6 @@ Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
-Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
diff --git a/core/api/current.txt b/core/api/current.txt
index 29d4915a4953..7cb602775e6b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19320,6 +19320,7 @@ package android.location {
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.OnNmeaMessageListener);
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, @NonNull android.app.PendingIntent);
method public void addTestProvider(@NonNull String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+ method public void addTestProvider(@NonNull String, @NonNull android.location.provider.ProviderProperties);
method @Deprecated public void clearTestProviderEnabled(@NonNull String);
method @Deprecated public void clearTestProviderLocation(@NonNull String);
method @Deprecated public void clearTestProviderStatus(@NonNull String);
@@ -19334,7 +19335,7 @@ package android.location {
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 @Deprecated @Nullable public android.location.LocationProvider getProvider(@NonNull String);
- method @Nullable public android.location.ProviderProperties getProviderProperties(@NonNull String);
+ method @Nullable public android.location.provider.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);
@@ -19466,6 +19467,24 @@ package android.location {
method public void onNmeaMessage(String, long);
}
+ public abstract class SettingInjectorService extends android.app.Service {
+ ctor public SettingInjectorService(String);
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method protected abstract boolean onGetEnabled();
+ method protected abstract String onGetSummary();
+ method public final void onStart(android.content.Intent, int);
+ method public final int onStartCommand(android.content.Intent, int, int);
+ method public static final void refreshSettings(@NonNull android.content.Context);
+ field public static final String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
+ field public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+ field public static final String ATTRIBUTES_NAME = "injected-location-setting";
+ field public static final String META_DATA_NAME = "android.location.SettingInjectorService";
+ }
+
+}
+
+package android.location.provider {
+
public final class ProviderProperties implements android.os.Parcelable {
method public int describeContents();
method public int getAccuracy();
@@ -19480,24 +19499,25 @@ package android.location {
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 @NonNull public static final android.os.Parcelable.Creator<android.location.provider.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);
- method protected abstract boolean onGetEnabled();
- method protected abstract String onGetSummary();
- method public final void onStart(android.content.Intent, int);
- method public final int onStartCommand(android.content.Intent, int, int);
- method public static final void refreshSettings(@NonNull android.content.Context);
- field public static final String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
- field public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
- field public static final String ATTRIBUTES_NAME = "injected-location-setting";
- field public static final String META_DATA_NAME = "android.location.SettingInjectorService";
+ public static final class ProviderProperties.Builder {
+ ctor public ProviderProperties.Builder();
+ ctor public ProviderProperties.Builder(@NonNull android.location.provider.ProviderProperties);
+ method @NonNull public android.location.provider.ProviderProperties build();
+ method @NonNull public android.location.provider.ProviderProperties.Builder setAccuracy(int);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasAltitudeSupport(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasBearingSupport(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasCellRequirement(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasMonetaryCost(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasNetworkRequirement(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasSatelliteRequirement(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setHasSpeedSupport(boolean);
+ method @NonNull public android.location.provider.ProviderProperties.Builder setPowerUsage(int);
}
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1553214bc2eb..34c9af435265 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4375,6 +4375,56 @@ package android.location {
}
+package android.location.provider {
+
+ public abstract class LocationProviderBase {
+ ctor public LocationProviderBase(@NonNull android.content.Context, @NonNull String, @NonNull android.location.provider.ProviderProperties);
+ method @Nullable public final android.os.IBinder getBinder();
+ method @NonNull public android.location.provider.ProviderProperties getProperties();
+ method public boolean isAllowed();
+ method public abstract void onFlush(@NonNull android.location.provider.LocationProviderBase.OnFlushCompleteCallback);
+ method public abstract void onSendExtraCommand(@NonNull String, @Nullable android.os.Bundle);
+ method public abstract void onSetRequest(@NonNull android.location.provider.ProviderRequest);
+ method public void reportLocation(@NonNull android.location.Location);
+ method public void reportLocation(@NonNull android.location.LocationResult);
+ method public void setAllowed(boolean);
+ method public void setProperties(@NonNull android.location.provider.ProviderProperties);
+ field public static final String ACTION_FUSED_PROVIDER = "com.android.location.service.FusedLocationProvider";
+ field public static final String ACTION_NETWORK_PROVIDER = "com.android.location.service.v3.NetworkLocationProvider";
+ }
+
+ public static interface LocationProviderBase.OnFlushCompleteCallback {
+ method public void onFlushComplete();
+ }
+
+ public final class ProviderRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=0) public long getIntervalMillis();
+ method @IntRange(from=0) public long getMaxUpdateDelayMillis();
+ method public int getQuality();
+ method @NonNull public android.os.WorkSource getWorkSource();
+ method public boolean isActive();
+ method public boolean isLocationSettingsIgnored();
+ method public boolean isLowPower();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.location.provider.ProviderRequest> CREATOR;
+ field @NonNull public static final android.location.provider.ProviderRequest EMPTY_REQUEST;
+ field public static final long INTERVAL_DISABLED = 9223372036854775807L; // 0x7fffffffffffffffL
+ }
+
+ public static final class ProviderRequest.Builder {
+ ctor public ProviderRequest.Builder();
+ method @NonNull public android.location.provider.ProviderRequest build();
+ method @NonNull public android.location.provider.ProviderRequest.Builder setIntervalMillis(@IntRange(from=0) long);
+ method @NonNull public android.location.provider.ProviderRequest.Builder setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.provider.ProviderRequest.Builder setLowPower(boolean);
+ method @NonNull public android.location.provider.ProviderRequest.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
+ method @NonNull public android.location.provider.ProviderRequest.Builder setQuality(int);
+ method @NonNull public android.location.provider.ProviderRequest.Builder setWorkSource(@NonNull android.os.WorkSource);
+ }
+
+}
+
package android.media {
public final class AudioAttributes implements android.os.Parcelable {
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index c50904cad4e2..afae50203cd3 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -36,7 +36,7 @@ import android.location.LastLocationRequest;
import android.location.Location;
import android.location.LocationRequest;
import android.location.LocationTime;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
import android.os.Bundle;
import android.os.ICancellationSignal;
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 1d3e8ebaa0ab..2dc9eb44236f 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -49,6 +49,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
+import android.location.provider.ProviderProperties;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -1803,7 +1804,6 @@ public class LocationManager {
}
try {
-
ProviderProperties properties = mService.getProviderProperties(provider);
return new LocationProvider(provider, properties);
} catch (IllegalArgumentException e) {
@@ -1931,11 +1931,35 @@ public class LocationManager {
boolean supportsSpeed, boolean supportsBearing,
@ProviderProperties.PowerUsage int powerUsage,
@ProviderProperties.Accuracy int accuracy) {
+ addTestProvider(provider, new ProviderProperties.Builder()
+ .setHasNetworkRequirement(requiresNetwork)
+ .setHasSatelliteRequirement(requiresSatellite)
+ .setHasCellRequirement(requiresCell)
+ .setHasMonetaryCost(hasMonetaryCost)
+ .setHasAltitudeSupport(supportsAltitude)
+ .setHasSpeedSupport(supportsSpeed)
+ .setHasBearingSupport(supportsBearing)
+ .setPowerUsage(powerUsage)
+ .setAccuracy(accuracy)
+ .build());
+ }
+
+ /**
+ * Creates a test location provider and adds it to the set of active providers. This provider
+ * will replace any provider with the same name that exists prior to this call.
+ *
+ * @param provider the provider name
+ *
+ * @throws IllegalArgumentException if provider is null
+ * @throws IllegalArgumentException if properties is null
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
+ */
+ public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties) {
Preconditions.checkArgument(provider != null, "invalid null provider");
+ Preconditions.checkArgument(properties != null, "invalid null properties");
- ProviderProperties properties = new ProviderProperties(requiresNetwork,
- requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed,
- 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 6d2bfed99fb7..60b251ea990d 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -17,6 +17,7 @@
package android.location;
import android.annotation.Nullable;
+import android.location.provider.ProviderProperties;
/**
* Information about the properties of a location provider.
@@ -200,10 +201,8 @@ public class LocationProvider {
}
/**
- * Returns the power requirement for this provider.
- *
- * @return the power requirement for this provider, as one of the
- * constants ProviderProperties.POWER_USAGE_*.
+ * Returns the power requirement for this provider, one of the ProviderProperties.POWER_USAGE_*
+ * constants.
*/
public int getPowerRequirement() {
if (mProperties == null) {
@@ -214,11 +213,8 @@ public class LocationProvider {
}
/**
- * Returns a constant describing horizontal accuracy of this provider.
- * If the provider returns finer grain or exact location,
- * {@link ProviderProperties#ACCURACY_FINE} is returned, otherwise if the
- * location is only approximate then {@link ProviderProperties#ACCURACY_COARSE}
- * is returned.
+ * Returns the rough accuracy of this provider, one of the ProviderProperties.ACCURACY_*
+ * constants.
*/
public int getAccuracy() {
if (mProperties == null) {
diff --git a/location/java/com/android/internal/location/ILocationProvider.aidl b/location/java/android/location/provider/ILocationProvider.aidl
index dac08ff77938..f9995d5cf8b8 100644
--- a/location/java/com/android/internal/location/ILocationProvider.aidl
+++ b/location/java/android/location/provider/ILocationProvider.aidl
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package com.android.internal.location;
+package android.location.provider;
import android.os.Bundle;
-import android.os.WorkSource;
-import com.android.internal.location.ILocationProviderManager;
-import com.android.internal.location.ProviderRequest;
+import android.location.provider.ILocationProviderManager;
+import android.location.provider.ProviderRequest;
/**
* Binder interface for services that implement location providers. Do not implement this directly,
@@ -29,14 +28,8 @@ import com.android.internal.location.ProviderRequest;
*/
interface ILocationProvider {
- @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}")
oneway void setLocationProviderManager(in ILocationProviderManager manager);
-
- @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}")
- oneway void setRequest(in ProviderRequest request, in WorkSource ws);
-
+ oneway void setRequest(in ProviderRequest request);
oneway void flush();
-
- @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "{@code Do not use}")
oneway void sendExtraCommand(String command, in Bundle extras);
}
diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/android/location/provider/ILocationProviderManager.aidl
index a5b22b2c07d3..e3f51d9a23e1 100644
--- a/location/java/com/android/internal/location/ILocationProviderManager.aidl
+++ b/location/java/android/location/provider/ILocationProviderManager.aidl
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-package com.android.internal.location;
+package android.location.provider;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
/**
* Binder interface for manager of all location providers.
diff --git a/location/java/android/location/provider/LocationProviderBase.java b/location/java/android/location/provider/LocationProviderBase.java
new file mode 100644
index 000000000000..1306ea2c0204
--- /dev/null
+++ b/location/java/android/location/provider/LocationProviderBase.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2010 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.provider;
+
+import static android.location.Location.EXTRA_NO_GPS_LOCATION;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationResult;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * Base class for location providers outside the system server.
+ *
+ * Location providers should be wrapped in a non-exported service which returns the result of
+ * {@link #getBinder()} from the service's {@link android.app.Service#onBind(Intent)} method. The
+ * service should not be exported so that components other than the system server cannot bind to it.
+ * Alternatively, the service may be guarded by a permission that only system server can obtain. The
+ * service may specify metadata on its capabilities:
+ *
+ * <ul>
+ * <li>
+ * "serviceVersion": An integer version code to help tie break if multiple services are
+ * capable of implementing the same location provider. All else equal, the service with the
+ * highest version code will be chosen. Assumed to be 0 if not specified.
+ * </li>
+ * <li>
+ * "serviceIsMultiuser": A boolean property, indicating if the service wishes to take
+ * responsibility for handling changes to the current user on the device. If true, the
+ * service will always be bound from the system user. If false, the service will always be
+ * bound from the current user. If the current user changes, the old binding will be
+ * released, and a new binding established under the new user. Assumed to be false if not
+ * specified.
+ * </li>
+ * </ul>
+ *
+ * <p>The service should have an intent filter in place for the location provider it wishes to
+ * implements. Defaults for some providers are specified as constants in this class.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class LocationProviderBase {
+
+ /**
+ * Callback to be invoked when a flush operation is complete and all flushed locations have been
+ * reported.
+ */
+ public interface OnFlushCompleteCallback {
+
+ /**
+ * Should be invoked once the flush is complete.
+ */
+ void onFlushComplete();
+ }
+
+ /**
+ * The action the wrapping service should have in its intent filter to implement the
+ * {@link android.location.LocationManager#NETWORK_PROVIDER}.
+ */
+ @SuppressLint("ActionValue")
+ public static final String ACTION_NETWORK_PROVIDER =
+ "com.android.location.service.v3.NetworkLocationProvider";
+
+ /**
+ * The action the wrapping service should have in its intent filter to implement the
+ * {@link android.location.LocationManager#FUSED_PROVIDER}.
+ */
+ @SuppressLint("ActionValue")
+ public static final String ACTION_FUSED_PROVIDER =
+ "com.android.location.service.FusedLocationProvider";
+
+ private final String mTag;
+ private final @Nullable String mPackageName;
+ private final @Nullable String mAttributionTag;
+ private final IBinder mBinder;
+
+ // write locked on mBinder, read lock is optional depending on atomicity requirements
+ private @Nullable volatile ILocationProviderManager mManager;
+ private volatile ProviderProperties mProperties;
+ private volatile boolean mAllowed;
+
+ public LocationProviderBase(@NonNull Context context, @NonNull String tag,
+ @NonNull ProviderProperties properties) {
+ mTag = tag;
+ mPackageName = context.getPackageName();
+ mAttributionTag = context.getAttributionTag();
+ mBinder = new Service();
+
+ mManager = null;
+ mProperties = Objects.requireNonNull(properties);
+ mAllowed = true;
+ }
+
+ /**
+ * Returns the IBinder instance that should be returned from the
+ * {@link android.app.Service#onBind(Intent)} method of the wrapping service.
+ */
+ public final @Nullable IBinder getBinder() {
+ return mBinder;
+ }
+
+ /**
+ * Sets whether this provider is currently allowed or not. Note that this is specific to the
+ * provider only, and is unrelated to global location settings. This is a hint to the location
+ * manager that this provider will be unable to fulfill incoming requests. Setting a provider
+ * as not allowed will result in the provider being disabled. Setting a provider as allowed
+ * means that the provider may be in either the enabled or disabled state.
+ *
+ * <p>Some guidelines: providers should set their own allowed/disallowed status based only on
+ * state "owned" by that provider. For instance, providers should not take into account the
+ * state of the location master setting when setting themselves allowed or disallowed, as this
+ * state is not owned by a particular provider. If a provider requires some additional user
+ * consent that is particular to the provider, this should be use to set the allowed/disallowed
+ * state. If the provider proxies to another provider, the child provider's allowed/disallowed
+ * state should be taken into account in the parent's allowed state. For most providers, it is
+ * expected that they will be always allowed.
+ */
+ public void setAllowed(boolean allowed) {
+ synchronized (mBinder) {
+ if (mAllowed == allowed) {
+ return;
+ }
+
+ mAllowed = allowed;
+ }
+
+ ILocationProviderManager manager = mManager;
+ if (manager != null) {
+ try {
+ manager.onSetAllowed(mAllowed);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (RuntimeException e) {
+ Log.w(mTag, e);
+ }
+ }
+ }
+
+ /**
+ * Returns true if this provider is allowed. Providers start as allowed on construction.
+ */
+ public boolean isAllowed() {
+ return mAllowed;
+ }
+
+ /**
+ * Sets the provider properties that may be queried by clients. Generally speaking, providers
+ * should try to avoid changing their properties after construction.
+ */
+ public void setProperties(@NonNull ProviderProperties properties) {
+ synchronized (mBinder) {
+ mProperties = Objects.requireNonNull(properties);
+ }
+
+ ILocationProviderManager manager = mManager;
+ if (manager != null) {
+ try {
+ manager.onSetProperties(mProperties);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (RuntimeException e) {
+ Log.w(mTag, e);
+ }
+ }
+ }
+
+ /**
+ * Returns the currently set properties of the provider.
+ */
+ public @NonNull ProviderProperties getProperties() {
+ return mProperties;
+ }
+
+ /**
+ * Reports a new location from this provider.
+ */
+ public void reportLocation(@NonNull Location location) {
+ reportLocation(LocationResult.create(location));
+ }
+
+ /**
+ * Reports a new location result from this provider.
+ *
+ * <p>May only be used from Android S onwards.
+ */
+ public void reportLocation(@NonNull LocationResult locationResult) {
+ ILocationProviderManager manager = mManager;
+ if (manager != null) {
+ locationResult = locationResult.map(location -> {
+ // remove deprecated extras to save on serialization costs
+ Bundle extras = location.getExtras();
+ if (extras != null && (extras.containsKey(EXTRA_NO_GPS_LOCATION)
+ || extras.containsKey("coarseLocation"))) {
+ location = new Location(location);
+ extras = location.getExtras();
+ extras.remove(EXTRA_NO_GPS_LOCATION);
+ extras.remove("coarseLocation");
+ if (extras.isEmpty()) {
+ location.setExtras(null);
+ }
+ }
+ return location;
+ });
+
+ try {
+ manager.onReportLocation(locationResult);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (RuntimeException e) {
+ Log.w(mTag, e);
+ }
+ }
+ }
+
+ /**
+ * Set the current {@link ProviderRequest} for this provider. Each call to this method overrides
+ * any prior ProviderRequests. The provider should immediately attempt to provide locations (or
+ * not provide locations) according to the parameters of the provider request.
+ */
+ public abstract void onSetRequest(@NonNull ProviderRequest request);
+
+ /**
+ * Requests a flush of any pending batched locations. The callback must always be invoked once
+ * per invocation, and should be invoked after {@link #reportLocation(LocationResult)} has been
+ * invoked with any flushed locations. The callback may be invoked immediately if no locations
+ * are flushed.
+ */
+ public abstract void onFlush(@NonNull OnFlushCompleteCallback callback);
+
+ /**
+ * Implements optional custom commands.
+ */
+ public abstract void onSendExtraCommand(@NonNull String command, @Nullable Bundle extras);
+
+ private final class Service extends ILocationProvider.Stub {
+
+ Service() {}
+
+ @Override
+ public void setLocationProviderManager(ILocationProviderManager manager) {
+ synchronized (mBinder) {
+ try {
+ manager.onInitialize(mAllowed, mProperties, mPackageName, mAttributionTag);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (RuntimeException e) {
+ Log.w(mTag, e);
+ }
+
+ mManager = manager;
+ }
+ }
+
+ @Override
+ public void setRequest(ProviderRequest request) {
+ onSetRequest(request);
+ }
+
+ @Override
+ public void flush() {
+ onFlush(this::onFlushComplete);
+ }
+
+ private void onFlushComplete() {
+ ILocationProviderManager manager = mManager;
+ if (manager != null) {
+ try {
+ manager.onFlushComplete();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } catch (RuntimeException e) {
+ Log.w(mTag, e);
+ }
+ }
+ }
+
+ @Override
+ public void sendExtraCommand(String command, Bundle extras) {
+ onSendExtraCommand(command, extras);
+ }
+ }
+}
diff --git a/location/java/android/location/ProviderProperties.aidl b/location/java/android/location/provider/ProviderProperties.aidl
index 8b1d79f90233..fd5a614b4fc8 100644
--- a/location/java/android/location/ProviderProperties.aidl
+++ b/location/java/android/location/provider/ProviderProperties.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.location;
+package android.location.provider;
parcelable ProviderProperties;
diff --git a/location/java/android/location/ProviderProperties.java b/location/java/android/location/provider/ProviderProperties.java
index 8fa8c984b172..793401251de8 100644
--- a/location/java/android/location/ProviderProperties.java
+++ b/location/java/android/location/provider/ProviderProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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,7 +14,7 @@
* limitations under the License.
*/
-package android.location;
+package android.location.provider;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -78,10 +78,7 @@ public final class ProviderProperties implements Parcelable {
private final @PowerUsage int mPowerUsage;
private final @Accuracy int mAccuracy;
- /**
- * @hide
- */
- public ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement,
+ private ProviderProperties(boolean hasNetworkRequirement, boolean hasSatelliteRequirement,
boolean hasCellRequirement, boolean hasMonetaryCost, boolean hasAltitudeSupport,
boolean hasSpeedSupport, boolean hasBearingSupport,
@PowerUsage int powerUsage, @Accuracy int accuracy) {
@@ -92,10 +89,8 @@ public final class ProviderProperties implements Parcelable {
mHasAltitudeSupport = hasAltitudeSupport;
mHasSpeedSupport = hasSpeedSupport;
mHasBearingSupport = hasBearingSupport;
- mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW,
- POWER_USAGE_HIGH, "powerUsage");
- mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE,
- ACCURACY_COARSE, "locationAccuracy");
+ mPowerUsage = powerUsage;
+ mAccuracy = accuracy;
}
/**
@@ -233,7 +228,7 @@ public final class ProviderProperties implements Parcelable {
@Override
public String toString() {
StringBuilder b = new StringBuilder("ProviderProperties[");
- b.append("power=").append(powerToString(mPowerUsage)).append(", ");
+ b.append("powerUsage=").append(powerToString(mPowerUsage)).append(", ");
b.append("accuracy=").append(accuracyToString(mAccuracy));
if (mHasNetworkRequirement || mHasSatelliteRequirement || mHasCellRequirement) {
b.append(", requires=");
@@ -292,4 +287,128 @@ public final class ProviderProperties implements Parcelable {
throw new AssertionError();
}
}
+
+ /**
+ * Builder for ProviderProperties.
+ */
+ public static final class Builder {
+
+ private boolean mHasNetworkRequirement;
+ private boolean mHasSatelliteRequirement;
+ private boolean mHasCellRequirement;
+ private boolean mHasMonetaryCost;
+ private boolean mHasAltitudeSupport;
+ private boolean mHasSpeedSupport;
+ private boolean mHasBearingSupport;
+ private @PowerUsage int mPowerUsage;
+ private @Accuracy int mAccuracy;
+
+ public Builder() {
+ mHasNetworkRequirement = false;
+ mHasSatelliteRequirement = false;
+ mHasCellRequirement = false;
+ mHasMonetaryCost = false;
+ mHasAltitudeSupport = false;
+ mHasSpeedSupport = false;
+ mHasBearingSupport = false;
+ mPowerUsage = POWER_USAGE_HIGH;
+ mAccuracy = ACCURACY_COARSE;
+ }
+
+ public Builder(@NonNull ProviderProperties providerProperties) {
+ mHasNetworkRequirement = providerProperties.mHasNetworkRequirement;
+ mHasSatelliteRequirement = providerProperties.mHasSatelliteRequirement;
+ mHasCellRequirement = providerProperties.mHasCellRequirement;
+ mHasMonetaryCost = providerProperties.mHasMonetaryCost;
+ mHasAltitudeSupport = providerProperties.mHasAltitudeSupport;
+ mHasSpeedSupport = providerProperties.mHasSpeedSupport;
+ mHasBearingSupport = providerProperties.mHasBearingSupport;
+ mPowerUsage = providerProperties.mPowerUsage;
+ mAccuracy = providerProperties.mAccuracy;
+ }
+
+ /**
+ * Sets whether a provider requires network access. False by default.
+ */
+ public @NonNull Builder setHasNetworkRequirement(boolean requiresNetwork) {
+ mHasNetworkRequirement = requiresNetwork;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider requires satellite access. False by default.
+ */
+ public @NonNull Builder setHasSatelliteRequirement(boolean requiresSatellite) {
+ mHasSatelliteRequirement = requiresSatellite;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider requires cell tower access. False by default.
+ */
+ public @NonNull Builder setHasCellRequirement(boolean requiresCell) {
+ mHasCellRequirement = requiresCell;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider has a monetary cost. False by default.
+ */
+ public @NonNull Builder setHasMonetaryCost(boolean monetaryCost) {
+ mHasMonetaryCost = monetaryCost;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider can provide altitude information. False by default.
+ */
+ public @NonNull Builder setHasAltitudeSupport(boolean supportsAltitude) {
+ mHasAltitudeSupport = supportsAltitude;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider can provide speed information. False by default.
+ */
+ public @NonNull Builder setHasSpeedSupport(boolean supportsSpeed) {
+ mHasSpeedSupport = supportsSpeed;
+ return this;
+ }
+
+ /**
+ * Sets whether a provider can provide bearing information. False by default.
+ */
+ public @NonNull Builder setHasBearingSupport(boolean supportsBearing) {
+ mHasBearingSupport = supportsBearing;
+ return this;
+ }
+
+ /**
+ * Sets a very rough bucket of provider power usage. {@link #POWER_USAGE_HIGH} by default.
+ */
+ public @NonNull Builder setPowerUsage(@PowerUsage int powerUsage) {
+ mPowerUsage = Preconditions.checkArgumentInRange(powerUsage, POWER_USAGE_LOW,
+ POWER_USAGE_HIGH, "powerUsage");
+ return this;
+ }
+
+ /**
+ * Sets a very rough bucket of provider location accuracy. {@link #ACCURACY_COARSE} by
+ * default.
+ */
+ public @NonNull Builder setAccuracy(@Accuracy int accuracy) {
+ mAccuracy = Preconditions.checkArgumentInRange(accuracy, ACCURACY_FINE,
+ ACCURACY_COARSE, "accuracy");
+ return this;
+ }
+
+ /**
+ * Builds a new ProviderProperties.
+ */
+ public @NonNull ProviderProperties build() {
+ return new ProviderProperties(mHasNetworkRequirement, mHasSatelliteRequirement,
+ mHasCellRequirement, mHasMonetaryCost, mHasAltitudeSupport, mHasSpeedSupport,
+ mHasBearingSupport, mPowerUsage, mAccuracy);
+ }
+ }
}
diff --git a/location/java/com/android/internal/location/ProviderRequest.aidl b/location/java/android/location/provider/ProviderRequest.aidl
index 4e1ea955c2e5..b98f3018fe2b 100644
--- a/location/java/com/android/internal/location/ProviderRequest.aidl
+++ b/location/java/android/location/provider/ProviderRequest.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package com.android.internal.location;
+package android.location.provider;
parcelable ProviderRequest;
diff --git a/location/java/com/android/internal/location/ProviderRequest.java b/location/java/android/location/provider/ProviderRequest.java
index 545ea528826b..e543b040a2d4 100644
--- a/location/java/com/android/internal/location/ProviderRequest.java
+++ b/location/java/android/location/provider/ProviderRequest.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,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.location;
+package android.location.provider;
import static android.location.LocationRequest.QUALITY_BALANCED_POWER_ACCURACY;
import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY;
@@ -22,10 +22,9 @@ import static android.location.LocationRequest.QUALITY_LOW_POWER;
import android.annotation.IntRange;
import android.annotation.NonNull;
-import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
import android.location.LocationRequest;
import android.location.LocationRequest.Quality;
-import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.WorkSource;
@@ -33,34 +32,25 @@ import android.util.TimeUtils;
import com.android.internal.util.Preconditions;
-import java.util.Collections;
-import java.util.List;
import java.util.Objects;
/**
* Location provider request.
* @hide
*/
+@SystemApi
public final class ProviderRequest implements Parcelable {
public static final long INTERVAL_DISABLED = Long.MAX_VALUE;
- public static final ProviderRequest EMPTY_REQUEST = new ProviderRequest(
+ public static final @NonNull ProviderRequest EMPTY_REQUEST = new ProviderRequest(
INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, 0, false, false, new WorkSource());
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link "
- + "ProviderRequest}")
- public final boolean reportLocation;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link "
- + "ProviderRequest}")
- public final long interval;
+ private final long mIntervalMillis;
private final @Quality int mQuality;
private final long mMaxUpdateDelayMillis;
private final boolean mLowPower;
private final boolean mLocationSettingsIgnored;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "{@link "
- + "ProviderRequest}")
- public final List<LocationRequest> locationRequests;
private final WorkSource mWorkSource;
private ProviderRequest(
@@ -70,22 +60,11 @@ public final class ProviderRequest implements Parcelable {
boolean lowPower,
boolean locationSettingsIgnored,
@NonNull WorkSource workSource) {
- reportLocation = intervalMillis != INTERVAL_DISABLED;
- interval = intervalMillis;
+ mIntervalMillis = intervalMillis;
mQuality = quality;
mMaxUpdateDelayMillis = maxUpdateDelayMillis;
mLowPower = lowPower;
mLocationSettingsIgnored = locationSettingsIgnored;
- if (intervalMillis != INTERVAL_DISABLED) {
- locationRequests = Collections.singletonList(new LocationRequest.Builder(intervalMillis)
- .setQuality(quality)
- .setLowPower(lowPower)
- .setLocationSettingsIgnored(locationSettingsIgnored)
- .setWorkSource(workSource)
- .build());
- } else {
- locationRequests = Collections.emptyList();
- }
mWorkSource = Objects.requireNonNull(workSource);
}
@@ -94,7 +73,7 @@ public final class ProviderRequest implements Parcelable {
* request is inactive and does not require any locations to be reported.
*/
public boolean isActive() {
- return interval != INTERVAL_DISABLED;
+ return mIntervalMillis != INTERVAL_DISABLED;
}
/**
@@ -102,7 +81,7 @@ public final class ProviderRequest implements Parcelable {
* {@link #INTERVAL_DISABLED} for an inactive request.
*/
public @IntRange(from = 0) long getIntervalMillis() {
- return interval;
+ return mIntervalMillis;
}
/**
@@ -148,29 +127,28 @@ public final class ProviderRequest implements Parcelable {
return mWorkSource;
}
- public static final Parcelable.Creator<ProviderRequest> CREATOR =
- new Parcelable.Creator<ProviderRequest>() {
- @Override
- public ProviderRequest createFromParcel(Parcel in) {
- long intervalMillis = in.readLong();
- if (intervalMillis == INTERVAL_DISABLED) {
- return EMPTY_REQUEST;
- } else {
- return new ProviderRequest(
- intervalMillis,
- /* quality= */ in.readInt(),
- /* maxUpdateDelayMillis= */ in.readLong(),
- /* lowPower= */ in.readBoolean(),
- /* locationSettingsIgnored= */ in.readBoolean(),
- /* workSource= */ in.readTypedObject(WorkSource.CREATOR));
- }
- }
+ public static final @NonNull Creator<ProviderRequest> CREATOR = new Creator<ProviderRequest>() {
+ @Override
+ public ProviderRequest createFromParcel(Parcel in) {
+ long intervalMillis = in.readLong();
+ if (intervalMillis == INTERVAL_DISABLED) {
+ return EMPTY_REQUEST;
+ } else {
+ return new ProviderRequest(
+ intervalMillis,
+ /* quality= */ in.readInt(),
+ /* maxUpdateDelayMillis= */ in.readLong(),
+ /* lowPower= */ in.readBoolean(),
+ /* locationSettingsIgnored= */ in.readBoolean(),
+ /* workSource= */ in.readTypedObject(WorkSource.CREATOR));
+ }
+ }
- @Override
- public ProviderRequest[] newArray(int size) {
- return new ProviderRequest[size];
- }
- };
+ @Override
+ public ProviderRequest[] newArray(int size) {
+ return new ProviderRequest[size];
+ }
+ };
@Override
public int describeContents() {
@@ -178,9 +156,9 @@ public final class ProviderRequest implements Parcelable {
}
@Override
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeLong(interval);
- if (interval != INTERVAL_DISABLED) {
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeLong(mIntervalMillis);
+ if (mIntervalMillis != INTERVAL_DISABLED) {
parcel.writeInt(mQuality);
parcel.writeLong(mMaxUpdateDelayMillis);
parcel.writeBoolean(mLowPower);
@@ -199,10 +177,10 @@ public final class ProviderRequest implements Parcelable {
}
ProviderRequest that = (ProviderRequest) o;
- if (interval == INTERVAL_DISABLED) {
- return that.interval == INTERVAL_DISABLED;
+ if (mIntervalMillis == INTERVAL_DISABLED) {
+ return that.mIntervalMillis == INTERVAL_DISABLED;
} else {
- return interval == that.interval
+ return mIntervalMillis == that.mIntervalMillis
&& mQuality == that.mQuality
&& mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis
&& mLowPower == that.mLowPower
@@ -213,16 +191,16 @@ public final class ProviderRequest implements Parcelable {
@Override
public int hashCode() {
- return Objects.hash(interval, mQuality, mWorkSource);
+ return Objects.hash(mIntervalMillis, mQuality, mWorkSource);
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
s.append("ProviderRequest[");
- if (interval != INTERVAL_DISABLED) {
+ if (mIntervalMillis != INTERVAL_DISABLED) {
s.append("@");
- TimeUtils.formatDuration(interval, s);
+ TimeUtils.formatDuration(mIntervalMillis, s);
if (mQuality != QUALITY_BALANCED_POWER_ACCURACY) {
if (mQuality == QUALITY_HIGH_ACCURACY) {
s.append(", HIGH_ACCURACY");
@@ -230,7 +208,7 @@ public final class ProviderRequest implements Parcelable {
s.append(", LOW_POWER");
}
}
- if (mMaxUpdateDelayMillis / 2 > interval) {
+ if (mMaxUpdateDelayMillis / 2 > mIntervalMillis) {
s.append(", maxUpdateDelay=");
TimeUtils.formatDuration(mMaxUpdateDelayMillis, s);
}
@@ -253,7 +231,7 @@ public final class ProviderRequest implements Parcelable {
/**
* A Builder for {@link ProviderRequest}s.
*/
- public static class Builder {
+ public static final class Builder {
private long mIntervalMillis = INTERVAL_DISABLED;
private int mQuality = QUALITY_BALANCED_POWER_ACCURACY;
private long mMaxUpdateDelayMillis = 0;
diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt
index 4e13487759ed..338d7ccd6c91 100644
--- a/location/lib/api/current.txt
+++ b/location/lib/api/current.txt
@@ -6,33 +6,33 @@ package com.android.location.provider {
method @Deprecated public android.os.IBinder getBinder();
}
- public abstract class LocationProviderBase {
+ @Deprecated public abstract class LocationProviderBase {
ctor @Deprecated public LocationProviderBase(String, com.android.location.provider.ProviderPropertiesUnbundled);
- ctor @RequiresApi(android.os.Build.VERSION_CODES.R) public LocationProviderBase(android.content.Context, String, com.android.location.provider.ProviderPropertiesUnbundled);
- method public android.os.IBinder getBinder();
- method @RequiresApi(android.os.Build.VERSION_CODES.R) public boolean isAllowed();
+ ctor @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.R) public LocationProviderBase(android.content.Context, String, com.android.location.provider.ProviderPropertiesUnbundled);
+ method @Deprecated public android.os.IBinder getBinder();
+ method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.R) public boolean isAllowed();
method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.Q) public boolean isEnabled();
method @Deprecated protected void onDisable();
method @Deprecated protected void onDump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
method @Deprecated protected void onEnable();
- method protected void onFlush(com.android.location.provider.LocationProviderBase.OnFlushCompleteCallback);
+ method @Deprecated protected void onFlush(com.android.location.provider.LocationProviderBase.OnFlushCompleteCallback);
method @Deprecated protected int onGetStatus(android.os.Bundle);
method @Deprecated protected long onGetStatusUpdateTime();
- method protected void onInit();
- method protected boolean onSendExtraCommand(@Nullable String, @Nullable android.os.Bundle);
- method protected abstract void onSetRequest(com.android.location.provider.ProviderRequestUnbundled, android.os.WorkSource);
- method public void reportLocation(android.location.Location);
- method public void reportLocation(android.location.LocationResult);
+ method @Deprecated protected void onInit();
+ method @Deprecated protected boolean onSendExtraCommand(@Nullable String, @Nullable android.os.Bundle);
+ method @Deprecated protected abstract void onSetRequest(com.android.location.provider.ProviderRequestUnbundled, android.os.WorkSource);
+ method @Deprecated public void reportLocation(android.location.Location);
+ method @Deprecated public void reportLocation(android.location.LocationResult);
method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setAdditionalProviderPackages(java.util.List<java.lang.String>);
- method @RequiresApi(android.os.Build.VERSION_CODES.R) public void setAllowed(boolean);
+ method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.R) public void setAllowed(boolean);
method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setEnabled(boolean);
- method @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
+ method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
- field public static final String FUSED_PROVIDER = "fused";
+ field @Deprecated public static final String FUSED_PROVIDER = "fused";
}
- protected static interface LocationProviderBase.OnFlushCompleteCallback {
- method public void onFlushComplete();
+ @Deprecated protected static interface LocationProviderBase.OnFlushCompleteCallback {
+ method @Deprecated public void onFlushComplete();
}
@Deprecated public final class LocationRequestUnbundled {
diff --git a/location/lib/api/system-current.txt b/location/lib/api/system-current.txt
index d802177e249b..7046abd8fd3b 100644
--- a/location/lib/api/system-current.txt
+++ b/location/lib/api/system-current.txt
@@ -1 +1,62 @@
// Signature format: 2.0
+package com.android.location.provider {
+
+ @Deprecated public final class FusedLocationHardware {
+ method @Deprecated public void flushBatchedLocations();
+ method @Deprecated public int getSupportedBatchSize();
+ method @Deprecated public int getVersion();
+ method @Deprecated public void injectDeviceContext(int);
+ method @Deprecated public void injectDiagnosticData(String);
+ method @Deprecated public void registerSink(com.android.location.provider.FusedLocationHardwareSink, android.os.Looper);
+ method @Deprecated public void requestBatchOfLocations(int);
+ method @Deprecated public void startBatching(int, com.android.location.provider.GmsFusedBatchOptions);
+ method @Deprecated public void stopBatching(int);
+ method @Deprecated public boolean supportsDeviceContextInjection();
+ method @Deprecated public boolean supportsDiagnosticDataInjection();
+ method @Deprecated public void unregisterSink(com.android.location.provider.FusedLocationHardwareSink);
+ method @Deprecated public void updateBatchingOptions(int, com.android.location.provider.GmsFusedBatchOptions);
+ }
+
+ @Deprecated public class FusedLocationHardwareSink {
+ ctor @Deprecated public FusedLocationHardwareSink();
+ method @Deprecated public void onCapabilities(int);
+ method @Deprecated public void onDiagnosticDataAvailable(String);
+ method @Deprecated public void onLocationAvailable(android.location.Location[]);
+ method @Deprecated public void onStatusChanged(int);
+ }
+
+ @Deprecated public class GmsFusedBatchOptions {
+ ctor @Deprecated public GmsFusedBatchOptions();
+ method @Deprecated public int getFlags();
+ method @Deprecated public double getMaxPowerAllocationInMW();
+ method @Deprecated public long getPeriodInNS();
+ method @Deprecated public float getSmallestDisplacementMeters();
+ method @Deprecated public int getSourcesToUse();
+ method @Deprecated public boolean isFlagSet(int);
+ method @Deprecated public boolean isSourceToUseSet(int);
+ method @Deprecated public void resetFlag(int);
+ method @Deprecated public void resetSourceToUse(int);
+ method @Deprecated public void setFlag(int);
+ method @Deprecated public void setMaxPowerAllocationInMW(double);
+ method @Deprecated public void setPeriodInNS(long);
+ method @Deprecated public void setSmallestDisplacementMeters(float);
+ method @Deprecated public void setSourceToUse(int);
+ }
+
+ @Deprecated public static final class GmsFusedBatchOptions.BatchFlags {
+ ctor @Deprecated public GmsFusedBatchOptions.BatchFlags();
+ field @Deprecated public static int CALLBACK_ON_LOCATION_FIX;
+ field @Deprecated public static int WAKEUP_ON_FIFO_FULL;
+ }
+
+ @Deprecated public static final class GmsFusedBatchOptions.SourceTechnologies {
+ ctor @Deprecated public GmsFusedBatchOptions.SourceTechnologies();
+ field @Deprecated public static int BLUETOOTH;
+ field @Deprecated public static int CELL;
+ field @Deprecated public static int GNSS;
+ field @Deprecated public static int SENSORS;
+ field @Deprecated public static int WIFI;
+ }
+
+}
+
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardware.java b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
new file mode 100644
index 000000000000..3d323867f026
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardware.java
@@ -0,0 +1,80 @@
+/*
+ * 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.location.provider;
+
+import android.annotation.SystemApi;
+import android.os.Looper;
+
+/**
+ * Class that exposes IFusedLocationHardware functionality to unbundled services.
+ *
+ * @deprecated This class may no longer be used from Android P and onwards.
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public final class FusedLocationHardware {
+
+ private FusedLocationHardware() {}
+
+ /*
+ * Methods to provide a Facade for IFusedLocationHardware
+ */
+ public void registerSink(FusedLocationHardwareSink sink, Looper looper) {}
+
+ public void unregisterSink(FusedLocationHardwareSink sink) {}
+
+ public int getSupportedBatchSize() {
+ return 0;
+ }
+
+ public void startBatching(int id, GmsFusedBatchOptions batchOptions) {}
+
+ public void stopBatching(int id) {}
+
+ public void updateBatchingOptions(int id, GmsFusedBatchOptions batchOptions) {}
+
+ public void requestBatchOfLocations(int batchSizeRequest) {}
+
+ public void flushBatchedLocations() {}
+
+ public boolean supportsDiagnosticDataInjection() {
+ return false;
+ }
+
+ public void injectDiagnosticData(String data) {}
+
+ public boolean supportsDeviceContextInjection() {
+ return false;
+ }
+
+ public void injectDeviceContext(int deviceEnabledContext) {}
+
+ /**
+ * Returns the version of the FLP HAL.
+ *
+ * <p>Version 1 is the initial release.
+ * <p>Version 2 adds the ability to use {@link #flushBatchedLocations},
+ * {@link FusedLocationHardwareSink#onCapabilities}, and
+ * {@link FusedLocationHardwareSink#onStatusChanged}.
+ *
+ * <p>This method is only available on API 23 or later. Older APIs have version 1.
+ */
+ public int getVersion() {
+ return 1;
+ }
+}
diff --git a/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
new file mode 100644
index 000000000000..30bb1b3a5476
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/FusedLocationHardwareSink.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.location.provider;
+
+import android.annotation.SystemApi;
+import android.location.Location;
+
+/**
+ * Base class for sinks to interact with FusedLocationHardware.
+ *
+ * <p>Default implementations allow new methods to be added without crashing
+ * clients compiled against an old library version.
+ *
+ * @deprecated This class may no longer be used from Android P and onwards.
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class FusedLocationHardwareSink {
+ /**
+ * Called when one or more locations are available from the FLP
+ * HAL.
+ */
+ public void onLocationAvailable(Location[] locations) {
+ // default do nothing
+ }
+
+ /**
+ * Called when diagnostic data is available from the FLP HAL.
+ */
+ public void onDiagnosticDataAvailable(String data) {
+ // default do nothing
+ }
+
+ /**
+ * Called when capabilities are available from the FLP HAL.
+ * Should be called once right after initialization.
+ *
+ * @param capabilities A bitmask of capabilities defined in
+ * fused_location.h.
+ */
+ public void onCapabilities(int capabilities) {
+ // default do nothing
+ }
+
+ /**
+ * Called when the status changes in the underlying FLP HAL
+ * implementation (the ability to compute location). This
+ * callback will only be made on version 2 or later
+ * (see {@link FusedLocationHardware#getVersion()}).
+ *
+ * @param status One of FLP_STATUS_LOCATION_AVAILABLE or
+ * FLP_STATUS_LOCATION_UNAVAILABLE as defined in
+ * fused_location.h.
+ */
+ public void onStatusChanged(int status) {
+ // default do nothing
+ }
+}
diff --git a/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java b/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java
new file mode 100644
index 000000000000..3647377fdcdf
--- /dev/null
+++ b/location/lib/java/com/android/location/provider/GmsFusedBatchOptions.java
@@ -0,0 +1,89 @@
+/*
+ * 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.location.provider;
+
+import android.annotation.SystemApi;
+
+/**
+ * Class that exposes FusedBatchOptions to the GmsCore.
+ *
+ * @deprecated This class may no longer be used from Android P and onwards.
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GmsFusedBatchOptions {
+
+ public void setMaxPowerAllocationInMW(double value) {}
+
+ public double getMaxPowerAllocationInMW() {
+ return 0;
+ }
+
+ public void setPeriodInNS(long value) {}
+
+ public long getPeriodInNS() {
+ return 0;
+ }
+
+ public void setSmallestDisplacementMeters(float value) {}
+
+ public float getSmallestDisplacementMeters() {
+ return 0;
+ }
+
+ public void setSourceToUse(int source) {}
+
+ public void resetSourceToUse(int source) {}
+
+ public boolean isSourceToUseSet(int source) {
+ return false;
+ }
+
+ public int getSourcesToUse() {
+ return 0;
+ }
+
+ public void setFlag(int flag) {}
+
+ public void resetFlag(int flag) {}
+
+ public boolean isFlagSet(int flag) {
+ return false;
+ }
+
+ public int getFlags() {
+ return 0;
+ }
+
+ /**
+ * Definition of enum flag sets needed by this class.
+ * Such values need to be kept in sync with the ones in fused_location.h
+ */
+ public static final class SourceTechnologies {
+ public static int GNSS = 1 << 0;
+ public static int WIFI = 1 << 1;
+ public static int SENSORS = 1 << 2;
+ public static int CELL = 1 << 3;
+ public static int BLUETOOTH = 1 << 4;
+ }
+
+ public static final class BatchFlags {
+ public static int WAKEUP_ON_FIFO_FULL = 1 << 0;
+ public static int CALLBACK_ON_LOCATION_FIX = 1 << 1;
+ }
+}
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 47e425629783..b545a834529d 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -23,7 +23,10 @@ import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ILocationProvider;
+import android.location.provider.ILocationProviderManager;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.IBinder;
@@ -34,10 +37,6 @@ import android.util.Log;
import androidx.annotation.RequiresApi;
-import com.android.internal.location.ILocationProvider;
-import com.android.internal.location.ILocationProviderManager;
-import com.android.internal.location.ProviderRequest;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
@@ -58,7 +57,11 @@ import java.util.List;
* <p>IMPORTANT: This class is effectively a public API for unbundled
* applications, and must remain API stable. See README.txt in the root
* of this package for more information.
+ *
+ * @deprecated This class is not part of the standard API surface - use
+ * {@link android.location.provider.LocationProviderBase} instead.
*/
+@Deprecated
public abstract class LocationProviderBase {
/**
@@ -386,8 +389,8 @@ public abstract class LocationProviderBase {
}
@Override
- public void setRequest(ProviderRequest request, WorkSource ws) {
- onSetRequest(new ProviderRequestUnbundled(request), ws);
+ public void setRequest(ProviderRequest request) {
+ onSetRequest(new ProviderRequestUnbundled(request), request.getWorkSource());
}
@Override
diff --git a/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java b/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java
index 9d8ccdf62ca5..89ca2822a19d 100644
--- a/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java
+++ b/location/lib/java/com/android/location/provider/ProviderPropertiesUnbundled.java
@@ -17,7 +17,7 @@
package com.android.location.provider;
import android.annotation.NonNull;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
import java.util.Objects;
@@ -35,10 +35,18 @@ public final class ProviderPropertiesUnbundled {
public static @NonNull ProviderPropertiesUnbundled create(boolean requiresNetwork,
boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost,
boolean supportsAltitude, boolean supportsSpeed, boolean supportsBearing,
- int powerRequirement, int accuracy) {
- return new ProviderPropertiesUnbundled(new ProviderProperties(requiresNetwork,
- requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed,
- supportsBearing, powerRequirement, accuracy));
+ int powerUsage, int accuracy) {
+ return new ProviderPropertiesUnbundled(new ProviderProperties.Builder()
+ .setHasNetworkRequirement(requiresNetwork)
+ .setHasSatelliteRequirement(requiresSatellite)
+ .setHasCellRequirement(requiresCell)
+ .setHasMonetaryCost(requiresCell)
+ .setHasAltitudeSupport(requiresCell)
+ .setHasSpeedSupport(requiresCell)
+ .setHasBearingSupport(requiresCell)
+ .setPowerUsage(powerUsage)
+ .setAccuracy(accuracy)
+ .build());
}
private final ProviderProperties mProperties;
diff --git a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
index b464fca6f596..28317fed9eee 100644
--- a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
+++ b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
@@ -18,13 +18,12 @@ package com.android.location.provider;
import android.annotation.NonNull;
import android.location.LocationRequest;
+import android.location.provider.ProviderRequest;
import android.os.Build;
import android.os.WorkSource;
import androidx.annotation.RequiresApi;
-import com.android.internal.location.ProviderRequest;
-
import java.util.Collections;
import java.util.List;
diff --git a/packages/FusedLocation/AndroidManifest.xml b/packages/FusedLocation/AndroidManifest.xml
index bad0497c487d..12dc170413de 100644
--- a/packages/FusedLocation/AndroidManifest.xml
+++ b/packages/FusedLocation/AndroidManifest.xml
@@ -40,7 +40,7 @@
LocationManagerService will bind to the service with the highest
version. -->
<service android:name="com.android.location.fused.FusedLocationService"
- android:exported="true"
+ android:exported="false"
android:permission="android.permission.WRITE_SECURE_SETTINGS">
<intent-filter>
<action android:name="com.android.location.service.FusedLocationProvider" />
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
index 6827d6eb0180..cb55c727809a 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
@@ -20,6 +20,8 @@ import static android.content.Intent.ACTION_USER_SWITCHED;
import static android.location.LocationManager.GPS_PROVIDER;
import static android.location.LocationManager.NETWORK_PROVIDER;
import static android.location.LocationRequest.QUALITY_LOW_POWER;
+import static android.location.provider.ProviderProperties.ACCURACY_FINE;
+import static android.location.provider.ProviderProperties.POWER_USAGE_LOW;
import static com.android.location.provider.ProviderRequestUnbundled.INTERVAL_DISABLED;
@@ -28,113 +30,57 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationRequest;
-import android.os.WorkSource;
+import android.location.provider.LocationProviderBase;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
+import android.os.Bundle;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.location.ProviderRequest;
-import com.android.location.provider.LocationProviderBase;
-import com.android.location.provider.ProviderPropertiesUnbundled;
-import com.android.location.provider.ProviderRequestUnbundled;
import java.io.PrintWriter;
+import java.util.Objects;
/** Basic fused location provider implementation. */
public class FusedLocationProvider extends LocationProviderBase {
private static final String TAG = "FusedLocationProvider";
- private static final ProviderPropertiesUnbundled PROPERTIES =
- ProviderPropertiesUnbundled.create(
- /* requiresNetwork = */ false,
- /* requiresSatellite = */ false,
- /* requiresCell = */ false,
- /* hasMonetaryCost = */ false,
- /* supportsAltitude = */ true,
- /* supportsSpeed = */ true,
- /* supportsBearing = */ true,
- Criteria.POWER_LOW,
- Criteria.ACCURACY_FINE
- );
+ private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
+ .setHasAltitudeSupport(true)
+ .setHasSpeedSupport(true)
+ .setHasBearingSupport(true)
+ .setPowerUsage(POWER_USAGE_LOW)
+ .setAccuracy(ACCURACY_FINE)
+ .build();
private static final long MAX_LOCATION_COMPARISON_NS = 11 * 1000000000L; // 11 seconds
- final Object mLock = new Object();
+ private final Object mLock = new Object();
private final Context mContext;
private final LocationManager mLocationManager;
- private final LocationListener mGpsListener;
- private final LocationListener mNetworkListener;
+ private final ChildLocationListener mGpsListener;
+ private final ChildLocationListener mNetworkListener;
private final BroadcastReceiver mUserChangeReceiver;
@GuardedBy("mLock")
- ProviderRequestUnbundled mRequest;
- @GuardedBy("mLock")
- private WorkSource mWorkSource;
- @GuardedBy("mLock")
- private long mGpsInterval;
- @GuardedBy("mLock")
- private long mNetworkInterval;
+ private ProviderRequest mRequest;
@GuardedBy("mLock")
- @Nullable private Location mFusedLocation;
- @GuardedBy("mLock")
- @Nullable Location mGpsLocation;
- @GuardedBy("mLock")
- @Nullable Location mNetworkLocation;
+ private @Nullable Location mFusedLocation;
public FusedLocationProvider(Context context) {
super(context, TAG, PROPERTIES);
mContext = context;
- mLocationManager = context.getSystemService(LocationManager.class);
-
- mGpsListener = new LocationListener() {
- @Override
- public void onLocationChanged(Location location) {
- synchronized (mLock) {
- mGpsLocation = location;
- reportBestLocationLocked();
- }
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- synchronized (mLock) {
- // if satisfying a bypass request, don't clear anything
- if (mRequest.getReportLocation() && mRequest.isLocationSettingsIgnored()) {
- return;
- }
-
- mGpsLocation = null;
- }
- }
- };
-
- mNetworkListener = new LocationListener() {
- @Override
- public void onLocationChanged(Location location) {
- synchronized (mLock) {
- mNetworkLocation = location;
- reportBestLocationLocked();
- }
- }
+ mLocationManager = Objects.requireNonNull(context.getSystemService(LocationManager.class));
- @Override
- public void onProviderDisabled(String provider) {
- synchronized (mLock) {
- // if satisfying a bypass request, don't clear anything
- if (mRequest.getReportLocation() && mRequest.isLocationSettingsIgnored()) {
- return;
- }
-
- mNetworkLocation = null;
- }
- }
- };
+ mGpsListener = new ChildLocationListener(GPS_PROVIDER);
+ mNetworkListener = new ChildLocationListener(NETWORK_PROVIDER);
mUserChangeReceiver = new BroadcastReceiver() {
@Override
@@ -147,10 +93,7 @@ public class FusedLocationProvider extends LocationProviderBase {
}
};
- mRequest = new ProviderRequestUnbundled(ProviderRequest.EMPTY_REQUEST);
- mWorkSource = new WorkSource();
- mGpsInterval = INTERVAL_DISABLED;
- mNetworkInterval = INTERVAL_DISABLED;
+ mRequest = ProviderRequest.EMPTY_REQUEST;
}
void start() {
@@ -161,57 +104,53 @@ public class FusedLocationProvider extends LocationProviderBase {
mContext.unregisterReceiver(mUserChangeReceiver);
synchronized (mLock) {
- mRequest = new ProviderRequestUnbundled(ProviderRequest.EMPTY_REQUEST);
+ mRequest = ProviderRequest.EMPTY_REQUEST;
updateRequirementsLocked();
}
}
@Override
- public void onSetRequest(ProviderRequestUnbundled request, WorkSource workSource) {
+ public void onSetRequest(ProviderRequest request) {
synchronized (mLock) {
mRequest = request;
- mWorkSource = workSource;
updateRequirementsLocked();
}
}
- @GuardedBy("mLock")
- private void updateRequirementsLocked() {
- long gpsInterval = mRequest.getQuality() < QUALITY_LOW_POWER ? mRequest.getInterval()
- : INTERVAL_DISABLED;
- long networkInterval = mRequest.getInterval();
+ @Override
+ public void onFlush(OnFlushCompleteCallback callback) {
+ OnFlushCompleteCallback wrapper = new OnFlushCompleteCallback() {
+ private int mFlushCount = 2;
- if (gpsInterval != mGpsInterval) {
- resetProviderRequestLocked(GPS_PROVIDER, mGpsInterval, gpsInterval, mGpsListener);
- mGpsInterval = gpsInterval;
- }
- if (networkInterval != mNetworkInterval) {
- resetProviderRequestLocked(NETWORK_PROVIDER, mNetworkInterval, networkInterval,
- mNetworkListener);
- mNetworkInterval = networkInterval;
- }
+ @Override
+ public void onFlushComplete() {
+ if (--mFlushCount == 0) {
+ callback.onFlushComplete();
+ }
+ }
+ };
+
+ mGpsListener.flush(wrapper);
+ mNetworkListener.flush(wrapper);
}
+ @Override
+ public void onSendExtraCommand(String command, @Nullable Bundle extras) {}
+
@GuardedBy("mLock")
- private void resetProviderRequestLocked(String provider, long oldInterval, long newInterval,
- LocationListener listener) {
- if (oldInterval != INTERVAL_DISABLED && newInterval == INTERVAL_DISABLED) {
- mLocationManager.removeUpdates(listener);
- }
- if (newInterval != INTERVAL_DISABLED) {
- LocationRequest request = new LocationRequest.Builder(newInterval)
- .setQuality(mRequest.getQuality())
- .setLocationSettingsIgnored(mRequest.isLocationSettingsIgnored())
- .setWorkSource(mWorkSource)
- .build();
- mLocationManager.requestLocationUpdates(provider, request, mContext.getMainExecutor(),
- listener);
- }
+ private void updateRequirementsLocked() {
+ long gpsInterval = mRequest.getQuality() < QUALITY_LOW_POWER ? mRequest.getIntervalMillis()
+ : INTERVAL_DISABLED;
+ long networkInterval = mRequest.getIntervalMillis();
+
+ mGpsListener.resetProviderRequest(gpsInterval);
+ mNetworkListener.resetProviderRequest(networkInterval);
}
@GuardedBy("mLock")
void reportBestLocationLocked() {
- Location bestLocation = chooseBestLocation(mGpsLocation, mNetworkLocation);
+ Location bestLocation = chooseBestLocation(mGpsListener.getLocation(),
+ mNetworkListener.getLocation());
if (bestLocation == mFusedLocation) {
return;
}
@@ -228,25 +167,25 @@ public class FusedLocationProvider extends LocationProviderBase {
// clear cached locations when the user changes to prevent leaking user information
synchronized (mLock) {
mFusedLocation = null;
- mGpsLocation = null;
- mNetworkLocation = null;
+ mGpsListener.clearLocation();
+ mNetworkListener.clearLocation();
}
}
void dump(PrintWriter writer) {
synchronized (mLock) {
writer.println("request: " + mRequest);
- if (mGpsInterval != INTERVAL_DISABLED) {
- writer.println(" gps interval: " + mGpsInterval);
+ if (mGpsListener.getInterval() != INTERVAL_DISABLED) {
+ writer.println(" gps interval: " + mGpsListener.getInterval());
}
- if (mNetworkInterval != INTERVAL_DISABLED) {
- writer.println(" network interval: " + mNetworkInterval);
+ if (mNetworkListener.getInterval() != INTERVAL_DISABLED) {
+ writer.println(" network interval: " + mNetworkListener.getInterval());
}
- if (mGpsLocation != null) {
- writer.println(" last gps location: " + mGpsLocation);
+ if (mGpsListener.getLocation() != null) {
+ writer.println(" last gps location: " + mGpsListener.getLocation());
}
- if (mNetworkLocation != null) {
- writer.println(" last network location: " + mNetworkLocation);
+ if (mNetworkListener.getLocation() != null) {
+ writer.println(" last network location: " + mNetworkListener.getLocation());
}
}
}
@@ -279,4 +218,104 @@ public class FusedLocationProvider extends LocationProviderBase {
}
return locationA.getAccuracy() < locationB.getAccuracy() ? locationA : locationB;
}
+
+ private class ChildLocationListener implements LocationListener {
+
+ private final String mProvider;
+ private final SparseArray<OnFlushCompleteCallback> mPendingFlushes;
+
+ @GuardedBy("mLock")
+ private int mNextFlushCode = 0;
+ @GuardedBy("mLock")
+ private @Nullable Location mLocation = null;
+ @GuardedBy("mLock")
+ private long mInterval = INTERVAL_DISABLED;
+
+ ChildLocationListener(String provider) {
+ mProvider = provider;
+ mPendingFlushes = new SparseArray<>();
+ }
+
+ @Nullable Location getLocation() {
+ synchronized (mLock) {
+ return mLocation;
+ }
+ }
+
+ long getInterval() {
+ synchronized (mLock) {
+ return mInterval;
+ }
+ }
+
+ void clearLocation() {
+ synchronized (mLock) {
+ mLocation = null;
+ }
+ }
+
+ private void resetProviderRequest(long newInterval) {
+ synchronized (mLock) {
+ if (newInterval == mInterval) {
+ return;
+ }
+
+ if (mInterval != INTERVAL_DISABLED && newInterval == INTERVAL_DISABLED) {
+ mLocationManager.removeUpdates(this);
+ }
+
+ mInterval = newInterval;
+
+ if (mInterval != INTERVAL_DISABLED) {
+ LocationRequest request = new LocationRequest.Builder(mInterval)
+ .setMaxUpdateDelayMillis(mRequest.getMaxUpdateDelayMillis())
+ .setQuality(mRequest.getQuality())
+ .setLowPower(mRequest.isLowPower())
+ .setLocationSettingsIgnored(mRequest.isLocationSettingsIgnored())
+ .setWorkSource(mRequest.getWorkSource())
+ .build();
+ mLocationManager.requestLocationUpdates(mProvider, request,
+ mContext.getMainExecutor(), this);
+ }
+ }
+ }
+
+ void flush(OnFlushCompleteCallback callback) {
+ synchronized (mLock) {
+ int requestCode = mNextFlushCode++;
+ mPendingFlushes.put(requestCode, callback);
+ mLocationManager.requestFlush(mProvider, this, requestCode);
+ }
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ synchronized (mLock) {
+ mLocation = location;
+ reportBestLocationLocked();
+ }
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ synchronized (mLock) {
+ // if satisfying a bypass request, don't clear anything
+ if (mRequest.isActive() && mRequest.isLocationSettingsIgnored()) {
+ return;
+ }
+
+ mLocation = null;
+ }
+ }
+
+ @Override
+ public void onFlushComplete(int requestCode) {
+ synchronized (mLock) {
+ OnFlushCompleteCallback callback = mPendingFlushes.removeReturnOld(requestCode);
+ if (callback != null) {
+ callback.onFlushComplete();
+ }
+ }
+ }
+ }
}
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 2bda530b83d4..d47231147a38 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -27,18 +27,18 @@ import android.location.Location;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ILocationProvider;
+import android.location.provider.ILocationProviderManager;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
-import android.os.WorkSource;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.location.ILocationProvider;
-import com.android.internal.location.ILocationProviderManager;
-import com.android.internal.location.ProviderRequest;
import com.android.location.fused.FusedLocationProvider;
import org.junit.After;
@@ -71,7 +71,7 @@ public class FusedLocationServiceTest {
long seed = System.currentTimeMillis();
Log.i(TAG, "location seed: " + seed);
- Context context = InstrumentationRegistry.getTargetContext();
+ Context context = ApplicationProvider.getApplicationContext();
mRandom = new Random(seed);
mLocationManager = context.getSystemService(LocationManager.class);
@@ -120,8 +120,7 @@ public class FusedLocationServiceTest {
mProvider.setRequest(
new ProviderRequest.Builder()
.setIntervalMillis(1000)
- .build(),
- new WorkSource());
+ .build());
Location location = createLocation(NETWORK_PROVIDER, mRandom);
mLocationManager.setTestProviderLocation(NETWORK_PROVIDER, location);
@@ -135,8 +134,7 @@ public class FusedLocationServiceTest {
new ProviderRequest.Builder()
.setQuality(LocationRequest.QUALITY_HIGH_ACCURACY)
.setIntervalMillis(1000)
- .build(),
- new WorkSource());
+ .build());
Location location = createLocation(GPS_PROVIDER, mRandom);
mLocationManager.setTestProviderLocation(GPS_PROVIDER, location);
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 9ab30b403044..7ec4a5adb33e 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -26,6 +26,8 @@ import static android.location.LocationManager.FUSED_PROVIDER;
import static android.location.LocationManager.GPS_PROVIDER;
import static android.location.LocationManager.NETWORK_PROVIDER;
import static android.location.LocationRequest.LOW_POWER_EXCEPTIONS;
+import static android.location.provider.LocationProviderBase.ACTION_FUSED_PROVIDER;
+import static android.location.provider.LocationProviderBase.ACTION_NETWORK_PROVIDER;
import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
@@ -64,7 +66,7 @@ import android.location.LocationManagerInternal;
import android.location.LocationProvider;
import android.location.LocationRequest;
import android.location.LocationTime;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
import android.location.util.identity.CallerIdentity;
import android.os.Binder;
import android.os.Bundle;
@@ -213,11 +215,6 @@ public class LocationManagerService extends ILocationManager.Stub {
public static final String TAG = "LocationManagerService";
public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
- private static final String NETWORK_LOCATION_SERVICE_ACTION =
- "com.android.location.service.v3.NetworkLocationProvider";
- private static final String FUSED_LOCATION_SERVICE_ACTION =
- "com.android.location.service.FusedLocationProvider";
-
private static final String ATTRIBUTION_TAG = "LocationService";
private final Object mLock = new Object();
@@ -339,7 +336,7 @@ public class LocationManagerService extends ILocationManager.Stub {
// provider has unfortunate hard dependencies on the network provider
ProxyLocationProvider networkProvider = ProxyLocationProvider.create(
mContext,
- NETWORK_LOCATION_SERVICE_ACTION,
+ ACTION_NETWORK_PROVIDER,
com.android.internal.R.bool.config_enableNetworkLocationOverlay,
com.android.internal.R.string.config_networkLocationProviderPackageName);
if (networkProvider != null) {
@@ -352,13 +349,13 @@ public class LocationManagerService extends ILocationManager.Stub {
// ensure that a fused provider exists which will work in direct boot
Preconditions.checkState(!mContext.getPackageManager().queryIntentServicesAsUser(
- new Intent(FUSED_LOCATION_SERVICE_ACTION),
+ new Intent(ACTION_FUSED_PROVIDER),
MATCH_DIRECT_BOOT_AWARE | MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).isEmpty(),
"Unable to find a direct boot aware fused location provider");
ProxyLocationProvider fusedProvider = ProxyLocationProvider.create(
mContext,
- FUSED_LOCATION_SERVICE_ACTION,
+ ACTION_FUSED_PROVIDER,
com.android.internal.R.bool.config_enableFusedLocationOverlay,
com.android.internal.R.string.config_fusedLocationProviderPackageName);
if (fusedProvider != null) {
@@ -410,16 +407,17 @@ public class LocationManagerService extends ILocationManager.Stub {
for (String testProviderString : testProviderStrings) {
String[] fragments = testProviderString.split(",");
String name = fragments[0].trim();
- ProviderProperties properties = new ProviderProperties(
- Boolean.parseBoolean(fragments[1]) /* requiresNetwork */,
- Boolean.parseBoolean(fragments[2]) /* requiresSatellite */,
- Boolean.parseBoolean(fragments[3]) /* requiresCell */,
- Boolean.parseBoolean(fragments[4]) /* hasMonetaryCost */,
- Boolean.parseBoolean(fragments[5]) /* supportsAltitude */,
- Boolean.parseBoolean(fragments[6]) /* supportsSpeed */,
- Boolean.parseBoolean(fragments[7]) /* supportsBearing */,
- Integer.parseInt(fragments[8]) /* powerUsage */,
- Integer.parseInt(fragments[9]) /* accuracy */);
+ ProviderProperties properties = new ProviderProperties.Builder()
+ .setHasNetworkRequirement(Boolean.parseBoolean(fragments[1]))
+ .setHasSatelliteRequirement(Boolean.parseBoolean(fragments[2]))
+ .setHasCellRequirement(Boolean.parseBoolean(fragments[3]))
+ .setHasMonetaryCost(Boolean.parseBoolean(fragments[4]))
+ .setHasAltitudeSupport(Boolean.parseBoolean(fragments[5]))
+ .setHasSpeedSupport(Boolean.parseBoolean(fragments[6]))
+ .setHasBearingSupport(Boolean.parseBoolean(fragments[7]))
+ .setPowerUsage(Integer.parseInt(fragments[8]))
+ .setAccuracy(Integer.parseInt(fragments[9]))
+ .build();
getOrAddLocationProviderManager(name).setMockProvider(
new MockLocationProvider(properties, CallerIdentity.fromContext(mContext)));
}
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 477c037befc4..d16267f0582e 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -16,6 +16,9 @@
package com.android.server.location.gnss;
+import static android.location.provider.ProviderProperties.ACCURACY_FINE;
+import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
+
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_GSM_CELLID;
import static com.android.server.location.gnss.hal.GnssNative.AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
@@ -58,7 +61,8 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.AsyncTask;
import android.os.BatteryStats;
@@ -88,7 +92,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.ProviderRequest;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.FgThread;
import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback;
@@ -122,16 +125,14 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
- private static final ProviderProperties PROPERTIES = new ProviderProperties(
- /* requiresNetwork = */false,
- /* requiresSatellite = */true,
- /* requiresCell = */false,
- /* hasMonetaryCost = */false,
- /* supportAltitude = */true,
- /* supportsSpeed = */true,
- /* supportsBearing = */true,
- ProviderProperties.POWER_USAGE_HIGH,
- ProviderProperties.ACCURACY_FINE);
+ private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
+ .setHasSatelliteRequirement(true)
+ .setHasAltitudeSupport(true)
+ .setHasSpeedSupport(true)
+ .setHasBearingSupport(true)
+ .setPowerUsage(POWER_USAGE_HIGH)
+ .setAccuracy(ACCURACY_FINE)
+ .build();
// The AGPS SUPL mode
private static final int AGPS_SUPL_MODE_MSA = 0x02;
diff --git a/services/core/java/com/android/server/location/injector/LocationEventLog.java b/services/core/java/com/android/server/location/injector/LocationEventLog.java
index b34beedd567e..b8b54b3a42e7 100644
--- a/services/core/java/com/android/server/location/injector/LocationEventLog.java
+++ b/services/core/java/com/android/server/location/injector/LocationEventLog.java
@@ -26,11 +26,11 @@ import static com.android.server.location.LocationManagerService.D;
import android.annotation.Nullable;
import android.location.LocationRequest;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Build;
import android.os.PowerManager.LocationPowerSaveMode;
-import com.android.internal.location.ProviderRequest;
import com.android.server.utils.eventlog.LocalEventLog;
/** In memory event log for location events. */
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 5364feb67fa4..e22a0145f2bf 100644
--- a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java
@@ -18,12 +18,12 @@ package com.android.server.location.provider;
import android.annotation.Nullable;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Binder;
import android.os.Bundle;
-import com.android.internal.location.ProviderRequest;
import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderController.java b/services/core/java/com/android/server/location/provider/LocationProviderController.java
index e49d9db274b5..a0e37944affd 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderController.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderController.java
@@ -17,9 +17,9 @@
package com.android.server.location.provider;
import android.annotation.Nullable;
+import android.location.provider.ProviderRequest;
import android.os.Bundle;
-import com.android.internal.location.ProviderRequest;
import com.android.server.location.provider.AbstractLocationProvider.Listener;
import com.android.server.location.provider.AbstractLocationProvider.State;
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 858b7624891a..14f010063538 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -55,7 +55,8 @@ import android.location.LocationManagerInternal;
import android.location.LocationManagerInternal.ProviderEnabledListener;
import android.location.LocationRequest;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Binder;
import android.os.Build;
@@ -82,7 +83,6 @@ import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.location.ProviderRequest;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
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 f9aa4020b522..dce7b081de6e 100644
--- a/services/core/java/com/android/server/location/provider/MockLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/MockLocationProvider.java
@@ -21,12 +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.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
-import com.android.internal.location.ProviderRequest;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
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 c1b0abf64820..cb7264e55fa9 100644
--- a/services/core/java/com/android/server/location/provider/MockableLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/MockableLocationProvider.java
@@ -21,12 +21,12 @@ 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.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.location.ProviderRequest;
import com.android.internal.util.Preconditions;
import java.io.FileDescriptor;
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 1f4c4cf2a0ac..a5758a37b983 100644
--- a/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/PassiveLocationProvider.java
@@ -16,16 +16,18 @@
package com.android.server.location.provider;
+import static android.location.provider.ProviderProperties.ACCURACY_FINE;
+import static android.location.provider.ProviderProperties.POWER_USAGE_LOW;
+
import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import android.content.Context;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
-import com.android.internal.location.ProviderRequest;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -38,16 +40,10 @@ import java.io.PrintWriter;
*/
public class PassiveLocationProvider extends AbstractLocationProvider {
- private static final ProviderProperties PROPERTIES = new ProviderProperties(
- /* requiresNetwork = */false,
- /* requiresSatellite = */false,
- /* requiresCell = */false,
- /* hasMonetaryCost = */false,
- /* supportsAltitude = */false,
- /* supportsSpeed = */false,
- /* supportsBearing = */false,
- ProviderProperties.POWER_USAGE_LOW,
- ProviderProperties.ACCURACY_COARSE);
+ private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
+ .setPowerUsage(POWER_USAGE_LOW)
+ .setAccuracy(ACCURACY_FINE)
+ .build();
public PassiveLocationProvider(Context context) {
// using a direct executor is ok because this class has no locks that could deadlock
diff --git a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
index d3fee82ed46a..b35af4f6475c 100644
--- a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java
@@ -20,9 +20,9 @@ import android.annotation.Nullable;
import android.content.Context;
import android.location.LocationManager;
import android.location.LocationResult;
+import android.location.provider.ProviderRequest;
import android.os.Binder;
-import com.android.internal.location.ProviderRequest;
import com.android.internal.util.Preconditions;
import com.android.server.location.injector.Injector;
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 345fdc00ff85..c274c2848ab6 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,7 +22,10 @@ import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ILocationProvider;
+import android.location.provider.ILocationProviderManager;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Binder;
import android.os.Bundle;
@@ -30,9 +33,6 @@ import android.os.IBinder;
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.ProviderRequest;
import com.android.internal.util.ArrayUtils;
import com.android.server.ServiceWatcher;
import com.android.server.location.provider.AbstractLocationProvider;
@@ -106,7 +106,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider {
ProviderRequest request = mRequest;
if (!request.equals(ProviderRequest.EMPTY_REQUEST)) {
- provider.setRequest(request, request.getWorkSource());
+ provider.setRequest(request);
}
}
}
@@ -142,7 +142,7 @@ public class ProxyLocationProvider extends AbstractLocationProvider {
mRequest = request;
mServiceWatcher.runOnBinder(binder -> {
ILocationProvider provider = ILocationProvider.Stub.asInterface(binder);
- provider.setRequest(request, request.getWorkSource());
+ provider.setRequest(request);
});
}
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 df7a445a068f..84bfc9be3d41 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
@@ -19,10 +19,8 @@ package com.android.server.location.provider;
import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION;
import static android.app.AppOpsManager.OP_MONITOR_LOCATION;
-import static android.location.Criteria.ACCURACY_COARSE;
-import static android.location.Criteria.ACCURACY_FINE;
-import static android.location.Criteria.POWER_HIGH;
import static android.location.LocationRequest.PASSIVE_INTERVAL;
+import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
import static androidx.test.ext.truth.location.LocationSubject.assertThat;
@@ -66,7 +64,8 @@ import android.location.LocationManagerInternal;
import android.location.LocationManagerInternal.ProviderEnabledListener;
import android.location.LocationRequest;
import android.location.LocationResult;
-import android.location.ProviderProperties;
+import android.location.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
import android.location.util.identity.CallerIdentity;
import android.os.Bundle;
import android.os.ICancellationSignal;
@@ -81,7 +80,6 @@ import android.util.Log;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.internal.location.ProviderRequest;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.location.injector.FakeUserInfoHelper;
@@ -115,8 +113,13 @@ public class LocationProviderManagerTest {
private static final int OTHER_USER = CURRENT_USER + 10;
private static final String NAME = "test";
- private static final ProviderProperties PROPERTIES = new ProviderProperties(false, false, false,
- false, true, true, true, POWER_HIGH, ACCURACY_FINE);
+ private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
+ .setHasAltitudeSupport(true)
+ .setHasSpeedSupport(true)
+ .setHasBearingSupport(true)
+ .setPowerUsage(POWER_USAGE_HIGH)
+ .setAccuracy(ProviderProperties.ACCURACY_FINE)
+ .build();
private static final CallerIdentity IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1,
"mypackage",
"attribution");
@@ -189,8 +192,14 @@ public class LocationProviderManagerTest {
assertThat(mManager.getIdentity()).isEqualTo(IDENTITY);
assertThat(mManager.hasProvider()).isTrue();
- ProviderProperties newProperties = new ProviderProperties(true, true, true,
- true, false, false, false, POWER_HIGH, ACCURACY_COARSE);
+ ProviderProperties newProperties = new ProviderProperties.Builder()
+ .setHasNetworkRequirement(true)
+ .setHasSatelliteRequirement(true)
+ .setHasCellRequirement(true)
+ .setHasMonetaryCost(true)
+ .setPowerUsage(POWER_USAGE_HIGH)
+ .setAccuracy(ProviderProperties.ACCURACY_COARSE)
+ .build();
mProvider.setProperties(newProperties);
assertThat(mManager.getProperties()).isEqualTo(newProperties);
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 daa8a22ccebb..99846c517b7a 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,7 +15,9 @@
*/
package com.android.server.location.provider;
-import static com.android.internal.location.ProviderRequest.EMPTY_REQUEST;
+import static android.location.provider.ProviderProperties.ACCURACY_FINE;
+import static android.location.provider.ProviderProperties.POWER_USAGE_LOW;
+import static android.location.provider.ProviderRequest.EMPTY_REQUEST;
import static com.google.common.truth.Truth.assertThat;
@@ -24,17 +26,16 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
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.provider.ProviderProperties;
+import android.location.provider.ProviderRequest;
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.ProviderRequest;
import com.android.server.location.test.FakeProvider;
import com.android.server.location.test.ProviderListenerCapture;
@@ -62,16 +63,14 @@ public class MockableLocationProviderTest {
mRealMock = mock(FakeProvider.FakeProviderInterface.class);
mRealProvider = new FakeProvider(mRealMock);
- mMockProvider = new MockLocationProvider(new ProviderProperties(
- false,
- false,
- false,
- false,
- true,
- true,
- true,
- Criteria.POWER_LOW,
- Criteria.ACCURACY_FINE),
+ mMockProvider = new MockLocationProvider(
+ new ProviderProperties.Builder()
+ .setHasAltitudeSupport(true)
+ .setHasSpeedSupport(true)
+ .setHasBearingSupport(true)
+ .setPowerUsage(POWER_USAGE_LOW)
+ .setAccuracy(ACCURACY_FINE)
+ .build(),
CallerIdentity.forTest(0, 1, "testpackage", "test"));
mProvider = new MockableLocationProvider(lock);
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 1eb03862f09c..775bdd580157 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
@@ -16,9 +16,9 @@
package com.android.server.location.test;
+import android.location.provider.ProviderRequest;
import android.os.Bundle;
-import com.android.internal.location.ProviderRequest;
import com.android.server.location.provider.AbstractLocationProvider;
import java.io.FileDescriptor;