diff options
| author | 2022-11-18 13:30:36 -0800 | |
|---|---|---|
| committer | 2022-11-19 03:25:28 +0000 | |
| commit | c7ece382b79d3eb54029ff7fde7adadab5348e6c (patch) | |
| tree | f03d8b4328546250908cd76101676148f4992ffe | |
| parent | 31944123ba298d761532b3e339a1400b495693f1 (diff) | |
Stop using CannotDeliverBroadcastException
This is a squashed CL. Due to significant BroadcastQueue rearchitecture
in master branch, the original CL can't be directly cherry-picked here.
This CL combines code from the following CLs:
ag/20498660 Stop using CannotDeliverBroadcastException
ag/20516440 Add killing subreason for undelivered broadcast
=== Original commit message ===
This crash behavior was introduced a long time ago to show a crash
dialog if the broadcast couldn't be delivered (b/28196243). Android
has changed a lot since then. The crash dialog won't be shown to the
user as it impacts user experience, especially when the app is in the
background.
Furthermore, this CannotDeliverBroadcastException crashes the app with
the same callstack, without any useful information for app developers
to debug the issue. And it pollutes the app crashlytics stats in a
negative way so app developers choose to suppress it (b/245258072).
This exception is hidden and not documented at developers.android.com.
Let's stop sending it to apps. Kill the app gently instead (as what's
already mentioned in the comments).
Bug: 239419108
Test: atest ApplicationExitInfoTest
Test: atest BroadcastQueueTest
Test: observe app is killed gently on failed broadcast (instead of
crash)
Test: use up async buffer, broadcast & dumpsys activity exit-info
Change-Id: I93aabe99167105111f9f3bd945cf4977cfb8cdb1
Merged-In: I93aabe99167105111f9f3bd945cf4977cfb8cdb1
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 4 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationExitInfo.java | 12 | ||||
| -rw-r--r-- | core/java/android/app/RemoteServiceException.java | 23 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/BroadcastQueue.java | 23 |
4 files changed, 27 insertions, 35 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 51efdbac00cc..ef6c5a6c8272 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -40,7 +40,6 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; import android.app.RemoteServiceException.BadForegroundServiceNotificationException; -import android.app.RemoteServiceException.CannotDeliverBroadcastException; import android.app.RemoteServiceException.CannotPostForegroundServiceNotificationException; import android.app.RemoteServiceException.CrashedByAdbException; import android.app.RemoteServiceException.ForegroundServiceDidNotStartInTimeException; @@ -1975,9 +1974,6 @@ public final class ActivityThread extends ClientTransactionHandler case ForegroundServiceDidNotStartInTimeException.TYPE_ID: throw generateForegroundServiceDidNotStartInTimeException(message, extras); - case CannotDeliverBroadcastException.TYPE_ID: - throw new CannotDeliverBroadcastException(message); - case CannotPostForegroundServiceNotificationException.TYPE_ID: throw new CannotPostForegroundServiceNotificationException(message); diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java index 5517c57d1f1e..871d15ec0b40 100644 --- a/core/java/android/app/ApplicationExitInfo.java +++ b/core/java/android/app/ApplicationExitInfo.java @@ -407,6 +407,15 @@ public final class ApplicationExitInfo implements Parcelable { */ public static final int SUBREASON_PACKAGE_UPDATE = 25; + /** + * The process was killed because of undelivered broadcasts; this would be set only when the + * reason is {@link #REASON_OTHER}. + * + * For internal use only. + * @hide + */ + public static final int SUBREASON_UNDELIVERED_BROADCAST = 26; + // If there is any OEM code which involves additional app kill reasons, it should // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000. @@ -579,6 +588,7 @@ public final class ApplicationExitInfo implements Parcelable { SUBREASON_STOP_APP, SUBREASON_KILL_BACKGROUND, SUBREASON_PACKAGE_UPDATE, + SUBREASON_UNDELIVERED_BROADCAST, }) @Retention(RetentionPolicy.SOURCE) public @interface SubReason {} @@ -1283,6 +1293,8 @@ public final class ApplicationExitInfo implements Parcelable { return "KILL BACKGROUND"; case SUBREASON_PACKAGE_UPDATE: return "PACKAGE UPDATE"; + case SUBREASON_UNDELIVERED_BROADCAST: + return "UNDELIVERED BROADCAST"; default: return "UNKNOWN"; } diff --git a/core/java/android/app/RemoteServiceException.java b/core/java/android/app/RemoteServiceException.java index e220627706f9..620adbedc903 100644 --- a/core/java/android/app/RemoteServiceException.java +++ b/core/java/android/app/RemoteServiceException.java @@ -72,21 +72,6 @@ public class RemoteServiceException extends AndroidRuntimeException { /** * Exception used to crash an app process when the system received a RemoteException - * while delivering a broadcast to an app process. - * - * @hide - */ - public static class CannotDeliverBroadcastException extends RemoteServiceException { - /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 2; - - public CannotDeliverBroadcastException(String msg) { - super(msg); - } - } - - /** - * Exception used to crash an app process when the system received a RemoteException * while posting a notification of a foreground service. * * @hide @@ -94,7 +79,7 @@ public class RemoteServiceException extends AndroidRuntimeException { public static class CannotPostForegroundServiceNotificationException extends RemoteServiceException { /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 3; + public static final int TYPE_ID = 2; public CannotPostForegroundServiceNotificationException(String msg) { super(msg); @@ -109,7 +94,7 @@ public class RemoteServiceException extends AndroidRuntimeException { */ public static class BadForegroundServiceNotificationException extends RemoteServiceException { /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 4; + public static final int TYPE_ID = 3; public BadForegroundServiceNotificationException(String msg) { super(msg); @@ -125,7 +110,7 @@ public class RemoteServiceException extends AndroidRuntimeException { public static class MissingRequestPasswordComplexityPermissionException extends RemoteServiceException { /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 5; + public static final int TYPE_ID = 4; public MissingRequestPasswordComplexityPermissionException(String msg) { super(msg); @@ -139,7 +124,7 @@ public class RemoteServiceException extends AndroidRuntimeException { */ public static class CrashedByAdbException extends RemoteServiceException { /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 6; + public static final int TYPE_ID = 5; public CrashedByAdbException(String msg) { super(msg); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index c235e0597384..621e3dbde360 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -45,10 +45,10 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; +import android.app.ApplicationExitInfo; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.PendingIntent; -import android.app.RemoteServiceException.CannotDeliverBroadcastException; import android.app.usage.UsageEvents.Event; import android.app.usage.UsageStatsManagerInternal; import android.content.ComponentName; @@ -665,18 +665,14 @@ public final class BroadcastQueue { thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser, app.mState.getReportedProcState()); - // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting - // DeadObjectException when the process isn't actually dead. - //} catch (DeadObjectException ex) { - // Failed to call into the process. It's dying so just let it die and move on. - // throw ex; } catch (RemoteException ex) { // Failed to call into the process. It's either dying or wedged. Kill it gently. synchronized (mService) { - Slog.w(TAG, "Can't deliver broadcast to " + app.processName - + " (pid " + app.getPid() + "). Crashing it."); - app.scheduleCrashLocked("can't deliver broadcast", - CannotDeliverBroadcastException.TYPE_ID, /* extras=*/ null); + final String msg = "Failed to schedule " + intent + " to " + receiver + + " via " + app + ": " + ex; + Slog.w(TAG, msg); + app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true); } throw ex; } @@ -1890,8 +1886,11 @@ public final class BroadcastQueue { processCurBroadcastLocked(r, app); return; } catch (RemoteException e) { - Slog.w(TAG, "Exception when sending broadcast to " - + r.curComponent, e); + final String msg = "Failed to schedule " + r.intent + " to " + info + + " via " + app + ": " + e; + Slog.w(TAG, msg); + app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER, + ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true); } catch (RuntimeException e) { Slog.wtf(TAG, "Failed sending broadcast to " + r.curComponent + " with " + r.intent, e); |