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

Commit fd1f59b3 authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge changes Ia69ff3b5,I56d9466d,I6c405116

* changes:
  Applying package visibility rules to the broadcast of overlay changed
  Do not split intents into multiple ones
  Do not split the suspended packages intent into multiple ones
parents 0054cebd 91a53a89
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;

/**
 * Activity manager local system service interface.
@@ -623,6 +624,11 @@ public abstract class ActivityManagerInternal {
     * broadcast my be sent to; any app Ids < {@link android.os.Process#FIRST_APPLICATION_UID} are
     * automatically allowlisted.
     *
     * @param filterExtrasForReceiver A function to filter intent extras for the given receiver by
     * using the rules of package visibility. Returns extras with legitimate package info that the
     * receiver is able to access, or {@code null} if none of the packages is visible to the
     * receiver.
     *
     * @see com.android.server.am.ActivityManagerService#broadcastIntentWithFeature(
     *      IApplicationThread, String, Intent, String, IIntentReceiver, int, String, Bundle,
     *      String[], int, Bundle, boolean, boolean, int)
@@ -630,7 +636,9 @@ public abstract class ActivityManagerInternal {
    public abstract int broadcastIntent(Intent intent,
            IIntentReceiver resultTo,
            String[] requiredPermissions, boolean serialized,
            int userId, int[] appIdAllowList, @Nullable Bundle bOptions);
            int userId, int[] appIdAllowList,
            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
            @Nullable Bundle bOptions);

    /**
     * Add uid to the ActivityManagerService PendingStartActivityUids list.
+18 −9
Original line number Diff line number Diff line
@@ -459,6 +459,7 @@ import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
@@ -4304,7 +4305,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                null /* excludedPackages */, OP_NONE, null /* bOptions */, false /* ordered */,
                false /* sticky */, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
                Binder.getCallingPid(), userId, false /* allowBackgroundActivityStarts */,
                null /* backgroundActivityStartsToken */, broadcastAllowList);
                null /* backgroundActivityStartsToken */,
                broadcastAllowList, null /* filterExtrasForReceiver */);
    }
    private void cleanupDisabledPackageComponentsLocked(
@@ -13357,7 +13359,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
                            null, null, -1, -1, false, null, null, null, null, OP_NONE, null,
                            receivers, null, 0, null, null, false, true, true, -1, false, null,
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */);
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
                            null /* filterExtrasForReceiver */);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
@@ -13620,7 +13623,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                excludedPermissions, excludedPackages, appOp, bOptions, ordered, sticky, callingPid,
                callingUid, realCallingUid, realCallingPid, userId,
                false /* allowBackgroundActivityStarts */,
                null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */);
                null /* tokenNeededForBackgroundActivityStarts */,
                null /* broadcastAllowList */, null /* filterExtrasForReceiver */);
    }
    @GuardedBy("this")
@@ -13633,7 +13637,8 @@ public class ActivityManagerService extends IActivityManager.Stub
            int realCallingUid, int realCallingPid, int userId,
            boolean allowBackgroundActivityStarts,
            @Nullable IBinder backgroundActivityStartsToken,
            @Nullable int[] broadcastAllowList) {
            @Nullable int[] broadcastAllowList,
            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
        intent = new Intent(intent);
        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
@@ -14233,7 +14238,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
                    registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered,
                    sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt);
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            final boolean replaced = replacePending
                    && (queue.replaceParallelBroadcastLocked(r) != null);
@@ -14331,7 +14336,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
                    receivers, resultTo, resultCode, resultData, resultExtras,
                    ordered, sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt);
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
@@ -14523,7 +14528,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                        resultTo, resultCode, resultData, resultExtras, requiredPermissions, null,
                        null, OP_NONE, bOptions, serialized, sticky, -1, uid, realCallingUid,
                        realCallingPid, userId, allowBackgroundActivityStarts,
                        backgroundActivityStartsToken, broadcastAllowList);
                        backgroundActivityStartsToken, broadcastAllowList,
                        null /* filterExtrasForReceiver */);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
@@ -17065,7 +17071,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        public int broadcastIntent(Intent intent,
                IIntentReceiver resultTo,
                String[] requiredPermissions,
                boolean serialized, int userId, int[] appIdAllowList, @Nullable Bundle bOptions) {
                boolean serialized, int userId, int[] appIdAllowList,
                @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
                @Nullable Bundle bOptions) {
            synchronized (ActivityManagerService.this) {
                intent = verifyBroadcastLocked(intent);
@@ -17081,7 +17089,8 @@ public class ActivityManagerService extends IActivityManager.Stub
                            AppOpsManager.OP_NONE, bOptions /*options*/, serialized,
                            false /*sticky*/, callingPid, callingUid, callingUid, callingPid,
                            userId, false /*allowBackgroundStarts*/,
                            null /*tokenNeededForBackgroundActivityStarts*/, appIdAllowList);
                            null /*tokenNeededForBackgroundActivityStarts*/,
                            appIdAllowList, filterExtrasForReceiver);
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
+50 −3
Original line number Diff line number Diff line
@@ -363,8 +363,8 @@ public final class BroadcastQueue {
                    + ": " + r);
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                      PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
            thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
                    null /* compatInfo (unused but need to keep method signature) */,
            thread.scheduleReceiver(prepareReceiverIntent(r.intent, r.curFilteredExtras),
                    r.curReceiver, null /* compatInfo (unused but need to keep method signature) */,
                    r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
                    app.mState.getReportedProcState());
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
@@ -592,6 +592,7 @@ public final class BroadcastQueue {
        r.curFilter = null;
        r.curReceiver = null;
        r.curApp = null;
        r.curFilteredExtras = null;
        mPendingBroadcast = null;

        r.resultCode = resultCode;
@@ -943,6 +944,24 @@ public final class BroadcastQueue {
            skip = true;
        }

        // Filter packages in the intent extras, skipping delivery if none of the packages is
        // visible to the receiver.
        Bundle filteredExtras = null;
        if (!skip && r.filterExtrasForReceiver != null) {
            final Bundle extras = r.intent.getExtras();
            if (extras != null) {
                filteredExtras = r.filterExtrasForReceiver.apply(filter.receiverList.uid, extras);
                if (filteredExtras == null) {
                    if (DEBUG_BROADCAST) {
                        Slog.v(TAG, "Skipping delivery to "
                                + filter.receiverList.app
                                + " : receiver is filtered by the package visibility");
                    }
                    skip = true;
                }
            }
        }

        if (skip) {
            r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
            return;
@@ -1000,7 +1019,7 @@ public final class BroadcastQueue {
                maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
                maybeReportBroadcastDispatchedEventLocked(r, filter.owningUid);
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        prepareReceiverIntent(r.intent, filteredExtras), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId,
                        filter.receiverList.uid, r.callingUid,
                        r.dispatchTime - r.enqueueTime,
@@ -1167,6 +1186,15 @@ public final class BroadcastQueue {
                + ", uid=" + r.callingUid + ") to " + component.flattenToShortString();
    }

    private static Intent prepareReceiverIntent(@NonNull Intent originalIntent,
            @Nullable Bundle filteredExtras) {
        final Intent intent = new Intent(originalIntent);
        if (filteredExtras != null) {
            intent.replaceExtras(filteredExtras);
        }
        return intent;
    }

    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
        BroadcastRecord r;

@@ -1837,6 +1865,24 @@ public final class BroadcastQueue {
            }
        }

        // Filter packages in the intent extras, skipping delivery if none of the packages is
        // visible to the receiver.
        Bundle filteredExtras = null;
        if (!skip && r.filterExtrasForReceiver != null) {
            final Bundle extras = r.intent.getExtras();
            if (extras != null) {
                filteredExtras = r.filterExtrasForReceiver.apply(receiverUid, extras);
                if (filteredExtras == null) {
                    if (DEBUG_BROADCAST) {
                        Slog.v(TAG, "Skipping delivery to "
                                + info.activityInfo.packageName + " / " + receiverUid
                                + " : receiver is filtered by the package visibility");
                    }
                    skip = true;
                }
            }
        }

        if (skip) {
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Skipping delivery of ordered [" + mQueueName + "] "
@@ -1855,6 +1901,7 @@ public final class BroadcastQueue {
        r.state = BroadcastRecord.APP_RECEIVE;
        r.curComponent = component;
        r.curReceiver = info.activityInfo;
        r.curFilteredExtras = filteredExtras;
        if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
            Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
                    + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
+17 −3
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;

/**
 * An active intent broadcast.
@@ -114,6 +115,11 @@ final class BroadcastRecord extends Binder {
    @Nullable
    final IBinder mBackgroundActivityStartsToken;

    // Filter the intent extras by using the rules of the package visibility before broadcasting
    // the intent to the receiver.
    @Nullable
    final BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver;

    static final int IDLE = 0;
    static final int APP_RECEIVE = 1;
    static final int CALL_IN_RECEIVE = 2;
@@ -134,6 +140,7 @@ final class BroadcastRecord extends Binder {
    ProcessRecord curApp;       // hosting application of current receiver.
    ComponentName curComponent; // the receiver class that is currently running.
    ActivityInfo curReceiver;   // info about the receiver that is currently running.
    Bundle curFilteredExtras;   // the bundle that has been filtered by the package visibility rules

    boolean mIsReceiverAppRunning; // Was the receiver's app already running.

@@ -227,6 +234,9 @@ final class BroadcastRecord extends Binder {
                        pw.println(curReceiver.applicationInfo.sourceDir);
            }
        }
        if (curFilteredExtras != null) {
            pw.print(" filtered extras: "); pw.println(curFilteredExtras);
        }
        if (state != IDLE) {
            String stateStr = " (?)";
            switch (state) {
@@ -273,7 +283,8 @@ final class BroadcastRecord extends Binder {
            BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo, int _resultCode,
            String _resultData, Bundle _resultExtras, boolean _serialized, boolean _sticky,
            boolean _initialSticky, int _userId, boolean allowBackgroundActivityStarts,
            @Nullable IBinder backgroundActivityStartsToken, boolean timeoutExempt) {
            @Nullable IBinder backgroundActivityStartsToken, boolean timeoutExempt,
            @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
        if (_intent == null) {
            throw new NullPointerException("Can't construct with a null intent");
        }
@@ -309,6 +320,7 @@ final class BroadcastRecord extends Binder {
        mBackgroundActivityStartsToken = backgroundActivityStartsToken;
        this.timeoutExempt = timeoutExempt;
        alarm = options != null && options.isAlarmBroadcast();
        this.filterExtrasForReceiver = filterExtrasForReceiver;
    }

    /**
@@ -362,6 +374,7 @@ final class BroadcastRecord extends Binder {
        mBackgroundActivityStartsToken = from.mBackgroundActivityStartsToken;
        timeoutExempt = from.timeoutExempt;
        alarm = from.alarm;
        filterExtrasForReceiver = from.filterExtrasForReceiver;
    }

    /**
@@ -397,7 +410,7 @@ final class BroadcastRecord extends Binder {
                requiredPermissions, excludedPermissions, excludedPackages, appOp, options,
                splitReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky,
                initialSticky, userId, allowBackgroundActivityStarts,
                mBackgroundActivityStartsToken, timeoutExempt);
                mBackgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
        split.enqueueTime = this.enqueueTime;
        split.enqueueRealTime = this.enqueueRealTime;
        split.enqueueClockTime = this.enqueueClockTime;
@@ -476,7 +489,8 @@ final class BroadcastRecord extends Binder {
                    requiredPermissions, excludedPermissions, excludedPackages, appOp, options,
                    uid2receiverList.valueAt(i), null /* _resultTo */,
                    resultCode, resultData, resultExtras, ordered, sticky, initialSticky, userId,
                    allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt);
                    allowBackgroundActivityStarts, mBackgroundActivityStartsToken, timeoutExempt,
                    filterExtrasForReceiver);
            br.enqueueTime = this.enqueueTime;
            br.enqueueRealTime = this.enqueueRealTime;
            br.enqueueClockTime = this.enqueueClockTime;
+9 −6
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -1416,16 +1417,18 @@ public final class OverlayManagerService extends SystemService {

    private static void broadcastActionOverlayChanged(@NonNull final Set<String> targetPackages,
            final int userId) {
        final PackageManagerInternal pmInternal =
                LocalServices.getService(PackageManagerInternal.class);
        final ActivityManagerInternal amInternal =
                LocalServices.getService(ActivityManagerInternal.class);
        CollectionUtils.forEach(targetPackages, target -> {
            final Intent intent = new Intent(ACTION_OVERLAY_CHANGED,
                    Uri.fromParts("package", target, null));
            intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            try {
                ActivityManager.getService().broadcastIntent(null, intent, null, null, 0, null,
                        null, null, android.app.AppOpsManager.OP_NONE, null, false, false, userId);
            } catch (RemoteException e) {
                Slog.e(TAG, "broadcastActionOverlayChanged remote exception", e);
            }
            final int[] allowList = pmInternal.getVisibilityAllowList(target, userId);
            amInternal.broadcastIntent(intent, null /* resultTo */, null /* requiredPermissions */,
                    false /* serialized */, userId, allowList, null /* filterExtrasForReceiver */,
                    null /* bOptions */);
        });
    }

Loading