diff --git a/location/java/android/location/util/listeners/AbstractListenerManager.java b/location/java/android/location/util/listeners/AbstractListenerManager.java index d2adab0aa9d91..facb74766f2c6 100644 --- a/location/java/android/location/util/listeners/AbstractListenerManager.java +++ b/location/java/android/location/util/listeners/AbstractListenerManager.java @@ -78,13 +78,6 @@ public abstract class AbstractListenerManager 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 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 function) { synchronized (mRegistrations) { @@ -307,6 +315,22 @@ public abstract class AbstractListenerManager { + GnssListenerManager 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 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; } } diff --git a/services/core/java/com/android/server/location/SettingsHelper.java b/services/core/java/com/android/server/location/SettingsHelper.java index 5ca83f9981072..b9320249a88e5 100644 --- a/services/core/java/com/android/server/location/SettingsHelper.java +++ b/services/core/java/com/android/server/location/SettingsHelper.java @@ -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 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 mCachedValue; - private StringSetCachedGlobalSetting(Context context, String settingName, + StringSetCachedGlobalSetting(Context context, String settingName, Supplier> baseValuesSupplier, Handler handler) { super(handler); mContext = context; diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 2c7ad97be100c..0067b1a436599 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -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); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/util/listeners/AbstractListenerManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/util/listeners/AbstractListenerManagerTest.java index cb821eb091e06..36d79123ddf20 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/util/listeners/AbstractListenerManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/util/listeners/AbstractListenerManagerTest.java @@ -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 { - 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 { - 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 testRegistrations) { int max = Integer.MIN_VALUE;