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

Commit 5da51fef authored by Soonil Nagarkar's avatar Soonil Nagarkar Committed by Android (Google) Code Review
Browse files

Merge "Listen for PACKAGE_RESET queries and events"

parents a42581f5 75daba97
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
{
    "presubmit": [
        {
            "name": "CtsLocationFineTestCases"
        },
        {
            "name": "CtsLocationCoarseTestCases"
        },
@@ -66,10 +69,5 @@
            ],
            "file_patterns": ["ClipboardService\\.java"]
        }
    ],
    "postsubmit": [
        {
            "name": "CtsLocationFineTestCases"
        }
    ]
}
+11 −1
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ import com.android.server.location.injector.Injector;
import com.android.server.location.injector.LocationPermissionsHelper;
import com.android.server.location.injector.LocationPowerSaveModeHelper;
import com.android.server.location.injector.LocationUsageLogger;
import com.android.server.location.injector.PackageResetHelper;
import com.android.server.location.injector.ScreenInteractiveHelper;
import com.android.server.location.injector.SettingsHelper;
import com.android.server.location.injector.SystemAlarmHelper;
@@ -125,6 +126,7 @@ import com.android.server.location.injector.SystemDeviceStationaryHelper;
import com.android.server.location.injector.SystemEmergencyHelper;
import com.android.server.location.injector.SystemLocationPermissionsHelper;
import com.android.server.location.injector.SystemLocationPowerSaveModeHelper;
import com.android.server.location.injector.SystemPackageResetHelper;
import com.android.server.location.injector.SystemScreenInteractiveHelper;
import com.android.server.location.injector.SystemSettingsHelper;
import com.android.server.location.injector.SystemUserInfoHelper;
@@ -1696,11 +1698,13 @@ public class LocationManagerService extends ILocationManager.Stub implements
        private final SystemDeviceStationaryHelper mDeviceStationaryHelper;
        private final SystemDeviceIdleHelper mDeviceIdleHelper;
        private final LocationUsageLogger mLocationUsageLogger;
        private final PackageResetHelper mPackageResetHelper;

        // lazily instantiated since they may not always be used

        @GuardedBy("this")
        private @Nullable SystemEmergencyHelper mEmergencyCallHelper;
        @Nullable
        private SystemEmergencyHelper mEmergencyCallHelper;

        @GuardedBy("this")
        private boolean mSystemReady;
@@ -1721,6 +1725,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
            mDeviceStationaryHelper = new SystemDeviceStationaryHelper();
            mDeviceIdleHelper = new SystemDeviceIdleHelper(context);
            mLocationUsageLogger = new LocationUsageLogger();
            mPackageResetHelper = new SystemPackageResetHelper(context);
        }

        synchronized void onSystemReady() {
@@ -1811,5 +1816,10 @@ public class LocationManagerService extends ILocationManager.Stub implements
        public LocationUsageLogger getLocationUsageLogger() {
            return mLocationUsageLogger;
        }

        @Override
        public PackageResetHelper getPackageResetHelper() {
            return mPackageResetHelper;
        }
    }
}
+38 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.server.LocalServices;
import com.android.server.location.injector.AppForegroundHelper;
import com.android.server.location.injector.Injector;
import com.android.server.location.injector.LocationPermissionsHelper;
import com.android.server.location.injector.PackageResetHelper;
import com.android.server.location.injector.SettingsHelper;
import com.android.server.location.injector.UserInfoHelper;
import com.android.server.location.injector.UserInfoHelper.UserListener;
@@ -193,6 +194,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
    protected final LocationPermissionsHelper mLocationPermissionsHelper;
    protected final AppForegroundHelper mAppForegroundHelper;
    protected final LocationManagerInternal mLocationManagerInternal;
    private final PackageResetHelper mPackageResetHelper;

    private final UserListener mUserChangedListener = this::onUserChanged;
    private final ProviderEnabledListener mProviderEnabledChangedListener =
@@ -218,12 +220,25 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
            };
    private final AppForegroundHelper.AppForegroundListener mAppForegroundChangedListener =
            this::onAppForegroundChanged;
    private final PackageResetHelper.Responder mPackageResetResponder =
            new PackageResetHelper.Responder() {
                @Override
                public void onPackageReset(String packageName) {
                    GnssListenerMultiplexer.this.onPackageReset(packageName);
                }

                @Override
                public boolean isResetableForPackage(String packageName) {
                    return GnssListenerMultiplexer.this.isResetableForPackage(packageName);
                }
            };

    protected GnssListenerMultiplexer(Injector injector) {
        mUserInfoHelper = injector.getUserInfoHelper();
        mSettingsHelper = injector.getSettingsHelper();
        mLocationPermissionsHelper = injector.getLocationPermissionsHelper();
        mAppForegroundHelper = injector.getAppForegroundHelper();
        mPackageResetHelper = injector.getPackageResetHelper();
        mLocationManagerInternal = Objects.requireNonNull(
                LocalServices.getService(LocationManagerInternal.class));
    }
@@ -357,6 +372,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
                mLocationPackageBlacklistChangedListener);
        mLocationPermissionsHelper.addListener(mLocationPermissionsListener);
        mAppForegroundHelper.addListener(mAppForegroundChangedListener);
        mPackageResetHelper.register(mPackageResetResponder);
    }

    @Override
@@ -374,6 +390,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
                mLocationPackageBlacklistChangedListener);
        mLocationPermissionsHelper.removeListener(mLocationPermissionsListener);
        mAppForegroundHelper.removeListener(mAppForegroundChangedListener);
        mPackageResetHelper.unregister(mPackageResetResponder);
    }

    private void onUserChanged(int userId, int change) {
@@ -407,6 +424,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter
        updateRegistrations(registration -> registration.onForegroundChanged(uid, foreground));
    }

    private void onPackageReset(String packageName) {
        // invoked when a package is "force quit" - move off the main thread
        FgThread.getExecutor().execute(
                () ->
                        updateRegistrations(
                                registration -> {
                                    if (registration.getIdentity().getPackageName().equals(
                                            packageName)) {
                                        registration.remove();
                                    }

                                    return false;
                                }));
    }

    private boolean isResetableForPackage(String packageName) {
        // invoked to find out if the given package has any state that can be "force quit"
        return findRegistration(
                registration -> registration.getIdentity().getPackageName().equals(packageName));
    }

    @Override
    protected String getServiceState() {
        if (!isSupported()) {
+3 −0
Original line number Diff line number Diff line
@@ -63,4 +63,7 @@ public interface Injector {

    /** Returns a LocationUsageLogger. */
    LocationUsageLogger getLocationUsageLogger();

    /** Returns a PackageResetHelper. */
    PackageResetHelper getPackageResetHelper();
}
+101 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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 com.android.server.location.injector;

import static com.android.server.location.LocationManagerService.D;
import static com.android.server.location.LocationManagerService.TAG;

import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.util.concurrent.CopyOnWriteArrayList;

/** Helpers for tracking queries and resets of package state. */
public abstract class PackageResetHelper {

    /** Interface for responding to reset events. */
    public interface Responder {

        /**
         * Called when a package's runtime state is being reset for whatever reason and any
         * components carrying runtime state on behalf of the package should clear that state.
         *
         * @param packageName The name of the package.
         */
        void onPackageReset(String packageName);

        /**
         * Called when the system queries whether this package has any active state for the given
         * package. Should return true if the component has some runtime state that is resetable of
         * behalf of the given package, and false otherwise.
         *
         * @param packageName The name of the package.
         * @return True if this component has resetable state for the given package.
         */
        boolean isResetableForPackage(String packageName);
    }

    private final CopyOnWriteArrayList<Responder> mResponders;

    public PackageResetHelper() {
        mResponders = new CopyOnWriteArrayList<>();
    }

    /** Begin listening for package reset events. */
    public synchronized void register(Responder responder) {
        boolean empty = mResponders.isEmpty();
        mResponders.add(responder);
        if (empty) {
            onRegister();
        }
    }

    /** Stop listening for package reset events. */
    public synchronized void unregister(Responder responder) {
        mResponders.remove(responder);
        if (mResponders.isEmpty()) {
            onUnregister();
        }
    }

    @GuardedBy("this")
    protected abstract void onRegister();

    @GuardedBy("this")
    protected abstract void onUnregister();

    protected final void notifyPackageReset(String packageName) {
        if (D) {
            Log.d(TAG, "package " + packageName + " reset");
        }

        for (Responder responder : mResponders) {
            responder.onPackageReset(packageName);
        }
    }

    protected final boolean queryResetableForPackage(String packageName) {
        for (Responder responder : mResponders) {
            if (responder.isResetableForPackage(packageName)) {
                return true;
            }
        }

        return false;
    }
}
Loading