summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoonil Nagarkar <sooniln@google.com>2020-12-24 14:02:44 -0800
committerSoonil Nagarkar <sooniln@google.com>2021-01-08 10:33:44 -0800
commit49983fcbbd085bd55dd8ef14d146120ec95cf256 (patch)
treeb1fc7efe872d7aa8e231271907817c83502a5224
parenta4c1faff5b1e280e0bae1903780b53ba08539b1f (diff)
Copy LocationProviderBase API into SystemApi surface
This allows third party location providers to link against the standard API surface. This replaces the LocationProviderBase implementation in the com.android.location.providers API. Both will temporarily coexist until third party applications can be migrated, and then old version will be removed. Only the LocationProviderBase API is migrated right now as its the only API that has undergone changes. This also restores some old, unused classes which should not have been remove from the API surface. Clients that support older API version will still need to link against these classes. Bug: 176115245 Test: builds Change-Id: I2d688447e1f59e441f5c48ff36d3f0dd8b5dc7f6
-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;