summaryrefslogtreecommitdiff
path: root/location
diff options
context:
space:
mode:
author Soonil Nagarkar <sooniln@google.com> 2020-03-04 23:05:49 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-03-04 23:05:49 +0000
commit1eb8014bd2d07ad03de3ee17243bb48b1e513297 (patch)
tree2e059301b8790e349581425a9bd46bff6cacd107 /location
parente445b758067f0fbe0796fab069a04aed2e1d1d06 (diff)
parent470c8f6a3f5a8f6d2c877019d1c22fc619eccad6 (diff)
Merge "Give location providers a known identity"
Diffstat (limited to 'location')
-rw-r--r--location/java/android/location/ILocationManager.aidl2
-rw-r--r--location/java/android/location/LocationManager.java80
-rw-r--r--location/java/android/location/LocationManagerInternal.java13
-rw-r--r--location/java/android/location/util/identity/CallerIdentity.java261
-rw-r--r--location/java/android/location/util/listeners/AbstractListenerManager.java31
-rw-r--r--location/java/com/android/internal/location/ILocationProviderManager.aidl2
-rw-r--r--location/lib/api/current.txt7
-rw-r--r--location/lib/java/com/android/location/provider/LocationProviderBase.java61
8 files changed, 405 insertions, 52 deletions
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index b7346308042f..6f543c31d9a3 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -96,7 +96,7 @@ interface ILocationManager
List<String> getProviders(in Criteria criteria, boolean enabledOnly);
String getBestProvider(in Criteria criteria, boolean enabledOnly);
ProviderProperties getProviderProperties(String provider);
- boolean isProviderPackage(String packageName);
+ boolean isProviderPackage(String provider, String packageName);
List<String> getProviderPackages(String provider);
void setExtraLocationControllerPackage(String packageName);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 7523f07674ea..0bf7add422cf 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -64,7 +64,6 @@ import com.android.internal.location.ProviderProperties;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledRunnable;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
@@ -313,10 +312,9 @@ public class LocationManager {
private static final long GET_CURRENT_LOCATION_MAX_TIMEOUT_MS = 30 * 1000;
- private final Context mContext;
-
+ final Context mContext;
@UnsupportedAppUsage
- private final ILocationManager mService;
+ final ILocationManager mService;
@GuardedBy("mListeners")
private final ArrayMap<LocationListener, LocationListenerTransport> mListeners =
@@ -1403,15 +1401,36 @@ public class LocationManager {
* otherwise.
*
* @hide
+ * @deprecated Prefer {@link #isProviderPackage(String, String)} instead.
*/
+ @Deprecated
@SystemApi
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
public boolean isProviderPackage(@NonNull String packageName) {
try {
- return mService.isProviderPackage(packageName);
+ return mService.isProviderPackage(null, packageName);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return false;
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns true if the given provider corresponds to the given package name. If the given
+ * provider is null, this will return true if any provider corresponds to the given package
+ * name.
+ *
+ * @param provider a provider listed by {@link #getAllProviders()} or null
+ * @param packageName the package name to test if it is a provider
+ * @return true if the given arguments correspond to a provider
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+ public boolean isProviderPackage(@Nullable String provider, @NonNull String packageName) {
+ try {
+ return mService.isProviderPackage(provider, packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -1420,16 +1439,17 @@ public class LocationManager {
* and an empty list if no package is associated with the provider.
*
* @hide
+ * @deprecated Prefer {@link #isProviderPackage(String, String)} instead.
*/
@TestApi
+ @Deprecated
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
@Nullable
public List<String> getProviderPackages(@NonNull String provider) {
try {
return mService.getProviderPackages(provider);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
- return Collections.emptyList();
+ throw e.rethrowFromSystemServer();
}
}
@@ -2470,7 +2490,7 @@ public class LocationManager {
@Nullable
private ICancellationSignal mRemoteCancellationSignal;
- private GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer) {
+ GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer) {
Preconditions.checkArgument(executor != null, "illegal null executor");
Preconditions.checkArgument(consumer != null, "illegal null consumer");
mExecutor = executor;
@@ -2595,7 +2615,7 @@ public class LocationManager {
private final LocationListener mListener;
@Nullable private volatile Executor mExecutor = null;
- private LocationListenerTransport(@NonNull LocationListener listener) {
+ LocationListenerTransport(@NonNull LocationListener listener) {
Preconditions.checkArgument(listener != null, "invalid null listener");
mListener = listener;
}
@@ -2769,7 +2789,7 @@ public class LocationManager {
private final OnNmeaMessageListener mListener;
- private NmeaAdapter(OnNmeaMessageListener listener) {
+ NmeaAdapter(OnNmeaMessageListener listener) {
mListener = listener;
}
@@ -2783,7 +2803,7 @@ public class LocationManager {
private final GpsStatus.Listener mGpsListener;
- private GpsAdapter(GpsStatus.Listener gpsListener) {
+ GpsAdapter(GpsStatus.Listener gpsListener) {
mGpsListener = gpsListener;
}
@@ -2813,8 +2833,11 @@ public class LocationManager {
private @Nullable IGnssStatusListener mListenerTransport;
- private volatile @Nullable GnssStatus mGnssStatus;
- private volatile int mTtff;
+ volatile @Nullable GnssStatus mGnssStatus;
+ volatile int mTtff;
+
+ GnssStatusListenerManager() {
+ }
public GnssStatus getGnssStatus() {
return mGnssStatus;
@@ -2862,6 +2885,9 @@ public class LocationManager {
}
private class GnssStatusListener extends IGnssStatusListener.Stub {
+ GnssStatusListener() {
+ }
+
@Override
public void onGnssStarted() {
deliverToListeners(GnssStatus.Callback::onStarted);
@@ -2905,6 +2931,9 @@ public class LocationManager {
@Nullable
private IGnssMeasurementsListener mListenerTransport;
+ GnssMeasurementsListenerManager() {
+ }
+
@Override
protected boolean registerService(GnssRequest request) {
Preconditions.checkState(mListenerTransport == null);
@@ -2947,6 +2976,9 @@ public class LocationManager {
}
private class GnssMeasurementsListener extends IGnssMeasurementsListener.Stub {
+ GnssMeasurementsListener() {
+ }
+
@Override
public void onGnssMeasurementsReceived(final GnssMeasurementsEvent event) {
deliverToListeners((callback) -> callback.onGnssMeasurementsReceived(event));
@@ -2965,6 +2997,9 @@ public class LocationManager {
@Nullable
private IGnssNavigationMessageListener mListenerTransport;
+ GnssNavigationMessageListenerManager() {
+ }
+
@Override
protected boolean registerService(Void ignored) {
Preconditions.checkState(mListenerTransport == null);
@@ -2994,6 +3029,9 @@ public class LocationManager {
}
private class GnssNavigationMessageListener extends IGnssNavigationMessageListener.Stub {
+ GnssNavigationMessageListener() {
+ }
+
@Override
public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {
deliverToListeners((listener) -> listener.onGnssNavigationMessageReceived(event));
@@ -3012,6 +3050,9 @@ public class LocationManager {
@Nullable
private IGnssAntennaInfoListener mListenerTransport;
+ GnssAntennaInfoListenerManager() {
+ }
+
@Override
protected boolean registerService(Void ignored) {
Preconditions.checkState(mListenerTransport == null);
@@ -3041,6 +3082,9 @@ public class LocationManager {
}
private class GnssAntennaInfoListener extends IGnssAntennaInfoListener.Stub {
+ GnssAntennaInfoListener() {
+ }
+
@Override
public void onGnssAntennaInfoReceived(List<GnssAntennaInfo> infos) {
deliverToListeners(callback -> callback.onGnssAntennaInfoReceived(infos));
@@ -3055,6 +3099,9 @@ public class LocationManager {
@Nullable
private IBatchedLocationCallback mListenerTransport;
+ BatchedLocationCallbackManager() {
+ }
+
@Override
protected boolean registerService(Void ignored) {
Preconditions.checkState(mListenerTransport == null);
@@ -3083,6 +3130,9 @@ public class LocationManager {
}
private class BatchedLocationCallback extends IBatchedLocationCallback.Stub {
+ BatchedLocationCallback() {
+ }
+
@Override
public void onLocationBatch(List<Location> locations) {
deliverToListeners((listener) -> listener.onLocationBatch(locations));
diff --git a/location/java/android/location/LocationManagerInternal.java b/location/java/android/location/LocationManagerInternal.java
index 6006d5079b07..542737b479e2 100644
--- a/location/java/android/location/LocationManagerInternal.java
+++ b/location/java/android/location/LocationManagerInternal.java
@@ -18,6 +18,8 @@ package android.location;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.location.util.identity.CallerIdentity;
/**
* Location manager local system service interface.
@@ -36,13 +38,14 @@ public abstract class LocationManagerInternal {
public abstract boolean isProviderEnabledForUser(@NonNull String provider, int userId);
/**
- * Returns true if the given package belongs to a location provider, and so should be afforded
- * some special privileges.
+ * Returns true if the given identity is a location provider.
*
- * @param packageName The package name to check
- * @return True is the given package belongs to a location provider, false otherwise
+ * @param provider The provider to check, or null to check every provider
+ * @param identity The identity to match
+ * @return True if the given identity matches either the given location provider or any
+ * provider, and false otherwise
*/
- public abstract boolean isProviderPackage(@NonNull String packageName);
+ public abstract boolean isProvider(@Nullable String provider, @NonNull CallerIdentity identity);
/**
* Should only be used by GNSS code.
diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java
new file mode 100644
index 000000000000..15641eb3bb6f
--- /dev/null
+++ b/location/java/android/location/util/identity/CallerIdentity.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.location.util.identity;
+
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Process;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Identifying information on a caller.
+ *
+ * @hide
+ */
+public final class CallerIdentity {
+
+ public static final int PERMISSION_NONE = 0;
+ public static final int PERMISSION_COARSE = 1;
+ public static final int PERMISSION_FINE = 2;
+
+ @IntDef({PERMISSION_NONE, PERMISSION_COARSE, PERMISSION_FINE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PermissionLevel {}
+
+ /**
+ * Converts the given permission level to the corresponding permission.
+ */
+ public static String asPermission(@PermissionLevel int permissionLevel) {
+ switch (permissionLevel) {
+ case PERMISSION_COARSE:
+ return ACCESS_COARSE_LOCATION;
+ case PERMISSION_FINE:
+ return ACCESS_FINE_LOCATION;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Converts the given permission level to the corresponding appop.
+ */
+ public static int asAppOp(@PermissionLevel int permissionLevel) {
+ switch (permissionLevel) {
+ case PERMISSION_COARSE:
+ return AppOpsManager.OP_COARSE_LOCATION;
+ case PERMISSION_FINE:
+ return AppOpsManager.OP_FINE_LOCATION;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Construct a CallerIdentity for test purposes.
+ */
+ @VisibleForTesting
+ public static CallerIdentity forTest(int uid, int pid, String packageName,
+ @Nullable String featureId, @PermissionLevel int permissionLevel) {
+
+ return new CallerIdentity(uid, pid, packageName, featureId,
+ permissionLevel);
+ }
+
+ /**
+ * Creates a CallerIdentity for the current process and context.
+ */
+ public static CallerIdentity fromContext(Context context) {
+ return new CallerIdentity(Process.myUid(), Process.myPid(),
+ context.getPackageName(), context.getFeatureId(),
+ getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid()));
+ }
+
+ /**
+ * Creates a CallerIdentity from the current binder identity, using the given package and
+ * feature id. The package will be checked to enforce it belongs to the calling uid, and a
+ * security exception will be thrown if it is invalid.
+ */
+ public static CallerIdentity fromBinder(Context context, String packageName,
+ @Nullable String featureId) {
+ int uid = Binder.getCallingUid();
+ if (!ArrayUtils.contains(context.getPackageManager().getPackagesForUid(uid), packageName)) {
+ throw new SecurityException("invalid package \"" + packageName + "\" for uid " + uid);
+ }
+
+ return fromBinderUnsafe(context, packageName, featureId);
+ }
+
+ /**
+ * Creates a CallerIdentity from the current binder identity, using the given package and
+ * feature id. The package will not be checked to enforce that it belongs to the calling uid -
+ * this method should only be used if the package will be validated by some other means, such as
+ * an appops call.
+ */
+ public static CallerIdentity fromBinderUnsafe(Context context, String packageName,
+ @Nullable String featureId) {
+ return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(),
+ packageName, featureId,
+ getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid()));
+ }
+
+ /**
+ * Throws a security exception if the caller does not hold a location permission.
+ */
+ public static void enforceCallingOrSelfLocationPermission(Context context,
+ @PermissionLevel int desiredPermissionLevel) {
+ enforceLocationPermission(Binder.getCallingUid(),
+ getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid()),
+ desiredPermissionLevel);
+ }
+
+ /**
+ * Returns false if the caller does not hold a location permission, true otherwise.
+ */
+ public static boolean checkCallingOrSelfLocationPermission(Context context,
+ @PermissionLevel int desiredPermissionLevel) {
+ return checkLocationPermission(
+ getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid()),
+ desiredPermissionLevel);
+ }
+
+ private static void enforceLocationPermission(int uid, @PermissionLevel int permissionLevel,
+ @PermissionLevel int desiredPermissionLevel) {
+ if (checkLocationPermission(permissionLevel, desiredPermissionLevel)) {
+ return;
+ }
+
+ if (desiredPermissionLevel == PERMISSION_COARSE) {
+ throw new SecurityException("uid " + uid + " does not have " + ACCESS_COARSE_LOCATION
+ + " or " + ACCESS_FINE_LOCATION + ".");
+ } else if (desiredPermissionLevel == PERMISSION_FINE) {
+ throw new SecurityException("uid " + uid + " does not have " + ACCESS_FINE_LOCATION
+ + ".");
+ }
+ }
+
+ private static boolean checkLocationPermission(@PermissionLevel int permissionLevel,
+ @PermissionLevel int desiredPermissionLevel) {
+ return permissionLevel >= desiredPermissionLevel;
+ }
+
+ private static @PermissionLevel int getPermissionLevel(Context context, int pid, int uid) {
+ if (context.checkPermission(ACCESS_FINE_LOCATION, pid, uid) == PERMISSION_GRANTED) {
+ return PERMISSION_FINE;
+ }
+ if (context.checkPermission(ACCESS_COARSE_LOCATION, pid, uid) == PERMISSION_GRANTED) {
+ return PERMISSION_COARSE;
+ }
+
+ return PERMISSION_NONE;
+ }
+
+ /** The calling UID. */
+ public final int uid;
+
+ /** The calling PID. */
+ public final int pid;
+
+ /** The calling user. */
+ public final int userId;
+
+ /** The calling package name. */
+ public final String packageName;
+
+ /** The calling feature id. */
+ public final @Nullable String featureId;
+
+ /**
+ * The calling location permission level. This field should only be used for validating
+ * permissions for API access. It should not be used for validating permissions for location
+ * access - that must be done through appops.
+ */
+ public final @PermissionLevel int permissionLevel;
+
+ private CallerIdentity(int uid, int pid, String packageName,
+ @Nullable String featureId, @PermissionLevel int permissionLevel) {
+ this.uid = uid;
+ this.pid = pid;
+ this.userId = UserHandle.getUserId(uid);
+ this.packageName = Objects.requireNonNull(packageName);
+ this.featureId = featureId;
+ this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE,
+ PERMISSION_FINE, "permissionLevel");
+ }
+
+ /**
+ * Throws a security exception if the CallerIdentity does not hold a location permission.
+ */
+ public void enforceLocationPermission(@PermissionLevel int desiredPermissionLevel) {
+ enforceLocationPermission(uid, permissionLevel, desiredPermissionLevel);
+ }
+
+ @Override
+ public String toString() {
+ int length = 10 + packageName.length();
+ if (featureId != null) {
+ length += featureId.length();
+ }
+
+ StringBuilder builder = new StringBuilder(length);
+ builder.append(pid).append("/").append(packageName);
+ if (featureId != null) {
+ builder.append("[");
+ if (featureId.startsWith(packageName)) {
+ builder.append(featureId.substring(packageName.length()));
+ } else {
+ builder.append(featureId);
+ }
+ builder.append("]");
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof CallerIdentity)) {
+ return false;
+ }
+ CallerIdentity that = (CallerIdentity) o;
+ return uid == that.uid
+ && pid == that.pid
+ && packageName.equals(that.packageName)
+ && Objects.equals(featureId, that.featureId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(uid, pid, packageName, featureId);
+ }
+}
diff --git a/location/java/android/location/util/listeners/AbstractListenerManager.java b/location/java/android/location/util/listeners/AbstractListenerManager.java
index facb74766f2c..09c1eb2ae153 100644
--- a/location/java/android/location/util/listeners/AbstractListenerManager.java
+++ b/location/java/android/location/util/listeners/AbstractListenerManager.java
@@ -156,8 +156,15 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
// this class does not support adding listeners reentrantly
Preconditions.checkState(!mReentrancyGuard.isReentrant());
+ if (mRegistrations.isEmpty()) {
+ onRegister();
+ }
+
if (!registration.register()) {
registration.unregister();
+ if (mRegistrations.isEmpty()) {
+ onUnregister();
+ }
return;
}
@@ -210,6 +217,10 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
onRegistrationRemoved(key, registration);
registration.unregister();
updateService();
+
+ if (mRegistrations.isEmpty()) {
+ onUnregister();
+ }
}
/**
@@ -316,10 +327,26 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
protected abstract void unregisterService();
/**
+ * Invoked before the first registration occurs. This is a convenient entry point for
+ * registering listeners, etc, which only need to be present while there are any registrations.
+ * This method will always be invoked before a corresponding call to
+ * {@link Registration#onRegister()} and {@link #onActive()}.
+ */
+ protected void onRegister() {}
+
+ /**
+ * Invoked after the last unregistration occurs. This is a convenient entry point for
+ * unregistering listeners, etc, which only need to be present while there are any
+ * registrations. This method will always be after a corresponding call to
+ * {@link Registration#onUnregister()} and {@link #onInactive()}.
+ */
+ protected void onUnregister() {}
+
+ /**
* Invoked when the listener goes from having no active registrations to having some active
* registrations. This is a convenient entry point for registering listeners, etc, which only
* need to be present while there are active registrations. This method will always be invoked
- * before a corrosponding call to {@link #registerService(Object)}.
+ * before a corresponding call to {@link #registerService(Object)}.
*/
protected void onActive() {}
@@ -327,7 +354,7 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
* Invoked when the listener goes from having some active registrations to having no active
* registrations. This is a convenient entry point for unregistering listeners, etc, which only
* need to be present while there are active registrations. This method will always be invoked
- * after a corrosponding call to {@link #unregisterService()}.
+ * after a corresponding call to {@link #unregisterService()}.
*/
protected void onInactive() {}
diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/com/android/internal/location/ILocationProviderManager.aidl
index 439039148773..1bdedd57f321 100644
--- a/location/java/com/android/internal/location/ILocationProviderManager.aidl
+++ b/location/java/com/android/internal/location/ILocationProviderManager.aidl
@@ -26,7 +26,7 @@ import com.android.internal.location.ProviderProperties;
*/
interface ILocationProviderManager {
- void onSetAdditionalProviderPackages(in List<String> packageNames);
+ void onSetFeatureId(String featureId);
@UnsupportedAppUsage
void onSetAllowed(boolean allowed);
diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt
index 9cc30d0d751e..4d0acea15263 100644
--- a/location/lib/api/current.txt
+++ b/location/lib/api/current.txt
@@ -7,7 +7,8 @@ package com.android.location.provider {
}
public abstract class LocationProviderBase {
- ctor public LocationProviderBase(String, com.android.location.provider.ProviderPropertiesUnbundled);
+ 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();
method @Deprecated @RequiresApi(android.os.Build.VERSION_CODES.Q) public boolean isEnabled();
@@ -20,11 +21,11 @@ package com.android.location.provider {
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 @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setAdditionalProviderPackages(java.util.List<java.lang.String>);
+ 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.Q) public void setEnabled(boolean);
method @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
- field public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
+ field @Deprecated public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
field public static final String FUSED_PROVIDER = "fused";
}
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index d3fb58fe257e..624e8d1b702b 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -39,7 +39,6 @@ import com.android.internal.location.ProviderRequest;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -65,7 +64,10 @@ public abstract class LocationProviderBase {
* Bundle key for a version of the location containing no GPS data.
* Allows location providers to flag locations as being safe to
* feed to LocationFudger.
+ *
+ * @deprecated Do not use from Android R onwards.
*/
+ @Deprecated
public static final String EXTRA_NO_GPS_LOCATION = Location.EXTRA_NO_GPS_LOCATION;
/**
@@ -76,8 +78,9 @@ public abstract class LocationProviderBase {
*/
public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER;
- private final String mTag;
- private final IBinder mBinder;
+ final String mTag;
+ final String mFeatureId;
+ final IBinder mBinder;
/**
* This field may be removed in the future, do not rely on it.
@@ -90,13 +93,30 @@ public abstract class LocationProviderBase {
protected final ILocationManager mLocationManager;
// write locked on mBinder, read lock is optional depending on atomicity requirements
- @Nullable private volatile ILocationProviderManager mManager;
- private volatile ProviderProperties mProperties;
- private volatile boolean mAllowed;
- private final ArrayList<String> mAdditionalProviderPackages;
+ @Nullable
+ volatile ILocationProviderManager mManager;
+ volatile ProviderProperties mProperties;
+ volatile boolean mAllowed;
+ /**
+ * @deprecated Prefer
+ * {@link #LocationProviderBase(Context, String, ProviderPropertiesUnbundled)}.
+ */
+ @Deprecated
public LocationProviderBase(String tag, ProviderPropertiesUnbundled properties) {
+ this(null, tag, properties);
+ }
+
+ /**
+ * This constructor associates the feature id of the given context with this location provider.
+ * The location service may afford special privileges to incoming calls identified as belonging
+ * to this location provider.
+ */
+ @RequiresApi(VERSION_CODES.R)
+ public LocationProviderBase(Context context, String tag,
+ ProviderPropertiesUnbundled properties) {
mTag = tag;
+ mFeatureId = context != null ? context.getFeatureId() : null;
mBinder = new Service();
mLocationManager = ILocationManager.Stub.asInterface(
@@ -105,7 +125,6 @@ public abstract class LocationProviderBase {
mManager = null;
mProperties = properties.getProviderProperties();
mAllowed = true;
- mAdditionalProviderPackages = new ArrayList<>(0);
}
public IBinder getBinder() {
@@ -183,23 +202,12 @@ public abstract class LocationProviderBase {
* another package may issue location requests on behalf of this package in the course of
* providing location. This will inform location services to treat the other packages as
* location providers as well.
+ *
+ * @deprecated On Android R and above this has no effect.
*/
+ @Deprecated
@RequiresApi(VERSION_CODES.Q)
- public void setAdditionalProviderPackages(List<String> packageNames) {
- synchronized (mBinder) {
- mAdditionalProviderPackages.clear();
- mAdditionalProviderPackages.addAll(packageNames);
- }
-
- ILocationProviderManager manager = mManager;
- if (manager != null) {
- try {
- manager.onSetAdditionalProviderPackages(mAdditionalProviderPackages);
- } catch (RemoteException | RuntimeException e) {
- Log.w(mTag, e);
- }
- }
- }
+ public void setAdditionalProviderPackages(List<String> packageNames) {}
/**
* @deprecated Use {@link #isAllowed()} instead.
@@ -317,12 +325,15 @@ public abstract class LocationProviderBase {
private final class Service extends ILocationProvider.Stub {
+ Service() {
+ }
+
@Override
public void setLocationProviderManager(ILocationProviderManager manager) {
synchronized (mBinder) {
try {
- if (!mAdditionalProviderPackages.isEmpty()) {
- manager.onSetAdditionalProviderPackages(mAdditionalProviderPackages);
+ if (mFeatureId != null) {
+ manager.onSetFeatureId(mFeatureId);
}
manager.onSetProperties(mProperties);
manager.onSetAllowed(mAllowed);