Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5afc097 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Show location icon for GNSS measurements"

parents 7347b89f e8272f72
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
    /**
     * Registration object for GNSS listeners.
     */
    protected final class GnssListenerRegistration extends
    protected class GnssListenerRegistration extends
            BinderListenerRegistration<TRequest, TListener> {

        // 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<TRequest, TListener extends IInter
        final long identity = Binder.clearCallingIdentity();
        try {
            addRegistration(listener.asBinder(),
                    new GnssListenerRegistration(request, callerIdentity, listener));
                    createRegistration(request, callerIdentity, listener));
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * May be overridden by subclasses to change the registration type.
     */
    protected GnssListenerRegistration createRegistration(TRequest request,
            CallerIdentity callerIdentity, TListener listener) {
        return new GnssListenerRegistration(request, callerIdentity, listener);
    }

    /**
     * Removes the given listener.
     */
+39 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.location.gnss;
import static com.android.server.location.gnss.GnssManagerService.D;
import static com.android.server.location.gnss.GnssManagerService.TAG;

import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.location.GnssMeasurementsEvent;
import android.location.GnssRequest;
@@ -32,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.server.location.util.AppOpsHelper;
import com.android.server.location.util.Injector;
import com.android.server.location.util.LocationAttributionHelper;
import com.android.server.location.util.LocationUsageLogger;
import com.android.server.location.util.SettingsHelper;

@@ -44,11 +46,40 @@ import java.util.Objects;
 *
 * @hide
 */
public class GnssMeasurementsProvider extends
public final class GnssMeasurementsProvider extends
        GnssListenerMultiplexer<GnssRequest, IGnssMeasurementsListener, Boolean> 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<IGnssMeasurementsListener> onActive() {
            mLocationAttributionHelper.reportHighPowerLocationStart(
                    getIdentity(), GNSS_MEASUREMENTS_BUCKET, getKey());
            return null;
        }

        @Nullable
        @Override
        protected ListenerOperation<IGnssMeasurementsListener> 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<GnssListenerRegistration> registrations) {
+25 −25
Original line number Diff line number Diff line
@@ -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<CallerIdentity, Set<ProviderListener>> mAttributions;
    private final Map<CallerIdentity, Set<BucketKey>> mAttributions;
    @GuardedBy("this")
    private final Map<CallerIdentity, Set<ProviderListener>> mHighPowerAttributions;
    private final Map<CallerIdentity, Set<BucketKey>> 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<ProviderListener> keySet = mAttributions.computeIfAbsent(identity,
        Set<BucketKey> 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<ProviderListener> keySet = mAttributions.get(identity);
        if (keySet != null && keySet.remove(new ProviderListener(provider, key))
        Set<BucketKey> 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<ProviderListener> keySet = mHighPowerAttributions.computeIfAbsent(identity,
        Set<BucketKey> 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<ProviderListener> keySet = mHighPowerAttributions.get(identity);
        if (keySet != null && keySet.remove(new ProviderListener(provider, key))
        Set<BucketKey> 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);