Merge "Add LocationManager#registerProviderRequestListener" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
15c8bf6793
@@ -4666,6 +4666,7 @@ package android.location {
|
||||
method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public boolean isProviderPackage(@Nullable String, @NonNull String, @Nullable String);
|
||||
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.UPDATE_APP_OPS_STATS}) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.GnssMeasurementsEvent.Callback);
|
||||
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerProviderRequestListener(@NonNull java.util.concurrent.Executor, @NonNull android.location.provider.ProviderRequest.Listener);
|
||||
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
|
||||
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener);
|
||||
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent);
|
||||
@@ -4674,6 +4675,7 @@ package android.location {
|
||||
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
|
||||
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
|
||||
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void unregisterProviderRequestListener(@NonNull android.location.provider.ProviderRequest.Listener);
|
||||
}
|
||||
|
||||
public final class LocationRequest implements android.os.Parcelable {
|
||||
@@ -4823,6 +4825,10 @@ package android.location.provider {
|
||||
method @NonNull public android.location.provider.ProviderRequest.Builder setWorkSource(@NonNull android.os.WorkSource);
|
||||
}
|
||||
|
||||
public static interface ProviderRequest.Listener {
|
||||
method public void onProviderRequestChanged(@NonNull String, @NonNull android.location.provider.ProviderRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.media {
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.location.LastLocationRequest;
|
||||
import android.location.Location;
|
||||
import android.location.LocationRequest;
|
||||
import android.location.LocationTime;
|
||||
import android.location.provider.IProviderRequestListener;
|
||||
import android.location.provider.ProviderProperties;
|
||||
import android.os.Bundle;
|
||||
import android.os.ICancellationSignal;
|
||||
@@ -91,6 +92,9 @@ interface ILocationManager
|
||||
void addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener, String packageName, @nullable String attributionTag);
|
||||
void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener);
|
||||
|
||||
void addProviderRequestListener(in IProviderRequestListener listener);
|
||||
void removeProviderRequestListener(in IProviderRequestListener listener);
|
||||
|
||||
int getGnssBatchSize();
|
||||
void startGnssBatch(long periodNanos, in ILocationListener listener, String packageName, @nullable String attributionTag, @nullable String listenerId);
|
||||
void flushGnssBatch();
|
||||
|
||||
@@ -49,7 +49,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.provider.IProviderRequestListener;
|
||||
import android.location.provider.ProviderProperties;
|
||||
import android.location.provider.ProviderRequest;
|
||||
import android.location.provider.ProviderRequest.Listener;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
@@ -436,6 +439,9 @@ public class LocationManager {
|
||||
new GnssNavigationTransportManager();
|
||||
}
|
||||
|
||||
private static final ProviderRequestTransportManager sProviderRequestListeners =
|
||||
new ProviderRequestTransportManager();
|
||||
|
||||
private final Context mContext;
|
||||
private final ILocationManager mService;
|
||||
|
||||
@@ -2771,6 +2777,37 @@ public class LocationManager {
|
||||
GnssLazyLoader.sGnssNavigationListeners.removeListener(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link ProviderRequest.Listener} to all providers.
|
||||
*
|
||||
* @param executor the executor that the callback runs on
|
||||
* @param listener the listener to register
|
||||
* @return {@code true} always
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
|
||||
public boolean registerProviderRequestListener(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull Listener listener) {
|
||||
sProviderRequestListeners.addListener(listener,
|
||||
new ProviderRequestTransport(executor, listener));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a {@link ProviderRequest.Listener}.
|
||||
*
|
||||
* @param listener the listener to remove.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
|
||||
public void unregisterProviderRequestListener(
|
||||
@NonNull Listener listener) {
|
||||
sProviderRequestListeners.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the batch size (in number of Location objects) that are supported by the batching
|
||||
* interface.
|
||||
@@ -2960,6 +2997,22 @@ public class LocationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ProviderRequestTransportManager extends
|
||||
ListenerTransportManager<ProviderRequestTransport> {
|
||||
|
||||
@Override
|
||||
protected void registerTransport(ProviderRequestTransport transport)
|
||||
throws RemoteException {
|
||||
getService().addProviderRequestListener(transport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void unregisterTransport(ProviderRequestTransport transport)
|
||||
throws RemoteException {
|
||||
getService().removeProviderRequestListener(transport);
|
||||
}
|
||||
}
|
||||
|
||||
private static class GetCurrentLocationTransport extends ILocationCallback.Stub implements
|
||||
ListenerExecutor, CancellationSignal.OnCancelListener {
|
||||
|
||||
@@ -3359,6 +3412,36 @@ public class LocationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ProviderRequestTransport extends IProviderRequestListener.Stub
|
||||
implements ListenerTransport<ProviderRequest.Listener> {
|
||||
|
||||
private final Executor mExecutor;
|
||||
|
||||
private volatile @Nullable ProviderRequest.Listener mListener;
|
||||
|
||||
ProviderRequestTransport(Executor executor, ProviderRequest.Listener listener) {
|
||||
Preconditions.checkArgument(executor != null, "invalid null executor");
|
||||
Preconditions.checkArgument(listener != null, "invalid null callback");
|
||||
mExecutor = executor;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ProviderRequest.Listener getListener() {
|
||||
return mListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderRequestChanged(String provider, ProviderRequest request) {
|
||||
execute(mExecutor, listener -> listener.onProviderRequestChanged(provider, request));
|
||||
}
|
||||
}
|
||||
|
||||
private static class BatchedLocationCallbackWrapper implements LocationListener {
|
||||
|
||||
private final BatchedLocationCallback mCallback;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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 android.location.provider;
|
||||
|
||||
import android.location.provider.ProviderRequest;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IProviderRequestListener {
|
||||
void onProviderRequestChanged(String provider, in ProviderRequest request);
|
||||
}
|
||||
@@ -53,6 +53,17 @@ public final class ProviderRequest implements Parcelable {
|
||||
private final boolean mLocationSettingsIgnored;
|
||||
private final WorkSource mWorkSource;
|
||||
|
||||
/**
|
||||
* Listener to be invoked when a new request is set to the provider.
|
||||
*/
|
||||
public interface Listener {
|
||||
|
||||
/**
|
||||
* Invoked when a new request is set.
|
||||
*/
|
||||
void onProviderRequestChanged(@NonNull String provider, @NonNull ProviderRequest request);
|
||||
}
|
||||
|
||||
private ProviderRequest(
|
||||
long intervalMillis,
|
||||
@Quality int quality,
|
||||
|
||||
@@ -66,6 +66,7 @@ import android.location.LocationManagerInternal;
|
||||
import android.location.LocationProvider;
|
||||
import android.location.LocationRequest;
|
||||
import android.location.LocationTime;
|
||||
import android.location.provider.IProviderRequestListener;
|
||||
import android.location.provider.ProviderProperties;
|
||||
import android.location.util.identity.CallerIdentity;
|
||||
import android.os.Binder;
|
||||
@@ -881,6 +882,20 @@ public class LocationManagerService extends ILocationManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProviderRequestListener(IProviderRequestListener listener) {
|
||||
for (LocationProviderManager manager : mProviderManagers) {
|
||||
manager.addProviderRequestListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProviderRequestListener(IProviderRequestListener listener) {
|
||||
for (LocationProviderManager manager : mProviderManagers) {
|
||||
manager.removeProviderRequestListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectGnssMeasurementCorrections(GnssMeasurementCorrections corrections) {
|
||||
if (mGnssManagerService != null) {
|
||||
|
||||
@@ -55,6 +55,7 @@ import android.location.LocationManagerInternal;
|
||||
import android.location.LocationManagerInternal.ProviderEnabledListener;
|
||||
import android.location.LocationRequest;
|
||||
import android.location.LocationResult;
|
||||
import android.location.provider.IProviderRequestListener;
|
||||
import android.location.provider.ProviderProperties;
|
||||
import android.location.provider.ProviderRequest;
|
||||
import android.location.util.identity.CallerIdentity;
|
||||
@@ -117,6 +118,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -1219,6 +1221,8 @@ public class LocationProviderManager extends
|
||||
@GuardedBy("mLock")
|
||||
private final ArrayList<ProviderEnabledListener> mEnabledListeners;
|
||||
|
||||
private final CopyOnWriteArrayList<IProviderRequestListener> mProviderRequestListeners;
|
||||
|
||||
protected final LocationManagerInternal mLocationManagerInternal;
|
||||
protected final SettingsHelper mSettingsHelper;
|
||||
protected final UserInfoHelper mUserHelper;
|
||||
@@ -1279,6 +1283,7 @@ public class LocationProviderManager extends
|
||||
mLastLocations = new SparseArray<>(2);
|
||||
|
||||
mEnabledListeners = new ArrayList<>();
|
||||
mProviderRequestListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
mLocationManagerInternal = Objects.requireNonNull(
|
||||
LocalServices.getService(LocationManagerInternal.class));
|
||||
@@ -1344,6 +1349,7 @@ public class LocationProviderManager extends
|
||||
// if external entities are registering listeners it's their responsibility to
|
||||
// unregister them before stopManager() is called
|
||||
Preconditions.checkState(mEnabledListeners.isEmpty());
|
||||
mProviderRequestListeners.clear();
|
||||
|
||||
mEnabled.clear();
|
||||
mLastLocations.clear();
|
||||
@@ -1404,6 +1410,16 @@ public class LocationProviderManager extends
|
||||
}
|
||||
}
|
||||
|
||||
/** Add a {@link IProviderRequestListener}. */
|
||||
public void addProviderRequestListener(IProviderRequestListener listener) {
|
||||
mProviderRequestListeners.add(listener);
|
||||
}
|
||||
|
||||
/** Remove a {@link IProviderRequestListener}. */
|
||||
public void removeProviderRequestListener(IProviderRequestListener listener) {
|
||||
mProviderRequestListeners.remove(listener);
|
||||
}
|
||||
|
||||
public void setRealProvider(@Nullable AbstractLocationProvider provider) {
|
||||
synchronized (mLock) {
|
||||
Preconditions.checkState(mState != STATE_STOPPED);
|
||||
@@ -1873,8 +1889,7 @@ public class LocationProviderManager extends
|
||||
Preconditions.checkState(delayMs >= 0 && delayMs <= newRequest.getIntervalMillis());
|
||||
|
||||
if (delayMs < MIN_REQUEST_DELAY_MS) {
|
||||
mLocationEventLog.logProviderUpdateRequest(mName, newRequest);
|
||||
mProvider.getController().setRequest(newRequest);
|
||||
setProviderRequest(newRequest);
|
||||
} else {
|
||||
if (D) {
|
||||
Log.d(TAG, mName + " provider delaying request update " + newRequest + " by "
|
||||
@@ -1886,8 +1901,7 @@ public class LocationProviderManager extends
|
||||
public void onAlarm() {
|
||||
synchronized (mLock) {
|
||||
if (mDelayedRegister == this) {
|
||||
mLocationEventLog.logProviderUpdateRequest(mName, newRequest);
|
||||
mProvider.getController().setRequest(newRequest);
|
||||
setProviderRequest(newRequest);
|
||||
mDelayedRegister = null;
|
||||
}
|
||||
}
|
||||
@@ -1906,8 +1920,23 @@ public class LocationProviderManager extends
|
||||
Preconditions.checkState(Thread.holdsLock(mLock));
|
||||
}
|
||||
|
||||
mLocationEventLog.logProviderUpdateRequest(mName, ProviderRequest.EMPTY_REQUEST);
|
||||
mProvider.getController().setRequest(ProviderRequest.EMPTY_REQUEST);
|
||||
setProviderRequest(ProviderRequest.EMPTY_REQUEST);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void setProviderRequest(ProviderRequest request) {
|
||||
mLocationEventLog.logProviderUpdateRequest(mName, request);
|
||||
mProvider.getController().setRequest(request);
|
||||
|
||||
FgThread.getHandler().post(() -> {
|
||||
for (IProviderRequestListener listener : mProviderRequestListeners) {
|
||||
try {
|
||||
listener.onProviderRequestChanged(mName, request);
|
||||
} catch (RemoteException e) {
|
||||
mProviderRequestListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
|
||||
@@ -64,6 +64,7 @@ import android.location.LocationManagerInternal;
|
||||
import android.location.LocationManagerInternal.ProviderEnabledListener;
|
||||
import android.location.LocationRequest;
|
||||
import android.location.LocationResult;
|
||||
import android.location.provider.IProviderRequestListener;
|
||||
import android.location.provider.ProviderProperties;
|
||||
import android.location.provider.ProviderRequest;
|
||||
import android.location.util.identity.CallerIdentity;
|
||||
@@ -661,6 +662,23 @@ public class LocationProviderManagerTest {
|
||||
.onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderRequestListener() throws Exception {
|
||||
IProviderRequestListener requestListener = mock(IProviderRequestListener.class);
|
||||
mManager.addProviderRequestListener(requestListener);
|
||||
|
||||
ILocationListener locationListener = createMockLocationListener();
|
||||
LocationRequest request = new LocationRequest.Builder(1).setWorkSource(
|
||||
WORK_SOURCE).build();
|
||||
mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, locationListener);
|
||||
|
||||
verify(requestListener, timeout(TIMEOUT_MS).times(1)).onProviderRequestChanged(anyString(),
|
||||
any(ProviderRequest.class));
|
||||
|
||||
mManager.unregisterLocationRequest(locationListener);
|
||||
mManager.removeProviderRequestListener(requestListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCurrentLocation() throws Exception {
|
||||
ILocationCallback listener = createMockGetCurrentLocationListener();
|
||||
|
||||
Reference in New Issue
Block a user