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

Commit ef4a7f30 authored by Rhed Jao's avatar Rhed Jao
Browse files

Do not split intents into multiple ones

Revert splitting of intents for sending resources changed and
distracting packages.

Bug: 238448280
Test: atest DistractingPackageHelperTest
Test: atest AppEnumerationTests
Change-Id: I56d9466dfe52f013869bd64d69d24d004cd2262c
parent 04cded96
Loading
Loading
Loading
Loading
+17 −77
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.Manifest;
import android.annotation.AppIdInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.BroadcastOptions;
@@ -41,10 +40,8 @@ import android.content.pm.PackageInstaller;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerExemptionManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
@@ -54,9 +51,9 @@ import android.util.SparseArray;
import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
 * Helper class to send broadcasts for various situations.
@@ -159,42 +156,26 @@ public final class BroadcastHelper {
        }
    }

    public void sendResourcesChangedBroadcast(@NonNull Computer snapshot, boolean mediaStatus,
            boolean replacing, @NonNull String[] pkgNames, @NonNull int[] uids) {
    public void sendResourcesChangedBroadcast(@NonNull Supplier<Computer> snapshotComputer,
            boolean mediaStatus, boolean replacing, @NonNull String[] pkgNames,
            @NonNull int[] uids) {
        if (ArrayUtils.isEmpty(pkgNames) || ArrayUtils.isEmpty(uids)) {
            return;
        }

        try {
            final IActivityManager am = ActivityManager.getService();
            if (am == null) {
                return;
            }

            final int[] resolvedUserIds = am.getRunningUserIds();
            for (int userId : resolvedUserIds) {
                final var lists = getBroadcastParams(snapshot, pkgNames, uids, userId);
                for (int i = 0; i < lists.size(); i++) {
                    // Send broadcasts here
                    final Bundle extras = new Bundle(3);
                    final BroadcastParams list = lists.get(i);
                    extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
                            list.getPackageNames());
                    extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, list.getUids());
        Bundle extras = new Bundle();
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgNames);
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uids);
        if (replacing) {
            extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
                    final SparseArray<int[]> allowList = list.getAllowList().size() == 0
                            ? null : list.getAllowList();
                    final String action =
                            mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
        }
        String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
        sendPackageBroadcast(action, null /* pkg */, extras, 0 /* flags */,
                            null /* targetPkg */, null /* finishedReceiver */, new int[]{userId},
                            null /* instantUserIds */, allowList,
                            null /* filterExtrasForReceiver */, null /* bOptions */);
                }
            }
        } catch (RemoteException ex) {
        }
                null /* targetPkg */, null /* finishedReceiver */, null /* userIds */,
                null /* instantUserIds */, null /* broadcastAllowList */,
                (callingUid, intentExtras) -> filterExtrasChangedPackageList(
                        snapshotComputer.get(), callingUid, intentExtras),
                null /* bOptions */);
    }

    /**
@@ -353,47 +334,6 @@ public final class BroadcastHelper {
                null /* filterExtrasForReceiver */, null);
    }

    /**
     * Get broadcast params list based on the given package and uid list. The broadcast params are
     * used to send broadcast separately if the given packages have different visibility allow list.
     *
     * @param pkgList The names of packages which have changes.
     * @param uidList The uids of packages which have changes.
     * @param userId The user where packages reside.
     * @return The list of {@link BroadcastParams} object.
     */
    public List<BroadcastParams> getBroadcastParams(@NonNull Computer snapshot,
            @NonNull String[] pkgList, @NonNull int[] uidList, @UserIdInt int userId) {
        final List<BroadcastParams> lists = new ArrayList<>(pkgList.length);
        // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
        // allow lists are the same.
        for (int i = 0; i < pkgList.length; i++) {
            final String pkgName = pkgList[i];
            final int uid = uidList[i];
            if (TextUtils.isEmpty(pkgName) || Process.INVALID_UID == uid) {
                continue;
            }
            int[] allowList = snapshot.getVisibilityAllowList(pkgName, userId);
            if (allowList == null) {
                allowList = new int[0];
            }
            boolean merged = false;
            for (int j = 0; j < lists.size(); j++) {
                final BroadcastParams list = lists.get(j);
                if (Arrays.equals(list.getAllowList().get(userId), allowList)) {
                    list.addPackage(pkgName, uid);
                    merged = true;
                    break;
                }
            }
            if (!merged) {
                lists.add(new BroadcastParams(pkgName, uid, allowList, userId));
            }
        }

        return lists;
    }

    /**
     * Filter package names for the intent extras {@link Intent#EXTRA_CHANGED_PACKAGE_LIST} and
     * {@link Intent#EXTRA_CHANGED_UID_LIST} by using the rules of the package visibility.
+0 −62
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.pm;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.util.IntArray;
import android.util.SparseArray;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * A helper class that contains information about package names and uids that share the same allow
 * list for sending broadcasts. Used by various package helpers.
 */
final class BroadcastParams {
    private final @NonNull List<String> mPackageNames;
    private final @NonNull IntArray mUids;
    private final @NonNull SparseArray<int[]> mAllowList;

    BroadcastParams(@NonNull String packageName, @IntRange(from = 0) int uid,
            @NonNull int[] allowList, @UserIdInt int userId) {
        mPackageNames = new ArrayList<>(Arrays.asList(packageName));
        mUids = IntArray.wrap(new int[]{uid});
        mAllowList = new SparseArray<>(1);
        mAllowList.put(userId, allowList);
    }

    public void addPackage(@NonNull String packageName, @IntRange(from = 0) int uid) {
        mPackageNames.add(packageName);
        mUids.add(uid);
    }

    public @NonNull String[] getPackageNames() {
        return mPackageNames.toArray(new String[0]);
    }

    public @NonNull int[] getUids() {
        return mUids.toArray();
    }

    public @NonNull SparseArray<int[]> getAllowList() {
        return mAllowList;
    }
}
+17 −21
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.os.UserHandle;
import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.util.ArrayUtils;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -127,7 +126,7 @@ public final class DistractingPackageHelper {
        if (!changedPackagesList.isEmpty()) {
            final String[] changedPackages = changedPackagesList.toArray(
                    new String[changedPackagesList.size()]);
            sendDistractingPackagesChanged(snapshot, changedPackages, changedUids.toArray(), userId,
            sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
                    restrictionFlags);
            mPm.scheduleWritePackageRestrictions(userId);
        }
@@ -169,7 +168,7 @@ public final class DistractingPackageHelper {
        if (!changedPackages.isEmpty()) {
            final String[] packageArray = changedPackages.toArray(
                    new String[changedPackages.size()]);
            sendDistractingPackagesChanged(snapshot, packageArray, changedUids.toArray(), userId,
            sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId,
                    RESTRICTION_NONE);
            mPm.scheduleWritePackageRestrictions(userId);
        }
@@ -182,24 +181,21 @@ public final class DistractingPackageHelper {
     * @param uidList The uids of packages which have suspension changes.
     * @param userId The user where packages reside.
     */
    void sendDistractingPackagesChanged(@NonNull Computer snapshot, @NonNull String[] pkgList,
            int[] uidList, int userId, int distractionFlags) {
        final List<BroadcastParams> lists = mBroadcastHelper.getBroadcastParams(
                snapshot, pkgList, uidList, userId);
        final Handler handler = mInjector.getHandler();
        for (int i = 0; i < lists.size(); i++) {
            final Bundle extras = new Bundle(3);
            final BroadcastParams list = lists.get(i);
            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, list.getPackageNames());
            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, list.getUids());
    void sendDistractingPackagesChanged(@NonNull String[] pkgList, int[] uidList, int userId,
            int distractionFlags) {
        final Bundle extras = new Bundle();
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
        extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
            final SparseArray<int[]> allowList = list.getAllowList().size() == 0
                    ? null : list.getAllowList();

        final Handler handler = mInjector.getHandler();
        handler.post(() -> mBroadcastHelper.sendPackageBroadcast(
                Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */,
                extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
                null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
                    allowList, null /* filterExtrasForReceiver */, null /* bOptions */));
        }
                null /* broadcastAllowList */,
                (callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList(
                        mPm.snapshotComputer(), callingUid, intentExtras),
                null /* bOptions */));
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -2626,7 +2626,7 @@ final class InstallPackageHelper {
                    }
                    final String[] pkgNames = new String[]{res.mRemovedInfo.mRemovedPackage};
                    final int[] uids = new int[]{res.mRemovedInfo.mUid};
                    mBroadcastHelper.sendResourcesChangedBroadcast(mPm.snapshotComputer(),
                    mBroadcastHelper.sendResourcesChangedBroadcast(mPm::snapshotComputer,
                            false /* mediaStatus */, true /* replacing */, pkgNames, uids);
                }
                res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
@@ -2804,7 +2804,7 @@ final class InstallPackageHelper {
                    }
                    final String[] pkgNames = new String[]{packageName};
                    final int[] uids = new int[]{res.mPkg.getUid()};
                    mBroadcastHelper.sendResourcesChangedBroadcast(mPm.snapshotComputer(),
                    mBroadcastHelper.sendResourcesChangedBroadcast(mPm::snapshotComputer,
                            true /* mediaStatus */, true /* replacing */, pkgNames, uids);
                }
            } else if (!ArrayUtils.isEmpty(res.mLibraryConsumers)) { // if static shared lib
+1 −1
Original line number Diff line number Diff line
@@ -298,7 +298,7 @@ public final class StorageEventHelper extends StorageEventListener {
            packageNames[i] = pkg.getPackageName();
            packageUids[i] = pkg.getUid();
        }
        mBroadcastHelper.sendResourcesChangedBroadcast(mPm.snapshotComputer(), mediaStatus,
        mBroadcastHelper.sendResourcesChangedBroadcast(mPm::snapshotComputer, mediaStatus,
                replacing, packageNames, packageUids);
    }

Loading