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

Commit cf71142c authored by Joanne Chung's avatar Joanne Chung
Browse files

Not allow to register for the same PackageMonitorCallback

Add a limitation for PackageManager#registerPackageMonitorCallback()
that not allow to register the same callback. We cannot limit the
count of the registered client. Most of registered clients are
different system service in the system_server, the count limitation
will crash the system.

Bug: 289567218
Test: atest FrameworksCorePackageMonitorTests
Test: atest FrameworksCorePackageMonitorWithoutPermissionTests
Test: manual. Boot success and the system registered callback can
receive callback

Change-Id: Ia79b4f49c0ac7cd8f3b11f6f2950c9b696fe2661
parent 4db2da9c
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -179,6 +179,10 @@ public class ApplicationPackageManager extends PackageManager {
    @GuardedBy("mDelegates")
    private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();

    @NonNull
    @GuardedBy("mPackageMonitorCallbacks")
    private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>();

    UserManager getUserManager() {
        if (mUserManager == null) {
            mUserManager = UserManager.get(mContext);
@@ -3926,6 +3930,14 @@ public class ApplicationPackageManager extends PackageManager {
        Objects.requireNonNull(callback);
        try {
            mPM.registerPackageMonitorCallback(callback, userId);
            synchronized (mPackageMonitorCallbacks) {
                if (mPackageMonitorCallbacks.contains(callback)) {
                    throw new IllegalStateException(
                            "registerPackageMonitorCallback: callback already registered: "
                                    + callback);
                }
                mPackageMonitorCallbacks.add(callback);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -3936,6 +3948,9 @@ public class ApplicationPackageManager extends PackageManager {
        Objects.requireNonNull(callback);
        try {
            mPM.unregisterPackageMonitorCallback(callback);
            synchronized (mPackageMonitorCallbacks) {
                mPackageMonitorCallbacks.remove(callback);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+22 −0
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ import static com.android.compatibility.common.util.ShellUtils.runShellCommand;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertThrows;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.UserHandle;

@@ -45,6 +48,25 @@ public class PackageMonitorVisibilityTest {
            TEST_DATA_PATH + "TestVisibilityApp.apk";
    private static final String TEAT_APK_PACKAGE_NAME = "com.example.android.testvisibilityapp";
    private static final int WAIT_CALLBACK_CALLED_IN_SECONDS = 1;

    @Test
    public void testPackageMonitorCallbackMultipleRegisterThrowsException() throws Exception {
        Context context = InstrumentationRegistry.getInstrumentation().getContext();
        final IRemoteCallback callback = new IRemoteCallback.Stub() {
            @Override
            public void sendResult(android.os.Bundle bundle) {
                // do-nothing
            }
        };
        try {
            context.getPackageManager().registerPackageMonitorCallback(callback, 0);
            assertThrows(IllegalStateException.class,
                    () -> context.getPackageManager().registerPackageMonitorCallback(callback, 0));
        } finally {
            context.getPackageManager().unregisterPackageMonitorCallback(callback);
        }
    }

    @Test
    public void testPackageMonitorPackageVisible() throws Exception {
        TestVisibilityPackageMonitor testPackageMonitor = new TestVisibilityPackageMonitor();