From 08408b9338f67acc4e9793ec531af2966c7f27da Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Tue, 9 May 2017 13:48:53 -0700 Subject: [PATCH] Tweak for b/37809561. From the WTF log we know Args.run() sometimes gets called multiple times. Remove the Runnable interface from the Args class to make it impossible to cast it to Runnable. If the WTF still happens with this change, that'd be *very* interesting. Test: Build and boot Bug: 37809561 Change-Id: Id4bd9bd8d4098086649235fddfc2136527805838 --- core/java/android/app/LoadedApk.java | 118 ++++++++++++++------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index b84161c05a139..0708b0bd38215 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -1214,7 +1214,7 @@ public final class LoadedApk { RuntimeException mUnregisterLocation; boolean mForgotten; - final class Args extends BroadcastReceiver.PendingResult implements Runnable { + final class Args extends BroadcastReceiver.PendingResult { private Intent mCurIntent; private final boolean mOrdered; private boolean mDispatched; @@ -1228,66 +1228,68 @@ public final class LoadedApk { mCurIntent = intent; mOrdered = ordered; } - - public void run() { - 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(); - final Intent intent = mCurIntent; - if (intent == null) { - Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched - + ": run() previously called at " - + Log.getStackTraceString(mPreviousRunStacktrace)); - } - mCurIntent = null; - mDispatched = true; - mPreviousRunStacktrace = new Throwable("Previous stacktrace"); - 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; - } + public final Runnable getRunnable() { + return () -> { + final BroadcastReceiver receiver = mReceiver; + final boolean ordered = mOrdered; - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg"); - try { - ClassLoader cl = mReceiver.getClass().getClassLoader(); - intent.setExtrasClassLoader(cl); - intent.prepareToEnterProcess(); - setExtrasClassLoader(cl); - 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 (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); } - if (mInstrumentation == null || - !mInstrumentation.onException(mReceiver, e)) { - Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); - throw new RuntimeException( - "Error receiving broadcast " + intent - + " in " + mReceiver, e); + + final IActivityManager mgr = ActivityManager.getService(); + final Intent intent = mCurIntent; + if (intent == null) { + Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched + + ": run() previously called at " + + Log.getStackTraceString(mPreviousRunStacktrace)); } - } - - if (receiver.getPendingResult() != null) { - finish(); - } - Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + + mCurIntent = null; + mDispatched = true; + mPreviousRunStacktrace = new Throwable("Previous stacktrace"); + 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; + } + + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg"); + try { + ClassLoader cl = mReceiver.getClass().getClassLoader(); + intent.setExtrasClassLoader(cl); + intent.prepareToEnterProcess(); + setExtrasClassLoader(cl); + 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); + throw new RuntimeException( + "Error receiving broadcast " + intent + + " in " + mReceiver, e); + } + } + + if (receiver.getPendingResult() != null) { + finish(); + } + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + }; } } @@ -1356,7 +1358,7 @@ public final class LoadedApk { + " seq=" + seq + " to " + mReceiver); } } - if (intent == null || !mActivityThread.post(args)) { + if (intent == null || !mActivityThread.post(args.getRunnable())) { if (mRegistered && ordered) { IActivityManager mgr = ActivityManager.getService(); if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,