From 33a01ec1b4a6957a4451a62b6b29b94829c42942 Mon Sep 17 00:00:00 2001 From: Arthur Hung Date: Wed, 23 Mar 2022 14:28:14 +0000 Subject: [PATCH] Prevent crash when unregsiter the broadcast Make sure the receiver could be generated and registered when `onStart` and cleared when `onStop`. Bug: 225214384 Test: Show error dialog, atest WindowInputTests Change-Id: Ib39629180aac1a7aa418e9c7e540922c7f865718 --- .../am/AppWaitingForDebuggerDialog.java | 3 -- .../android/server/am/BaseErrorDialog.java | 37 +++++++++++++------ .../android/server/wm/FactoryErrorDialog.java | 3 -- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java index 262e79521e8c6..9b5f18caf71a4 100644 --- a/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java +++ b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java @@ -57,9 +57,6 @@ final class AppWaitingForDebuggerDialog extends BaseErrorDialog { attrs.setTitle("Waiting For Debugger: " + app.info.processName); getWindow().setAttributes(attrs); } - - public void onStop() { - } @Override protected void closeDialog() { diff --git a/services/core/java/com/android/server/am/BaseErrorDialog.java b/services/core/java/com/android/server/am/BaseErrorDialog.java index 259dd8ec567df..b1cfd7fa0f580 100644 --- a/services/core/java/com/android/server/am/BaseErrorDialog.java +++ b/services/core/java/com/android/server/am/BaseErrorDialog.java @@ -16,6 +16,8 @@ package com.android.server.am; +import static android.content.Context.RECEIVER_EXPORTED; + import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -34,6 +36,7 @@ public class BaseErrorDialog extends AlertDialog { private static final int DISABLE_BUTTONS = 1; private boolean mConsuming = true; + private BroadcastReceiver mReceiver; public BaseErrorDialog(Context context) { super(context, com.android.internal.R.style.Theme_DeviceDefault_Dialog_AppError); @@ -52,14 +55,33 @@ public class BaseErrorDialog extends AlertDialog { super.onStart(); mHandler.sendEmptyMessage(DISABLE_BUTTONS); mHandler.sendMessageDelayed(mHandler.obtainMessage(ENABLE_BUTTONS), 1000); - getContext().registerReceiver(mReceiver, - new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), Context.RECEIVER_EXPORTED); + if (mReceiver == null) { + mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { + closeDialog(); + } + } + }; + getContext().registerReceiver(mReceiver, + new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), RECEIVER_EXPORTED); + } } @Override protected void onStop() { super.onStop(); - getContext().unregisterReceiver(mReceiver); + if (mReceiver != null) { + try { + getContext().unregisterReceiver(mReceiver); + } catch (IllegalArgumentException e) { + // Receiver not registered exception. + android.util.Slog.e("BaseErrorDialog", + "unregisterReceiver threw exception: " + e.getMessage()); + } + mReceiver = null; + } } public boolean dispatchKeyEvent(KeyEvent event) { @@ -107,13 +129,4 @@ public class BaseErrorDialog extends AlertDialog { dismiss(); } } - - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) { - closeDialog(); - } - } - }; } diff --git a/services/core/java/com/android/server/wm/FactoryErrorDialog.java b/services/core/java/com/android/server/wm/FactoryErrorDialog.java index afdf1ee4de7fd..4ebaad98cd755 100644 --- a/services/core/java/com/android/server/wm/FactoryErrorDialog.java +++ b/services/core/java/com/android/server/wm/FactoryErrorDialog.java @@ -37,9 +37,6 @@ final class FactoryErrorDialog extends BaseErrorDialog { attrs.setTitle("Factory Error"); getWindow().setAttributes(attrs); } - - public void onStop() { - } @Override protected void closeDialog() {