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

Commit 4bd98b45 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Add a new cmd to wait for a specific broadcast to be dispatched." into udc-dev

parents 66250a05 7c32a497
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -18964,6 +18964,13 @@ public class ActivityManagerService extends IActivityManager.Stub
        pw.flush();
    }
    void waitForBroadcastDispatch(@NonNull PrintWriter pw, @NonNull Intent intent) {
        enforceCallingPermission(permission.DUMP, "waitForBroadcastDispatch");
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.waitForDispatched(intent, pw);
        }
    }
    void setIgnoreDeliveryGroupPolicy(@NonNull String broadcastAction) {
        Objects.requireNonNull(broadcastAction);
        enforceCallingPermission(permission.DUMP, "waitForBroadcastBarrier()");
+14 −0
Original line number Diff line number Diff line
@@ -368,6 +368,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runWaitForBroadcastBarrier(pw);
                case "wait-for-application-barrier":
                    return runWaitForApplicationBarrier(pw);
                case "wait-for-broadcast-dispatch":
                    return runWaitForBroadcastDispatch(pw);
                case "set-ignore-delivery-group-policy":
                    return runSetIgnoreDeliveryGroupPolicy(pw);
                case "clear-ignore-delivery-group-policy":
@@ -3472,6 +3474,18 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return 0;
    }

    int runWaitForBroadcastDispatch(PrintWriter pw) throws RemoteException {
        pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw));
        final Intent intent;
        try {
            intent = makeIntent(UserHandle.USER_CURRENT);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        mInternal.waitForBroadcastDispatch(pw, intent);
        return 0;
    }

    int runSetIgnoreDeliveryGroupPolicy(PrintWriter pw) throws RemoteException {
        final String broadcastAction = getNextArgRequired();
        mInternal.setIgnoreDeliveryGroupPolicy(broadcastAction);
+32 −0
Original line number Diff line number Diff line
@@ -582,6 +582,38 @@ public class BroadcastDispatcher {
        }
    }

    private static boolean isDispatchedInDeferrals(@NonNull ArrayList<Deferrals> list,
            @NonNull Intent intent) {
        for (int i = 0; i < list.size(); i++) {
            if (!isDispatched(list.get(i).broadcasts, intent)) {
                return false;
            }
        }
        return true;
    }

    private static boolean isDispatched(@NonNull ArrayList<BroadcastRecord> list,
            @NonNull Intent intent) {
        for (int i = 0; i < list.size(); i++) {
            if (intent.filterEquals(list.get(i).intent)) {
                return false;
            }
        }
        return true;
    }

    public boolean isDispatched(@NonNull Intent intent) {
        synchronized (mLock) {
            if ((mCurrentBroadcast != null) && intent.filterEquals(mCurrentBroadcast.intent)) {
                return false;
            }
            return isDispatched(mOrderedBroadcasts, intent)
                    && isDispatched(mAlarmQueue, intent)
                    && isDispatchedInDeferrals(mDeferredBroadcasts, intent)
                    && isDispatchedInDeferrals(mAlarmDeferrals, intent);
        }
    }

    private static int pendingInDeferralsList(ArrayList<Deferrals> list) {
        int pending = 0;
        final int numEntries = list.size();
+70 −10
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ class BroadcastProcessQueue {
    private int mCountInstrumented;
    private int mCountManifest;

    private boolean mPrioritizeEarliest;
    private int mCountPrioritizeEarliestRequests;

    private @UptimeMillisLong long mRunnableAt = Long.MAX_VALUE;
    private @Reason int mRunnableAtReason = REASON_EMPTY;
@@ -748,7 +748,7 @@ class BroadcastProcessQueue {
        final BroadcastRecord nextLPRecord = (BroadcastRecord) nextLPArgs.arg1;
        final int nextLPRecordIndex = nextLPArgs.argi1;
        final BroadcastRecord nextHPRecord = (BroadcastRecord) highPriorityQueue.peekFirst().arg1;
        final boolean shouldConsiderLPQueue = (mPrioritizeEarliest
        final boolean shouldConsiderLPQueue = (mCountPrioritizeEarliestRequests > 0
                || consecutiveHighPriorityCount >= maxHighPriorityDispatchLimit);
        final boolean isLPQueueEligible = shouldConsiderLPQueue
                && nextLPRecord.enqueueTime <= nextHPRecord.enqueueTime
@@ -761,10 +761,9 @@ class BroadcastProcessQueue {
    }

    /**
     * When {@code prioritizeEarliest} is set to {@code true}, then earliest enqueued
     * broadcasts would be prioritized for dispatching, even if there are urgent broadcasts
     * waiting. This is typically used in case there are callers waiting for "barrier" to be
     * reached.
     * Add a request to prioritize dispatching of broadcasts that have been enqueued the earliest,
     * even if there are urgent broadcasts waiting to be dispatched. This is typically used in
     * case there are callers waiting for "barrier" to be reached.
     *
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
@@ -772,11 +771,37 @@ class BroadcastProcessQueue {
     */
    @CheckResult
    @VisibleForTesting
    boolean setPrioritizeEarliest(boolean prioritizeEarliest) {
        if (mPrioritizeEarliest != prioritizeEarliest) {
            mPrioritizeEarliest = prioritizeEarliest;
    boolean addPrioritizeEarliestRequest() {
        if (mCountPrioritizeEarliestRequests == 0) {
            mCountPrioritizeEarliestRequests++;
            invalidateRunnableAt();
            return true;
        } else {
            mCountPrioritizeEarliestRequests++;
            return false;
        }
    }

    /**
     * Remove a request to prioritize dispatching of broadcasts that have been enqueued the
     * earliest, even if there are urgent broadcasts waiting to be dispatched. This is typically
     * used in case there are callers waiting for "barrier" to be reached.
     *
     * <p> Once there are no more remaining requests, the dispatching order reverts back to normal.
     *
     * @return if this operation may have changed internal state, indicating
     *         that the caller is responsible for invoking
     *         {@link BroadcastQueueModernImpl#updateRunnableList}
     */
    @CheckResult
    boolean removePrioritizeEarliestRequest() {
        mCountPrioritizeEarliestRequests--;
        if (mCountPrioritizeEarliestRequests == 0) {
            invalidateRunnableAt();
            return true;
        } else if (mCountPrioritizeEarliestRequests < 0) {
            mCountPrioritizeEarliestRequests = 0;
            return false;
        } else {
            return false;
        }
@@ -837,7 +862,7 @@ class BroadcastProcessQueue {
    }

    /**
     * Quickly determine if this queue has broadcasts enqueued before the given
     * Quickly determine if this queue has non-deferred broadcasts enqueued before the given
     * barrier timestamp that are still waiting to be delivered.
     */
    public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime) {
@@ -859,6 +884,41 @@ class BroadcastProcessQueue {
                || isDeferredUntilActive();
    }

    /**
     * Quickly determine if this queue has non-deferred broadcasts waiting to be dispatched,
     * that match {@code intent}, as defined by {@link Intent#filterEquals(Intent)}.
     */
    public boolean isDispatched(@NonNull Intent intent) {
        final boolean activeDispatched = (mActive == null)
                || (!intent.filterEquals(mActive.intent));
        final boolean dispatched = isDispatchedInQueue(mPending, intent);
        final boolean urgentDispatched = isDispatchedInQueue(mPendingUrgent, intent);
        final boolean offloadDispatched = isDispatchedInQueue(mPendingOffload, intent);

        return (activeDispatched && dispatched && urgentDispatched && offloadDispatched)
                || isDeferredUntilActive();
    }

    /**
     * Quickly determine if the {@code queue} has non-deferred broadcasts waiting to be dispatched,
     * that match {@code intent}, as defined by {@link Intent#filterEquals(Intent)}.
     */
    private boolean isDispatchedInQueue(@NonNull ArrayDeque<SomeArgs> queue,
            @NonNull Intent intent) {
        final Iterator<SomeArgs> it = queue.iterator();
        while (it.hasNext()) {
            final SomeArgs args = it.next();
            if (args == null) {
                return true;
            }
            final BroadcastRecord record = (BroadcastRecord) args.arg1;
            if (intent.filterEquals(record.intent)) {
                return false;
            }
        }
        return true;
    }

    public boolean isRunnable() {
        if (mRunnableAtInvalidated) updateRunnableAt();
        return mRunnableAt != Long.MAX_VALUE;
+20 −2
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ public abstract class BroadcastQueue {
    public abstract boolean isIdleLocked();

    /**
     * Quickly determine if this queue has broadcasts enqueued before the given
     * Quickly determine if this queue has non-deferred broadcasts enqueued before the given
     * barrier timestamp that are still waiting to be delivered.
     *
     * @see #waitForIdle
@@ -201,6 +201,15 @@ public abstract class BroadcastQueue {
    @GuardedBy("mService")
    public abstract boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime);

    /**
     * Quickly determine if this queue has non-deferred broadcasts waiting to be dispatched,
     * that match {@code intent}, as defined by {@link Intent#filterEquals(Intent)}.
     *
     * @see #waitForDispatched(Intent, PrintWriter)
     */
    @GuardedBy("mService")
    public abstract boolean isDispatchedLocked(@NonNull Intent intent);

    /**
     * Wait until this queue becomes completely idle.
     * <p>
@@ -214,7 +223,7 @@ public abstract class BroadcastQueue {
    public abstract void waitForIdle(@NonNull PrintWriter pw);

    /**
     * Wait until any currently waiting broadcasts have been dispatched.
     * Wait until any currently waiting non-deferred broadcasts have been dispatched.
     * <p>
     * Any broadcasts waiting to be delivered at some point in the future will
     * be dispatched as quickly as possible.
@@ -224,6 +233,15 @@ public abstract class BroadcastQueue {
     */
    public abstract void waitForBarrier(@NonNull PrintWriter pw);

    /**
     * Wait until all non-deferred broadcasts matching {@code intent}, as defined by
     * {@link Intent#filterEquals(Intent)}, have been dispatched.
     * <p>
     * Any broadcasts waiting to be delivered at some point in the future will
     * be dispatched as quickly as possible.
     */
    public abstract void waitForDispatched(@NonNull Intent intent, @NonNull PrintWriter pw);

    /**
     * Delays delivering broadcasts to the specified package.
     *
Loading