diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java index b94f1555cfaa9..ec48d4cbcecd5 100644 --- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java @@ -67,7 +67,7 @@ public abstract class GnssListenerMultiplexer { // we store these values because we don't trust the listeners not to give us dupes, not to @@ -232,12 +232,20 @@ public abstract class GnssListenerMultiplexer implements SettingsHelper.GlobalSettingChangedListener { + private class GnssMeasurementListenerRegistration extends GnssListenerRegistration { + + private static final String GNSS_MEASUREMENTS_BUCKET = "gnss_measurement"; + + protected GnssMeasurementListenerRegistration( + @Nullable GnssRequest gnssRequest, + CallerIdentity callerIdentity, + IGnssMeasurementsListener iGnssMeasurementsListener) { + super(gnssRequest, callerIdentity, iGnssMeasurementsListener); + } + + @Nullable + @Override + protected ListenerOperation onActive() { + mLocationAttributionHelper.reportHighPowerLocationStart( + getIdentity(), GNSS_MEASUREMENTS_BUCKET, getKey()); + return null; + } + + @Nullable + @Override + protected ListenerOperation onInactive() { + mLocationAttributionHelper.reportHighPowerLocationStop( + getIdentity(), GNSS_MEASUREMENTS_BUCKET, getKey()); + return null; + } + } + private final AppOpsHelper mAppOpsHelper; + private final LocationAttributionHelper mLocationAttributionHelper; private final LocationUsageLogger mLogger; private final GnssMeasurementProviderNative mNative; @@ -60,6 +91,7 @@ public class GnssMeasurementsProvider extends public GnssMeasurementsProvider(Injector injector, GnssMeasurementProviderNative aNative) { super(injector); mAppOpsHelper = injector.getAppOpsHelper(); + mLocationAttributionHelper = injector.getLocationAttributionHelper(); mLogger = injector.getLocationUsageLogger(); mNative = aNative; } @@ -75,6 +107,12 @@ public class GnssMeasurementsProvider extends super.addListener(request, identity, listener); } + @Override + protected GnssListenerRegistration createRegistration(GnssRequest request, + CallerIdentity callerIdentity, IGnssMeasurementsListener listener) { + return new GnssMeasurementListenerRegistration(request, callerIdentity, listener); + } + @Override protected boolean registerWithService(Boolean fullTrackingRequest, Collection registrations) { diff --git a/services/core/java/com/android/server/location/util/LocationAttributionHelper.java b/services/core/java/com/android/server/location/util/LocationAttributionHelper.java index bc3ac0ff2e487..36b3ef31ef488 100644 --- a/services/core/java/com/android/server/location/util/LocationAttributionHelper.java +++ b/services/core/java/com/android/server/location/util/LocationAttributionHelper.java @@ -38,12 +38,12 @@ import java.util.Set; */ public class LocationAttributionHelper { - private static class ProviderListener { - private final String mProvider; + private static class BucketKey { + private final String mBucket; private final Object mKey; - private ProviderListener(String provider, Object key) { - mProvider = Objects.requireNonNull(provider); + private BucketKey(String bucket, Object key) { + mBucket = Objects.requireNonNull(bucket); mKey = Objects.requireNonNull(key); } @@ -56,23 +56,23 @@ public class LocationAttributionHelper { return false; } - ProviderListener that = (ProviderListener) o; - return mProvider.equals(that.mProvider) + BucketKey that = (BucketKey) o; + return mBucket.equals(that.mBucket) && mKey.equals(that.mKey); } @Override public int hashCode() { - return Objects.hash(mProvider, mKey); + return Objects.hash(mBucket, mKey); } } private final AppOpsHelper mAppOpsHelper; @GuardedBy("this") - private final Map> mAttributions; + private final Map> mAttributions; @GuardedBy("this") - private final Map> mHighPowerAttributions; + private final Map> mHighPowerAttributions; public LocationAttributionHelper(AppOpsHelper appOpsHelper) { mAppOpsHelper = appOpsHelper; @@ -82,14 +82,14 @@ public class LocationAttributionHelper { } /** - * Report normal location usage for the given caller on the given provider, with a unique key. + * Report normal location usage for the given caller in the given bucket, with a unique key. */ - public synchronized void reportLocationStart(CallerIdentity identity, String provider, + public synchronized void reportLocationStart(CallerIdentity identity, String bucket, Object key) { - Set keySet = mAttributions.computeIfAbsent(identity, + Set keySet = mAttributions.computeIfAbsent(identity, i -> new ArraySet<>()); boolean empty = keySet.isEmpty(); - if (keySet.add(new ProviderListener(provider, key)) && empty) { + if (keySet.add(new BucketKey(bucket, key)) && empty) { if (!mAppOpsHelper.startOpNoThrow(OP_MONITOR_LOCATION, identity)) { mAttributions.remove(identity); } @@ -97,13 +97,13 @@ public class LocationAttributionHelper { } /** - * Report normal location usage has stopped for the given caller on the given provider, with a + * Report normal location usage has stopped for the given caller in the given bucket, with a * unique key. */ - public synchronized void reportLocationStop(CallerIdentity identity, String provider, + public synchronized void reportLocationStop(CallerIdentity identity, String bucket, Object key) { - Set keySet = mAttributions.get(identity); - if (keySet != null && keySet.remove(new ProviderListener(provider, key)) + Set keySet = mAttributions.get(identity); + if (keySet != null && keySet.remove(new BucketKey(bucket, key)) && keySet.isEmpty()) { mAttributions.remove(identity); mAppOpsHelper.finishOp(OP_MONITOR_LOCATION, identity); @@ -111,15 +111,15 @@ public class LocationAttributionHelper { } /** - * Report high power location usage for the given caller on the given provider, with a unique + * Report high power location usage for the given caller in the given bucket, with a unique * key. */ - public synchronized void reportHighPowerLocationStart(CallerIdentity identity, String provider, + public synchronized void reportHighPowerLocationStart(CallerIdentity identity, String bucket, Object key) { - Set keySet = mHighPowerAttributions.computeIfAbsent(identity, + Set keySet = mHighPowerAttributions.computeIfAbsent(identity, i -> new ArraySet<>()); boolean empty = keySet.isEmpty(); - if (keySet.add(new ProviderListener(provider, key)) && empty) { + if (keySet.add(new BucketKey(bucket, key)) && empty) { if (mAppOpsHelper.startOpNoThrow(OP_MONITOR_HIGH_POWER_LOCATION, identity)) { if (D) { Log.v(TAG, "starting high power location attribution for " + identity); @@ -131,13 +131,13 @@ public class LocationAttributionHelper { } /** - * Report high power location usage has stopped for the given caller on the given provider, + * Report high power location usage has stopped for the given caller in the given bucket, * with a unique key. */ - public synchronized void reportHighPowerLocationStop(CallerIdentity identity, String provider, + public synchronized void reportHighPowerLocationStop(CallerIdentity identity, String bucket, Object key) { - Set keySet = mHighPowerAttributions.get(identity); - if (keySet != null && keySet.remove(new ProviderListener(provider, key)) + Set keySet = mHighPowerAttributions.get(identity); + if (keySet != null && keySet.remove(new BucketKey(bucket, key)) && keySet.isEmpty()) { if (D) { Log.v(TAG, "stopping high power location attribution for " + identity);