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

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

Merge "BroadcastQueue: blocked registered receivers."

parents 00cb8434 484d03d5
Loading
Loading
Loading
Loading
+25 −9
Original line number Diff line number Diff line
@@ -784,9 +784,10 @@ public final class ActivityThread extends ClientTransactionHandler

    static final class ReceiverData extends BroadcastReceiver.PendingResult {
        public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                boolean ordered, boolean sticky, IBinder token, int sendingUser) {
                boolean ordered, boolean sticky, boolean assumeDelivered, IBinder token,
                int sendingUser) {
            super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
                    token, sendingUser, intent.getFlags());
                    assumeDelivered, token, sendingUser, intent.getFlags());
            this.intent = intent;
        }

@@ -1040,10 +1041,10 @@ public final class ActivityThread extends ClientTransactionHandler

        public final void scheduleReceiver(Intent intent, ActivityInfo info,
                CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
                boolean sync, int sendingUser, int processState) {
                boolean ordered, boolean assumeDelivered, int sendingUser, int processState) {
            updateProcessState(processState, false);
            ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
                    sync, false, mAppThread.asBinder(), sendingUser);
                    ordered, false, assumeDelivered, mAppThread.asBinder(), sendingUser);
            r.info = info;
            sendMessage(H.RECEIVER, r);
        }
@@ -1054,11 +1055,11 @@ public final class ActivityThread extends ClientTransactionHandler
                if (r.registered) {
                    scheduleRegisteredReceiver(r.receiver, r.intent,
                            r.resultCode, r.data, r.extras, r.ordered, r.sticky,
                            r.sendingUser, r.processState);
                            r.assumeDelivered, r.sendingUser, r.processState);
                } else {
                    scheduleReceiver(r.intent, r.activityInfo, r.compatInfo,
                            r.resultCode, r.data, r.extras, r.sync,
                            r.sendingUser, r.processState);
                            r.assumeDelivered, r.sendingUser, r.processState);
                }
            }
        }
@@ -1288,10 +1289,25 @@ public final class ActivityThread extends ClientTransactionHandler
        // applies transaction ordering per object for such calls.
        public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                int resultCode, String dataStr, Bundle extras, boolean ordered,
                boolean sticky, int sendingUser, int processState) throws RemoteException {
                boolean sticky, boolean assumeDelivered, int sendingUser, int processState)
                throws RemoteException {
            updateProcessState(processState, false);
            receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                    sticky, sendingUser);

            // We can't modify IIntentReceiver due to UnsupportedAppUsage, so
            // try our best to shortcut to known subclasses, and alert if
            // registered using a custom IIntentReceiver that isn't able to
            // report an expected delivery event
            if (receiver instanceof LoadedApk.ReceiverDispatcher.InnerReceiver) {
                ((LoadedApk.ReceiverDispatcher.InnerReceiver) receiver).performReceive(intent,
                        resultCode, dataStr, extras, ordered, sticky, assumeDelivered, sendingUser);
            } else {
                if (!assumeDelivered) {
                    Log.wtf(TAG, "scheduleRegisteredReceiver() called for " + receiver
                            + " and " + intent + " without mechanism to finish delivery");
                }
                receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky,
                        sendingUser);
            }
        }

        @Override
+3 −3
Original line number Diff line number Diff line
@@ -65,8 +65,8 @@ import java.util.Map;
oneway interface IApplicationThread {
    void scheduleReceiver(in Intent intent, in ActivityInfo info,
            in CompatibilityInfo compatInfo,
            int resultCode, in String data, in Bundle extras, boolean sync,
            int sendingUser, int processState);
            int resultCode, in String data, in Bundle extras, boolean ordered,
            boolean assumeDelivered, int sendingUser, int processState);

    void scheduleReceiverList(in List<ReceiverInfo> info);

@@ -102,7 +102,7 @@ oneway interface IApplicationThread {
            in String[] args);
    void scheduleRegisteredReceiver(IIntentReceiver receiver, in Intent intent,
            int resultCode, in String data, in Bundle extras, boolean ordered,
            boolean sticky, int sendingUser, int processState);
            boolean sticky, boolean assumeDelivered, int sendingUser, int processState);
    void scheduleLowMemory();
    void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType);
    void setSchedulingGroup(int group);
+28 −27
Original line number Diff line number Diff line
@@ -1679,6 +1679,16 @@ public final class LoadedApk {
            @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                Log.wtf(TAG, "performReceive() called targeting raw IIntentReceiver for " + intent);
                performReceive(intent, resultCode, data, extras, ordered, sticky,
                        BroadcastReceiver.PendingResult.guessAssumeDelivered(
                                BroadcastReceiver.PendingResult.TYPE_REGISTERED, ordered),
                        sendingUser);
            }

            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
                    int sendingUser) {
                final LoadedApk.ReceiverDispatcher rd;
                if (intent == null) {
                    Log.wtf(TAG, "Null intent received");
@@ -1693,8 +1703,8 @@ public final class LoadedApk {
                }
                if (rd != null) {
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
                } else {
                            ordered, sticky, assumeDelivered, sendingUser);
                } else if (!assumeDelivered) {
                    // The activity manager dispatched a broadcast to a registered
                    // receiver in this process, but before it could be delivered the
                    // receiver was unregistered.  Acknowledge the broadcast on its
@@ -1729,30 +1739,26 @@ public final class LoadedApk {

        final class Args extends BroadcastReceiver.PendingResult {
            private Intent mCurIntent;
            private final boolean mOrdered;
            private boolean mDispatched;
            private boolean mRunCalled;

            public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                    boolean ordered, boolean sticky, int sendingUser) {
                    boolean ordered, boolean sticky, boolean assumeDelivered, int sendingUser) {
                super(resultCode, resultData, resultExtras,
                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
                        sticky, mAppThread.asBinder(), sendingUser, intent.getFlags());
                        sticky, assumeDelivered, mAppThread.asBinder(), sendingUser,
                        intent.getFlags());
                mCurIntent = intent;
                mOrdered = ordered;
            }

            public final Runnable getRunnable() {
                return () -> {
                    final BroadcastReceiver receiver = mReceiver;
                    final boolean ordered = mOrdered;

                    if (ActivityThread.DEBUG_BROADCAST) {
                        int seq = mCurIntent.getIntExtra("seq", -1);
                        Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
                                + " seq=" + seq + " to " + mReceiver);
                        Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
                                + " mOrderedHint=" + ordered);
                    }

                    final IActivityManager mgr = ActivityManager.getService();
@@ -1766,11 +1772,9 @@ public final class LoadedApk {
                    mDispatched = true;
                    mRunCalled = true;
                    if (receiver == null || intent == null || mForgotten) {
                        if (mRegistered && ordered) {
                        if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                "Finishing null broadcast to " + mReceiver);
                        sendFinished(mgr);
                        }
                        return;
                    }

@@ -1790,11 +1794,9 @@ public final class LoadedApk {
                        receiver.setPendingResult(this);
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        if (mRegistered && ordered) {
                        if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                "Finishing failed broadcast to " + mReceiver);
                        sendFinished(mgr);
                        }
                        if (mInstrumentation == null ||
                                !mInstrumentation.onException(mReceiver, e)) {
                            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -1868,9 +1870,10 @@ public final class LoadedApk {
        }

        public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                Bundle extras, boolean ordered, boolean sticky, boolean assumeDelivered,
                int sendingUser) {
            final Args args = new Args(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
                    sticky, assumeDelivered, sendingUser);
            if (intent == null) {
                Log.wtf(TAG, "Null intent received");
            } else {
@@ -1881,14 +1884,12 @@ public final class LoadedApk {
                }
            }
            if (intent == null || !mActivityThread.post(args.getRunnable())) {
                if (mRegistered && ordered) {
                IActivityManager mgr = ActivityManager.getService();
                if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                        "Finishing sync broadcast to " + mReceiver);
                args.sendFinished(mgr);
            }
        }
        }

    }

+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ parcelable ReceiverInfo {
    Intent intent;
    String data;
    Bundle extras;
    boolean assumeDelivered;
    int sendingUser;
    int processState;
    int resultCode;
+33 −8
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ public abstract class BroadcastReceiver {
        final boolean mOrderedHint;
        @UnsupportedAppUsage
        final boolean mInitialStickyHint;
        final boolean mAssumeDeliveredHint;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        final IBinder mToken;
        @UnsupportedAppUsage
@@ -105,17 +106,38 @@ public abstract class BroadcastReceiver {
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type,
                boolean ordered, boolean sticky, IBinder token, int userId, int flags) {
            this(resultCode, resultData, resultExtras, type, ordered, sticky,
                    guessAssumeDelivered(type, ordered), token, userId, flags);
        }

        /** @hide */
        public PendingResult(int resultCode, String resultData, Bundle resultExtras, int type,
                boolean ordered, boolean sticky, boolean assumeDelivered, IBinder token,
                int userId, int flags) {
            mResultCode = resultCode;
            mResultData = resultData;
            mResultExtras = resultExtras;
            mType = type;
            mOrderedHint = ordered;
            mInitialStickyHint = sticky;
            mAssumeDeliveredHint = assumeDelivered;
            mToken = token;
            mSendingUser = userId;
            mFlags = flags;
        }

        /** @hide */
        public static boolean guessAssumeDelivered(int type, boolean ordered) {
            // When a caller didn't provide a concrete way of knowing if we need
            // to report delivery, make a best-effort guess
            if (type == TYPE_COMPONENT) {
                return false;
            } else if (ordered && type != TYPE_UNREGISTERED) {
                return false;
            }
            return true;
        }

        /**
         * Version of {@link BroadcastReceiver#setResultCode(int)
         * BroadcastReceiver.setResultCode(int)} for
@@ -252,7 +274,7 @@ public abstract class BroadcastReceiver {
                            "Finishing broadcast to component " + mToken);
                    sendFinished(mgr);
                }
            } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
            } else {
                if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                        "Finishing broadcast to " + mToken);
                final IActivityManager mgr = ActivityManager.getService();
@@ -279,14 +301,17 @@ public abstract class BroadcastReceiver {
                    if (mResultExtras != null) {
                        mResultExtras.setAllowFds(false);
                    }

                    // When the OS didn't assume delivery, we need to inform
                    // it that we've actually finished the delivery
                    if (!mAssumeDeliveredHint) {
                        if (mOrderedHint) {
                            am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
                                    mAbortBroadcast, mFlags);
                        } else {
                        // This broadcast was sent to a component; it is not ordered,
                        // but we still need to tell the activity manager we are done.
                            am.finishReceiver(mToken, 0, null, null, false, mFlags);
                        }
                    }
                } catch (RemoteException ex) {
                }
            }
Loading