Update crash dialog options.

Add app info to crash dialog. Show close (aka force stop) on all dialogs,
not just the repeat dialog.

Remove showing restart and mute by default. Add Settings.Global
configuration parameters for both in case we want to show those options again.

Also some minor cleanup (converting some members to locals).

Bug: 63703353
Bug: 70640329
Test: manual
Change-Id: I83a2b1a5ea0f6a2a9765d7648dab7c184bfbc43f
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0e323f8..e076c8b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11915,6 +11915,19 @@
          * @hide
          */
         public static final String SHOW_FIRST_CRASH_DIALOG = "show_first_crash_dialog";
+
+        /**
+         * If nonzero, crash dialogs will show an option to restart the app.
+         * @hide
+         */
+        public static final String SHOW_RESTART_IN_CRASH_DIALOG = "show_restart_in_crash_dialog";
+
+        /**
+         * If nonzero, crash dialogs will show an option to mute all future crash dialogs for
+         * this app.
+         * @hide
+         */
+        public static final String SHOW_MUTE_IN_CRASH_DIALOG = "show_mute_in_crash_dialog";
     }
 
     /**
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 95eb889..ee9c65d 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -392,8 +392,10 @@
     optional SettingProto enable_smart_replies_in_notifications = 348;
     optional SettingProto show_first_crash_dialog = 349;
     optional SettingProto wifi_connected_mac_randomization_enabled = 350;
+    optional SettingProto show_restart_in_crash_dialog = 351;
+    optional SettingProto show_mute_in_crash_dialog = 352;
 
-    // Next tag = 351;
+    // Next tag = 353;
 }
 
 message SecureSettingsProto {
diff --git a/core/res/res/drawable/ic_info_outline_24.xml b/core/res/res/drawable/ic_info_outline_24.xml
new file mode 100644
index 0000000..abba8cf
--- /dev/null
+++ b/core/res/res/drawable/ic_info_outline_24.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
+</vector>
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
index d78ce59..c3b149a 100644
--- a/core/res/res/layout/app_error_dialog.xml
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -18,48 +18,50 @@
 */
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingTop="@dimen/aerr_padding_list_top"
+    android:paddingBottom="@dimen/aerr_padding_list_bottom">
+
+    <Button
+        android:id="@+id/aerr_restart"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:paddingTop="@dimen/aerr_padding_list_top"
-        android:paddingBottom="@dimen/aerr_padding_list_bottom">
-
+        android:text="@string/aerr_restart"
+        android:drawableStart="@drawable/ic_refresh"
+        style="@style/aerr_list_item" />
 
     <Button
-            android:id="@+id/aerr_restart"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/aerr_restart"
-            android:drawableStart="@drawable/ic_refresh"
-            style="@style/aerr_list_item"
-    />
+        android:id="@+id/aerr_app_info"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/app_info"
+        android:drawableStart="@drawable/ic_info_outline_24"
+        style="@style/aerr_list_item" />
 
     <Button
-            android:id="@+id/aerr_close"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/aerr_close_app"
-            android:drawableStart="@drawable/ic_close"
-            style="@style/aerr_list_item"
-    />
+        android:id="@+id/aerr_close"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/aerr_close_app"
+        android:drawableStart="@drawable/ic_close"
+        style="@style/aerr_list_item" />
 
     <Button
-            android:id="@+id/aerr_report"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/aerr_report"
-            android:drawableStart="@drawable/ic_feedback"
-            style="@style/aerr_list_item"
-    />
+        android:id="@+id/aerr_report"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/aerr_report"
+        android:drawableStart="@drawable/ic_feedback"
+        style="@style/aerr_list_item" />
 
     <Button
-            android:id="@+id/aerr_mute"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/aerr_mute"
-            android:drawableStart="@drawable/ic_eject_24dp"
-            style="@style/aerr_list_item"
-    />
-
+        android:id="@+id/aerr_mute"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/aerr_mute"
+        android:drawableStart="@drawable/ic_eject_24dp"
+        style="@style/aerr_list_item" />
 
 </LinearLayout>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4ef0a6c..effd207 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2650,6 +2650,7 @@
   <java-symbol type="id" name="aerr_report" />
   <java-symbol type="id" name="aerr_restart" />
   <java-symbol type="id" name="aerr_close" />
+  <java-symbol type="id" name="aerr_app_info" />
   <java-symbol type="id" name="aerr_mute" />
 
   <java-symbol type="string" name="status_bar_rotate" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 7403c26..c897841 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -332,7 +332,9 @@
                     Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL,
                     Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
                     Settings.Global.SHOW_FIRST_CRASH_DIALOG,
+                    Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
                     Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
+                    Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
                     Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
                     Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 5a75681..f1fe457 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1120,8 +1120,8 @@
                 Settings.Global.NOTIFICATION_SNOOZE_OPTIONS,
                 GlobalSettingsProto.NOTIFICATION_SNOOZE_OPTIONS);
         dumpSetting(s, p,
-                    Settings.Global.ZRAM_ENABLED,
-                    GlobalSettingsProto.ZRAM_ENABLED);
+                Settings.Global.ZRAM_ENABLED,
+                GlobalSettingsProto.ZRAM_ENABLED);
         dumpSetting(s, p,
                 Settings.Global.ENABLE_SMART_REPLIES_IN_NOTIFICATIONS,
                 GlobalSettingsProto.ENABLE_SMART_REPLIES_IN_NOTIFICATIONS);
@@ -1129,8 +1129,14 @@
                 Settings.Global.SHOW_FIRST_CRASH_DIALOG,
                 GlobalSettingsProto.SHOW_FIRST_CRASH_DIALOG);
         dumpSetting(s, p,
-                    Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
-                    GlobalSettingsProto.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED);
+                Settings.Global.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED,
+                GlobalSettingsProto.WIFI_CONNECTED_MAC_RANDOMIZATION_ENABLED);
+        dumpSetting(s, p,
+                Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
+                GlobalSettingsProto.SHOW_RESTART_IN_CRASH_DIALOG);
+        dumpSetting(s, p,
+                Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
+                GlobalSettingsProto.SHOW_MUTE_IN_CRASH_DIALOG);
     }
 
     /** Dump a single {@link SettingsState.Setting} to a proto buf */
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index 5412266..68c63a2 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -38,9 +38,7 @@
     private final ActivityManagerService mService;
     private final AppErrorResult mResult;
     private final ProcessRecord mProc;
-    private final boolean mRepeating;
     private final boolean mIsRestartable;
-    private CharSequence mName;
 
     static int CANT_SHOW = -1;
     static int BACKGROUND_USER = -2;
@@ -53,6 +51,7 @@
     static final int MUTE = 5;
     static final int TIMEOUT = 6;
     static final int CANCEL = 7;
+    static final int APP_INFO = 8;
 
     // 5-minute timeout, then we automatically dismiss the crash dialog
     static final long DISMISS_TIMEOUT = 1000 * 60 * 5;
@@ -64,23 +63,25 @@
         mService = service;
         mProc = data.proc;
         mResult = data.result;
-        mRepeating = data.repeating;
-        mIsRestartable = data.task != null || data.isRestartableForService;
+        mIsRestartable = (data.task != null || data.isRestartableForService)
+                && Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, 0) != 0;
         BidiFormatter bidi = BidiFormatter.getInstance();
 
+        CharSequence name;
         if ((mProc.pkgList.size() == 1) &&
-                (mName = context.getPackageManager().getApplicationLabel(mProc.info)) != null) {
+                (name = context.getPackageManager().getApplicationLabel(mProc.info)) != null) {
             setTitle(res.getString(
-                    mRepeating ? com.android.internal.R.string.aerr_application_repeated
+                    data.repeating ? com.android.internal.R.string.aerr_application_repeated
                             : com.android.internal.R.string.aerr_application,
-                    bidi.unicodeWrap(mName.toString()),
+                    bidi.unicodeWrap(name.toString()),
                     bidi.unicodeWrap(mProc.info.processName)));
         } else {
-            mName = mProc.processName;
+            name = mProc.processName;
             setTitle(res.getString(
-                    mRepeating ? com.android.internal.R.string.aerr_process_repeated
+                    data.repeating ? com.android.internal.R.string.aerr_process_repeated
                             : com.android.internal.R.string.aerr_process,
-                    bidi.unicodeWrap(mName.toString())));
+                    bidi.unicodeWrap(name.toString())));
         }
 
         setCancelable(true);
@@ -118,11 +119,14 @@
         report.setOnClickListener(this);
         report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
         final TextView close = findViewById(com.android.internal.R.id.aerr_close);
-        close.setVisibility(mRepeating ? View.VISIBLE : View.GONE);
         close.setOnClickListener(this);
+        final TextView appInfo = findViewById(com.android.internal.R.id.aerr_app_info);
+        appInfo.setOnClickListener(this);
 
         boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0
+                && Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG, 0) != 0;
         final TextView mute = findViewById(com.android.internal.R.id.aerr_mute);
         mute.setOnClickListener(this);
         mute.setVisibility(showMute ? View.VISIBLE : View.GONE);
@@ -183,6 +187,9 @@
             case com.android.internal.R.id.aerr_close:
                 mHandler.obtainMessage(FORCE_QUIT).sendToTarget();
                 break;
+            case com.android.internal.R.id.aerr_app_info:
+                mHandler.obtainMessage(APP_INFO).sendToTarget();
+                break;
             case com.android.internal.R.id.aerr_mute:
                 mHandler.obtainMessage(MUTE).sendToTarget();
                 break;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 0da7e0e..139e4f8 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Message;
 import android.os.Process;
@@ -430,6 +431,11 @@
                     Binder.restoreCallingIdentity(orig);
                 }
             }
+            if (res == AppErrorDialog.APP_INFO) {
+                appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+                appErrorIntent.setData(Uri.parse("package:" + r.info.packageName));
+                appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            }
             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
             }