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

Commit 4d1f54e3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix waitForBroadcastIdle()"

parents 0e0d1c59 b486f41e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18100,8 +18100,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                    if (!queue.isIdle()) {
                        final String msg = "Waiting for queue " + queue + " to become idle...";
                        pw.println(msg);
                        pw.println(queue.describeState());
                        pw.flush();
                        Slog.v(TAG, msg);
                        queue.cancelDeferrals();
                        idle = false;
                    }
                }
+65 −11
Original line number Diff line number Diff line
@@ -65,6 +65,14 @@ public class BroadcastDispatcher {
            broadcasts.add(br);
        }

        int size() {
            return broadcasts.size();
        }

        boolean isEmpty() {
            return broadcasts.isEmpty();
        }

        void writeToProto(ProtoOutputStream proto, long fieldId) {
            for (BroadcastRecord br : broadcasts) {
                br.writeToProto(proto, fieldId);
@@ -252,22 +260,48 @@ public class BroadcastDispatcher {
        synchronized (mLock) {
            return mCurrentBroadcast == null
                    && mOrderedBroadcasts.isEmpty()
                    && mDeferredBroadcasts.isEmpty()
                    && mAlarmBroadcasts.isEmpty();
                    && isDeferralsListEmpty(mDeferredBroadcasts)
                    && isDeferralsListEmpty(mAlarmBroadcasts);
        }
    }

    private static int pendingInDeferralsList(ArrayList<Deferrals> list) {
        int pending = 0;
        final int numEntries = list.size();
        for (int i = 0; i < numEntries; i++) {
            pending += list.get(i).size();
        }
        return pending;
    }

    private static boolean isDeferralsListEmpty(ArrayList<Deferrals> list) {
        return pendingInDeferralsList(list) == 0;
    }

    /**
     * Not quite the traditional size() measurement; includes any in-process but
     * not yet retired active outbound broadcast.
     * Strictly for logging, describe the currently pending contents in a human-
     * readable way
     */
    public int totalUndelivered() {
        synchronized (mLock) {
            return mAlarmBroadcasts.size()
                    + mDeferredBroadcasts.size()
                    + mOrderedBroadcasts.size()
                    + (mCurrentBroadcast == null ? 0 : 1);
    public String describeStateLocked() {
        final StringBuilder sb = new StringBuilder(128);
        if (mCurrentBroadcast != null) {
            sb.append("1 in flight, ");
        }
        sb.append(mOrderedBroadcasts.size());
        sb.append(" ordered");
        int n = pendingInDeferralsList(mAlarmBroadcasts);
        if (n > 0) {
            sb.append(", ");
            sb.append(n);
            sb.append(" deferrals in alarm recipients");
        }
        n = pendingInDeferralsList(mDeferredBroadcasts);
        if (n > 0) {
            sb.append(", ");
            sb.append(n);
            sb.append(" deferred");
        }
        return sb.toString();
    }

    // ----------------------------------
@@ -579,6 +613,26 @@ public class BroadcastDispatcher {
        }
    }

    /**
     * Cancel all current deferrals; that is, make all currently-deferred broadcasts
     * immediately deliverable.  Used by the wait-for-broadcast-idle mechanism.
     */
    public void cancelDeferrals() {
        synchronized (mLock) {
            zeroDeferralTimes(mAlarmBroadcasts);
            zeroDeferralTimes(mDeferredBroadcasts);
        }
    }

    private static void zeroDeferralTimes(ArrayList<Deferrals> list) {
        final int num = list.size();
        for (int i = 0; i < num; i++) {
            Deferrals d = list.get(i);
            // Safe to do this in-place because it won't break ordering
            d.deferUntil = d.deferredBy = 0;
        }
    }

    // ----------------------------------

    /**
+16 −3
Original line number Diff line number Diff line
@@ -928,8 +928,8 @@ public final class BroadcastQueue {

        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
                + mQueueName + "]: "
                + mParallelBroadcasts.size() + " parallel broadcasts, "
                + mDispatcher.totalUndelivered() + " ordered broadcasts");
                + mParallelBroadcasts.size() + " parallel broadcasts; "
                + mDispatcher.describeStateLocked());

        mService.updateCpuStats();

@@ -1827,11 +1827,24 @@ public final class BroadcastQueue {
                record.intent == null ? "" : record.intent.getAction());
    }

    final boolean isIdle() {
    boolean isIdle() {
        return mParallelBroadcasts.isEmpty() && mDispatcher.isEmpty()
                && (mPendingBroadcast == null);
    }

    // Used by wait-for-broadcast-idle : fast-forward all current deferrals to
    // be immediately deliverable.
    void cancelDeferrals() {
        mDispatcher.cancelDeferrals();
    }

    String describeState() {
        synchronized (mService) {
            return mParallelBroadcasts.size() + " parallel; "
                    + mDispatcher.describeStateLocked();
        }
    }

    void writeToProto(ProtoOutputStream proto, long fieldId) {
        long token = proto.start(fieldId);
        proto.write(BroadcastQueueProto.QUEUE_NAME, mQueueName);