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

Commit 40b720d4 authored by Joanne Chung's avatar Joanne Chung Committed by Android (Google) Code Review
Browse files

Merge "Restricted by package visibility rule for PackageMonitorCallbackHelper" into main

parents 4f31ec72 7d2a43c3
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -2999,14 +2999,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            // action. When the targetPkg is set, it sends the broadcast to specific app, e.g.
            // installer app or null for registered apps. The callback only need to send back to the
            // registered apps so we check the null condition here.
            notifyPackageMonitor(action, pkg, extras, userIds, instantUserIds);
            notifyPackageMonitor(action, pkg, extras, userIds, instantUserIds, broadcastAllowList);
        }
    }

    void notifyPackageMonitor(String action, String pkg, Bundle extras, int[] userIds,
            int[] instantUserIds) {
            int[] instantUserIds, SparseArray<int[]> broadcastAllowList) {
        mPackageMonitorCallbackHelper.notifyPackageMonitor(action, pkg, extras, userIds,
                instantUserIds);
                instantUserIds, broadcastAllowList);
    }

    void notifyResourcesChanged(boolean mediaStatus, boolean replacing,
@@ -3062,7 +3062,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mHandler.post(() -> mBroadcastHelper.sendPackageAddedForNewUsers(
                packageName, appId, userIds, instantUserIds, dataLoaderType, broadcastAllowList));
        mPackageMonitorCallbackHelper.notifyPackageAddedForNewUsers(packageName, appId, userIds,
                instantUserIds, dataLoaderType);
                instantUserIds, dataLoaderType, broadcastAllowList);
        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
            mHandler.post(() -> {
                        for (int userId : userIds) {
@@ -4068,7 +4068,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                packageName, dontKillApp, componentNames, packageUid, reason, userIds,
                instantUserIds, broadcastAllowList));
        mPackageMonitorCallbackHelper.notifyPackageChanged(packageName, dontKillApp, componentNames,
                packageUid, reason, userIds, instantUserIds);
                packageUid, reason, userIds, instantUserIds, broadcastAllowList);
    }

    /**
@@ -6238,7 +6238,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService

        @Override
        public void registerPackageMonitorCallback(@NonNull IRemoteCallback callback, int userId) {
            mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, userId);
            int uid = Binder.getCallingUid();
            mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, userId, uid);
        }

        @Override
+55 −15
Original line number Diff line number Diff line
@@ -29,10 +29,13 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
@@ -42,6 +45,9 @@ import java.util.ArrayList;
/** Helper class to handle PackageMonitorCallback and notify the registered client. This is mainly
 * used by PackageMonitor to improve the broadcast latency. */
class PackageMonitorCallbackHelper {

    private static final boolean DEBUG = false;

    @NonNull
    private final Object mLock = new Object();
    final IActivityManager mActivityManager = ActivityManager.getService();
@@ -56,9 +62,9 @@ class PackageMonitorCallbackHelper {
    @GuardedBy("mLock")
    private final RemoteCallbackList<IRemoteCallback> mCallbacks = new RemoteCallbackList<>();

    public void registerPackageMonitorCallback(IRemoteCallback callback, int userId) {
    public void registerPackageMonitorCallback(IRemoteCallback callback, int userId, int uid) {
        synchronized (mLock) {
            mCallbacks.register(callback, userId);
            mCallbacks.register(callback, new RegisterUser(userId, uid));
        }
    }

@@ -73,8 +79,9 @@ class PackageMonitorCallbackHelper {
        synchronized (mLock) {
            int registerCount = mCallbacks.getRegisteredCallbackCount();
            for (int i = 0; i < registerCount; i++) {
                int registerUserId = (int) mCallbacks.getRegisteredCallbackCookie(i);
                if (registerUserId == userId) {
                RegisterUser registerUser =
                        (RegisterUser) mCallbacks.getRegisteredCallbackCookie(i);
                if (registerUser.getUserId() == userId) {
                    IRemoteCallback callback = mCallbacks.getRegisteredCallbackItem(i);
                    if (targetUnRegisteredCallbacks == null) {
                        targetUnRegisteredCallbacks = new ArrayList<>();
@@ -93,7 +100,7 @@ class PackageMonitorCallbackHelper {

    public void notifyPackageAddedForNewUsers(String packageName,
            @AppIdInt int appId, @NonNull int[] userIds, @NonNull int[] instantUserIds,
            int dataLoaderType) {
            int dataLoaderType, SparseArray<int[]> broadcastAllowList) {
        Bundle extras = new Bundle(2);
        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
        final int uid = UserHandle.getUid(
@@ -101,7 +108,7 @@ class PackageMonitorCallbackHelper {
        extras.putInt(Intent.EXTRA_UID, uid);
        extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
        notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED, packageName, extras ,
                userIds /* userIds */, instantUserIds);
                userIds /* userIds */, instantUserIds, broadcastAllowList);
    }

    public void notifyResourcesChanged(boolean mediaStatus, boolean replacing,
@@ -115,12 +122,12 @@ class PackageMonitorCallbackHelper {
        String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
        notifyPackageMonitor(action, null /* pkg */, extras, null /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);
    }

    public void notifyPackageChanged(String packageName, boolean dontKillApp,
            ArrayList<String> componentNames, int packageUid, String reason, int[] userIds,
            int[] instantUserIds) {
            int[] instantUserIds, SparseArray<int[]> broadcastAllowList) {
        Bundle extras = new Bundle(4);
        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
        String[] nameList = new String[componentNames.size()];
@@ -132,11 +139,11 @@ class PackageMonitorCallbackHelper {
            extras.putString(Intent.EXTRA_REASON, reason);
        }
        notifyPackageMonitor(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, userIds,
                instantUserIds);
                instantUserIds, broadcastAllowList);
    }

    public void notifyPackageMonitor(String action, String pkg, Bundle extras,
            int[] userIds, int[] instantUserIds) {
            int[] userIds, int[] instantUserIds, SparseArray<int[]> broadcastAllowList) {
        if (!isAllowedCallbackAction(action)) {
            return;
        }
@@ -150,9 +157,9 @@ class PackageMonitorCallbackHelper {
            }

            if (ArrayUtils.isEmpty(instantUserIds)) {
                doNotifyCallbacks(action, pkg, extras, resolvedUserIds);
                doNotifyCallbacks(action, pkg, extras, resolvedUserIds, broadcastAllowList);
            } else {
                doNotifyCallbacks(action, pkg, extras, instantUserIds);
                doNotifyCallbacks(action, pkg, extras, instantUserIds, broadcastAllowList);
            }
        } catch (RemoteException e) {
            // do nothing
@@ -170,7 +177,8 @@ class PackageMonitorCallbackHelper {
                || TextUtils.equals(action, Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
    }

    private void doNotifyCallbacks(String action, String pkg, Bundle extras, int[] userIds) {
    private void doNotifyCallbacks(String action, String pkg, Bundle extras, int[] userIds,
            SparseArray<int[]> broadcastAllowList) {
        RemoteCallbackList<IRemoteCallback> callbacks;
        synchronized (mLock) {
            callbacks = mCallbacks;
@@ -188,9 +196,23 @@ class PackageMonitorCallbackHelper {
            }
            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);

            final int[] allowUids =
                    broadcastAllowList != null ? broadcastAllowList.get(userId) : new int[]{};

            mHandler.post(() -> callbacks.broadcast((callback, user) -> {
                int registerUserId = (int) user;
                if ((registerUserId != UserHandle.USER_ALL) && (registerUserId != userId)) {
                RegisterUser registerUser = (RegisterUser) user;
                if ((registerUser.getUserId() != UserHandle.USER_ALL) && (registerUser.getUserId()
                        != userId)) {
                    return;
                }
                int registerUid = registerUser.getUid();
                if (broadcastAllowList != null && registerUid != Process.SYSTEM_UID
                        && !ArrayUtils.contains(allowUids, registerUid)) {
                    if (DEBUG) {
                        Slog.w("PackageMonitorCallbackHelper",
                                "Skip invoke PackageMonitorCallback for " + action + ", uid "
                                        + registerUid);
                    }
                    return;
                }
                invokeCallback(callback, intent);
@@ -208,4 +230,22 @@ class PackageMonitorCallbackHelper {
            // do nothing
        }
    }

    private final class RegisterUser {
        int mUserId;
        int mUid;

        RegisterUser(int userId, int uid) {
            mUid = uid;
            mUserId = userId;
        }

        public int getUid() {
            return mUid;
        }

        public int getUserId() {
            return mUserId;
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -634,7 +634,7 @@ public final class SuspendPackageHelper {
                        mPm.snapshotComputer(), callingUid, intentExtras),
                options));
        mPm.notifyPackageMonitor(intent, null /* pkg */, extras, new int[]{userId},
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);
    }

    /**
+25 −15
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import android.content.Intent;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
@@ -78,7 +79,7 @@ public class PackageMonitorCallbackHelperTest {

        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{0} /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);

        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).never()).sendResult(any());
    }
@@ -87,9 +88,11 @@ public class PackageMonitorCallbackHelperTest {
    public void testUnregisterPackageMonitorCallback_callbackShouldNotCalled() throws Exception {
        IRemoteCallback callback = createMockPackageMonitorCallback();

        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{0}, null /* instantUserIds */);
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{0}, null /* instantUserIds */,
                null /* broadcastAllowList */);

        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).times(1)).sendResult(any());

@@ -97,7 +100,7 @@ public class PackageMonitorCallbackHelperTest {
        mPackageMonitorCallbackHelper.unregisterPackageMonitorCallback(callback);
        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{0} /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);

        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).never()).sendResult(any());
    }
@@ -106,10 +109,11 @@ public class PackageMonitorCallbackHelperTest {
    public void testRegisterPackageMonitorCallback_callbackCalled() throws Exception {
        IRemoteCallback callback = createMockPackageMonitorCallback();

        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{0} /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);

        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).times(1)).sendResult(
@@ -128,11 +132,12 @@ public class PackageMonitorCallbackHelperTest {
        IRemoteCallback callback = createMockPackageMonitorCallback();

        // Register for user 0
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        // Notify for user 10
        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{10} /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);

        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).never()).sendResult(any());
    }
@@ -144,10 +149,12 @@ public class PackageMonitorCallbackHelperTest {
        ArrayList<String> components = new ArrayList<>();
        String component1 = FAKE_PACKAGE_NAME + "/.Component1";
        components.add(component1);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        mPackageMonitorCallbackHelper.notifyPackageChanged(FAKE_PACKAGE_NAME,
                false /* dontKillApp */, components, FAKE_PACKAGE_UID, null /* reason */,
                new int[]{0} /* userIds */, null /* instantUserIds */);
                new int[]{0} /* userIds */, null /* instantUserIds */,
                null /* broadcastAllowList */);

        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).times(1)).sendResult(
@@ -171,10 +178,11 @@ public class PackageMonitorCallbackHelperTest {
    public void testNotifyPackageAddedForNewUsers_callbackCalled() throws Exception {
        IRemoteCallback callback = createMockPackageMonitorCallback();

        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        mPackageMonitorCallbackHelper.notifyPackageAddedForNewUsers(FAKE_PACKAGE_NAME,
                FAKE_PACKAGE_UID, new int[]{0} /* userIds */, new int[0],
                PackageInstaller.DATA_LOADER_TYPE_STREAMING);
                PackageInstaller.DATA_LOADER_TYPE_STREAMING, null /* broadcastAllowList */);

        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).times(1)).sendResult(
@@ -194,7 +202,8 @@ public class PackageMonitorCallbackHelperTest {
    public void testNotifyResourcesChanged_callbackCalled() throws Exception {
        IRemoteCallback callback = createMockPackageMonitorCallback();

        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 0 /* userId */,
                Binder.getCallingUid());
        mPackageMonitorCallbackHelper.notifyResourcesChanged(true /* mediaStatus */,
                true /* replacing */, new String[]{FAKE_PACKAGE_NAME},
                new int[]{FAKE_PACKAGE_UID} /* uids */);
@@ -224,12 +233,13 @@ public class PackageMonitorCallbackHelperTest {
    @Test
    public void testPackageMonitorCallback_onUserRemoved_callbackNotCalled() throws Exception {
        IRemoteCallback callback = createMockPackageMonitorCallback();
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 10 /* userId */);
        mPackageMonitorCallbackHelper.registerPackageMonitorCallback(callback, 10 /* userId */,
                Binder.getCallingUid());

        mPackageMonitorCallbackHelper.onUserRemoved(10);
        mPackageMonitorCallbackHelper.notifyPackageMonitor(Intent.ACTION_PACKAGE_ADDED,
                FAKE_PACKAGE_NAME, createFakeBundle(), new int[]{10} /* userIds */,
                null /* instantUserIds */);
                null /* instantUserIds */, null /* broadcastAllowList */);

        verify(callback, after(WAIT_CALLBACK_CALLED_IN_MS).never()).sendResult(any());
    }