Merge "Updates and fixes to GnssMeasurementsProvider"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5e793ba9d7
@@ -78,13 +78,6 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
|
||||
return mRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the listener, or null if this registration is no longer registered.
|
||||
*/
|
||||
protected @Nullable TListener getListener() {
|
||||
return mListener;
|
||||
}
|
||||
|
||||
boolean register() {
|
||||
Preconditions.checkState(mListener != null);
|
||||
return onRegister();
|
||||
@@ -145,6 +138,9 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
|
||||
@GuardedBy("mRegistrations")
|
||||
private final ReentrancyGuard mReentrancyGuard = new ReentrancyGuard();
|
||||
|
||||
@GuardedBy("mRegistrations")
|
||||
private boolean mActiveRegistrations = false;
|
||||
|
||||
@GuardedBy("mRegistrations")
|
||||
private boolean mServiceRegistered = false;
|
||||
|
||||
@@ -216,36 +212,47 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
|
||||
updateService();
|
||||
}
|
||||
|
||||
@GuardedBy("mRegistrations")
|
||||
private void updateService() {
|
||||
if (Build.IS_DEBUGGABLE) {
|
||||
Preconditions.checkState(Thread.holdsLock(mRegistrations));
|
||||
}
|
||||
|
||||
ArrayList<TRegistration> actives = new ArrayList<>(mRegistrations.size());
|
||||
for (int i = 0; i < mRegistrations.size(); i++) {
|
||||
TRegistration registration = mRegistrations.valueAt(i);
|
||||
if (isActive(registration)) {
|
||||
actives.add(registration);
|
||||
/**
|
||||
* Forces a re-evalution of the active state of all registrations, the merged request for all
|
||||
* active registrations, and service registration state.
|
||||
*/
|
||||
protected void updateService() {
|
||||
synchronized (mRegistrations) {
|
||||
ArrayList<TRegistration> actives = new ArrayList<>(mRegistrations.size());
|
||||
for (int i = 0; i < mRegistrations.size(); i++) {
|
||||
TRegistration registration = mRegistrations.valueAt(i);
|
||||
if (isActive(registration)) {
|
||||
actives.add(registration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (actives.isEmpty()) {
|
||||
if (mServiceRegistered) {
|
||||
unregisterService();
|
||||
mServiceRegistered = false;
|
||||
}
|
||||
mCurrentRequest = null;
|
||||
return;
|
||||
}
|
||||
if (actives.isEmpty()) {
|
||||
if (mServiceRegistered) {
|
||||
unregisterService();
|
||||
mServiceRegistered = false;
|
||||
}
|
||||
mCurrentRequest = null;
|
||||
|
||||
TMergedRequest merged = mergeRequests(actives);
|
||||
if (!mServiceRegistered || !Objects.equals(merged, mCurrentRequest)) {
|
||||
if (mServiceRegistered) {
|
||||
unregisterService();
|
||||
if (mActiveRegistrations) {
|
||||
mActiveRegistrations = false;
|
||||
onInactive();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (!mActiveRegistrations) {
|
||||
mActiveRegistrations = true;
|
||||
onActive();
|
||||
}
|
||||
}
|
||||
|
||||
TMergedRequest merged = mergeRequests(actives);
|
||||
if (!mServiceRegistered || !Objects.equals(merged, mCurrentRequest)) {
|
||||
if (mServiceRegistered) {
|
||||
unregisterService();
|
||||
}
|
||||
mCurrentRequest = merged;
|
||||
mServiceRegistered = registerService(mCurrentRequest);
|
||||
}
|
||||
mCurrentRequest = merged;
|
||||
mServiceRegistered = registerService(mCurrentRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +271,8 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
|
||||
/**
|
||||
* Performs some function on all (not just active) registrations. The function should return
|
||||
* true if the active state of the registration has changed, or if the change to the
|
||||
* registration may have changed the result of {@link #mergeRequests(List)}.
|
||||
* registration may have changed the result of {@link #mergeRequests(List)}. If the function
|
||||
* returns true for any registration, {@link #updateService()} will be invoked.
|
||||
*/
|
||||
protected final void updateRegistrations(@NonNull Function<TRegistration, Boolean> function) {
|
||||
synchronized (mRegistrations) {
|
||||
@@ -307,6 +315,22 @@ public abstract class AbstractListenerManager<TKey, TRequest, TListener,
|
||||
*/
|
||||
protected abstract void unregisterService();
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
*/
|
||||
protected void onActive() {}
|
||||
|
||||
/**
|
||||
* 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()}.
|
||||
*/
|
||||
protected void onInactive() {}
|
||||
|
||||
/**
|
||||
* Invoked when a registration is added.
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.server.location.gnss.GnssManagerService;
|
||||
import com.android.server.location.util.listeners.GnssListenerManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An base implementation for GNSS measurements provider. It abstracts out the responsibility of
|
||||
@@ -37,7 +38,8 @@ import java.util.List;
|
||||
* @hide
|
||||
*/
|
||||
public class GnssMeasurementsProvider extends
|
||||
GnssListenerManager<GnssRequest, IGnssMeasurementsListener, Boolean> {
|
||||
GnssListenerManager<GnssRequest, IGnssMeasurementsListener, Boolean> implements
|
||||
SettingsHelper.GlobalSettingChangedListener {
|
||||
|
||||
private final LocationUsageLogger mLogger;
|
||||
private final GnssMeasurementProviderNative mNative;
|
||||
@@ -94,6 +96,22 @@ public class GnssMeasurementsProvider extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActive() {
|
||||
mSettingsHelper.addOnGnssMeasurementsFullTrackingEnabledChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInactive() {
|
||||
mSettingsHelper.removeOnGnssMeasurementsFullTrackingEnabledChangedListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChanged() {
|
||||
// GNSS Measurements Full Tracking dev setting changed
|
||||
updateService();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean mergeRequests(List<GnssRegistration> registrations) {
|
||||
if (mSettingsHelper.isGnssMeasurementsFullTrackingEnabled()) {
|
||||
@@ -101,7 +119,7 @@ public class GnssMeasurementsProvider extends
|
||||
}
|
||||
|
||||
for (GnssRegistration registration : registrations) {
|
||||
if (registration.getRequest().isFullTracking()) {
|
||||
if (Objects.requireNonNull(registration.getRequest()).isFullTracking()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ public class SettingsHelper {
|
||||
|
||||
private final IntegerSecureSetting mLocationMode;
|
||||
private final LongGlobalSetting mBackgroundThrottleIntervalMs;
|
||||
private final BooleanGlobalSetting mGnssMeasurementFullTracking;
|
||||
private final StringListCachedSecureSetting mLocationPackageBlacklist;
|
||||
private final StringListCachedSecureSetting mLocationPackageWhitelist;
|
||||
private final StringSetCachedGlobalSetting mBackgroundThrottlePackageWhitelist;
|
||||
@@ -110,6 +111,8 @@ public class SettingsHelper {
|
||||
mLocationMode = new IntegerSecureSetting(context, LOCATION_MODE, handler);
|
||||
mBackgroundThrottleIntervalMs = new LongGlobalSetting(context,
|
||||
LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS, handler);
|
||||
mGnssMeasurementFullTracking = new BooleanGlobalSetting(context,
|
||||
ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, handler);
|
||||
mLocationPackageBlacklist = new StringListCachedSecureSetting(context,
|
||||
LOCATION_PACKAGE_BLACKLIST, handler);
|
||||
mLocationPackageWhitelist = new StringListCachedSecureSetting(context,
|
||||
@@ -245,6 +248,30 @@ public class SettingsHelper {
|
||||
mBackgroundThrottlePackageWhitelist.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the gnss measurements full tracking enabled setting.
|
||||
*/
|
||||
public boolean isGnssMeasurementsFullTrackingEnabled() {
|
||||
return mGnssMeasurementFullTracking.getValue(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for changes to the background throttle package whitelist. Callbacks occur on
|
||||
* an unspecified thread.
|
||||
*/
|
||||
public void addOnGnssMeasurementsFullTrackingEnabledChangedListener(
|
||||
GlobalSettingChangedListener listener) {
|
||||
mGnssMeasurementFullTracking.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a listener for changes to the background throttle package whitelist.
|
||||
*/
|
||||
public void removeOnGnssMeasurementsFullTrackingEnabledChangedListener(
|
||||
GlobalSettingChangedListener listener) {
|
||||
mGnssMeasurementFullTracking.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the ignore settings package whitelist.
|
||||
*/
|
||||
@@ -283,19 +310,6 @@ public class SettingsHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the gnss measurements full tracking enabled setting.
|
||||
*/
|
||||
public boolean isGnssMeasurementsFullTrackingEnabled() {
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(),
|
||||
ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0) == 1;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the accuracy for coarsening location, ie, the grid size used for snap-to-grid
|
||||
* coarsening.
|
||||
@@ -395,7 +409,7 @@ public class SettingsHelper {
|
||||
@GuardedBy("this")
|
||||
private boolean mRegistered;
|
||||
|
||||
private ObservingSetting(Handler handler) {
|
||||
ObservingSetting(Handler handler) {
|
||||
super(handler);
|
||||
mListeners = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
@@ -439,13 +453,13 @@ public class SettingsHelper {
|
||||
private final Context mContext;
|
||||
private final String mSettingName;
|
||||
|
||||
private IntegerSecureSetting(Context context, String settingName, Handler handler) {
|
||||
IntegerSecureSetting(Context context, String settingName, Handler handler) {
|
||||
super(handler);
|
||||
mContext = context;
|
||||
mSettingName = settingName;
|
||||
}
|
||||
|
||||
private void register() {
|
||||
void register() {
|
||||
register(mContext, Settings.Secure.getUriFor(mSettingName));
|
||||
}
|
||||
|
||||
@@ -470,7 +484,7 @@ public class SettingsHelper {
|
||||
@GuardedBy("this")
|
||||
private List<String> mCachedValue;
|
||||
|
||||
private StringListCachedSecureSetting(Context context, String settingName,
|
||||
StringListCachedSecureSetting(Context context, String settingName,
|
||||
Handler handler) {
|
||||
super(handler);
|
||||
mContext = context;
|
||||
@@ -524,12 +538,38 @@ public class SettingsHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BooleanGlobalSetting extends ObservingSetting {
|
||||
|
||||
private final Context mContext;
|
||||
private final String mSettingName;
|
||||
|
||||
BooleanGlobalSetting(Context context, String settingName, Handler handler) {
|
||||
super(handler);
|
||||
mContext = context;
|
||||
mSettingName = settingName;
|
||||
}
|
||||
|
||||
public void register() {
|
||||
register(mContext, Settings.Global.getUriFor(mSettingName));
|
||||
}
|
||||
|
||||
public boolean getValue(boolean defaultValue) {
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return Settings.Global.getInt(mContext.getContentResolver(), mSettingName,
|
||||
defaultValue ? 1 : 0) != 0;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class LongGlobalSetting extends ObservingSetting {
|
||||
|
||||
private final Context mContext;
|
||||
private final String mSettingName;
|
||||
|
||||
private LongGlobalSetting(Context context, String settingName, Handler handler) {
|
||||
LongGlobalSetting(Context context, String settingName, Handler handler) {
|
||||
super(handler);
|
||||
mContext = context;
|
||||
mSettingName = settingName;
|
||||
@@ -561,7 +601,7 @@ public class SettingsHelper {
|
||||
@GuardedBy("this")
|
||||
private ArraySet<String> mCachedValue;
|
||||
|
||||
private StringSetCachedGlobalSetting(Context context, String settingName,
|
||||
StringSetCachedGlobalSetting(Context context, String settingName,
|
||||
Supplier<ArraySet<String>> baseValuesSupplier, Handler handler) {
|
||||
super(handler);
|
||||
mContext = context;
|
||||
|
||||
@@ -313,9 +313,8 @@ public class GnssManagerService {
|
||||
/**
|
||||
* Adds a GNSS measurements listener.
|
||||
*/
|
||||
public void addGnssMeasurementsListener(@Nullable GnssRequest request,
|
||||
IGnssMeasurementsListener listener, String packageName,
|
||||
@Nullable String featureId) {
|
||||
public void addGnssMeasurementsListener(GnssRequest request, IGnssMeasurementsListener listener,
|
||||
String packageName, @Nullable String featureId) {
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);
|
||||
if (request.isFullTracking()) {
|
||||
mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class AbstractListenerManagerTest {
|
||||
|
||||
mListenerManager.addListener(0, listener);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(0);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -69,6 +70,7 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.addListener(0, listener);
|
||||
mListenerManager.removeListener(listener);
|
||||
assertThat(mListenerManager.mRegistered).isFalse();
|
||||
assertThat(mListenerManager.mActive).isFalse();
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
verify(listener, never()).run();
|
||||
@@ -83,6 +85,7 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.addListener(0, listener1);
|
||||
mListenerManager.addListener(1, listener2);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(1);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -92,6 +95,7 @@ public class AbstractListenerManagerTest {
|
||||
|
||||
mListenerManager.addListener(0, listener3);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(1);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -101,6 +105,7 @@ public class AbstractListenerManagerTest {
|
||||
|
||||
mListenerManager.removeListener(listener2);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(0);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -111,6 +116,7 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.removeListener(listener1);
|
||||
mListenerManager.removeListener(listener3);
|
||||
assertThat(mListenerManager.mRegistered).isFalse();
|
||||
assertThat(mListenerManager.mActive).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,12 +139,14 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.addListener(0, listener);
|
||||
mListenerManager.setActive(0, false);
|
||||
assertThat(mListenerManager.mRegistered).isFalse();
|
||||
assertThat(mListenerManager.mActive).isFalse();
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
verify(listener, never()).run();
|
||||
|
||||
mListenerManager.setActive(0, true);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(0);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -155,6 +163,7 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.addListener(2, listener2);
|
||||
mListenerManager.addListener(1, listener3);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(2);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -164,6 +173,7 @@ public class AbstractListenerManagerTest {
|
||||
|
||||
mListenerManager.setActive(2, false);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(1);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -173,6 +183,7 @@ public class AbstractListenerManagerTest {
|
||||
|
||||
mListenerManager.setActive(2, true);
|
||||
assertThat(mListenerManager.mRegistered).isTrue();
|
||||
assertThat(mListenerManager.mActive).isTrue();
|
||||
assertThat(mListenerManager.mMergedRequest).isEqualTo(2);
|
||||
|
||||
mListenerManager.notifyListeners();
|
||||
@@ -184,12 +195,13 @@ public class AbstractListenerManagerTest {
|
||||
mListenerManager.setActive(1, false);
|
||||
mListenerManager.setActive(2, false);
|
||||
assertThat(mListenerManager.mRegistered).isFalse();
|
||||
assertThat(mListenerManager.mActive).isFalse();
|
||||
}
|
||||
|
||||
private static class TestRegistration extends
|
||||
AbstractListenerManager.Registration<Integer, Runnable> {
|
||||
|
||||
private boolean mActive = true;
|
||||
boolean mActive = true;
|
||||
|
||||
protected TestRegistration(Integer integer, Runnable runnable) {
|
||||
super(integer, DIRECT_EXECUTOR, runnable);
|
||||
@@ -199,8 +211,12 @@ public class AbstractListenerManagerTest {
|
||||
private static class TestListenerManager extends
|
||||
AbstractListenerManager<Runnable, Integer, Runnable, TestRegistration, Integer> {
|
||||
|
||||
private boolean mRegistered;
|
||||
private int mMergedRequest;
|
||||
boolean mActive;
|
||||
boolean mRegistered;
|
||||
int mMergedRequest;
|
||||
|
||||
TestListenerManager() {
|
||||
}
|
||||
|
||||
public void addListener(Integer request, Runnable listener) {
|
||||
addRegistration(listener, new TestRegistration(request, listener));
|
||||
@@ -245,6 +261,16 @@ public class AbstractListenerManagerTest {
|
||||
return registration.mActive;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActive() {
|
||||
mActive = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInactive() {
|
||||
mActive = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer mergeRequests(List<TestRegistration> testRegistrations) {
|
||||
int max = Integer.MIN_VALUE;
|
||||
|
||||
Reference in New Issue
Block a user