Merge "Remove stacks from topTaks that no longer exist."
diff --git a/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_checked.xml b/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_checked.xml
index 9a6717a..8e9369a 100644
--- a/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_checked.xml
+++ b/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_checked.xml
@@ -16,9 +16,9 @@
   -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="@*android:dimen/car_icon_size"
-        android:height="@*android:dimen/car_icon_size"
-        android:tint="@*android:color/car_teal_700"
+        android:width="@dimen/checkbox_size"
+        android:height="@dimen/checkbox_size"
+        android:tint="@color/checkbox_color_checked"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
diff --git a/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_unchecked.xml b/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_unchecked.xml
index 522935c..c4916ee 100644
--- a/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_unchecked.xml
+++ b/car_product/overlay/packages/apps/PackageInstaller/res/drawable/ic_check_box_unchecked.xml
@@ -16,9 +16,9 @@
   -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="@*android:dimen/car_icon_size"
-        android:height="@*android:dimen/car_icon_size"
-        android:tint="@*android:color/car_tint"
+        android:width="@dimen/checkbox_size"
+        android:height="@dimen/checkbox_size"
+        android:tint="@color/checkbox_color_unchecked"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
diff --git a/car_product/overlay/packages/apps/PackageInstaller/res/layout/grant_permissions.xml b/car_product/overlay/packages/apps/PackageInstaller/res/layout/grant_permissions.xml
index 58f6ea3..b9874a5 100644
--- a/car_product/overlay/packages/apps/PackageInstaller/res/layout/grant_permissions.xml
+++ b/car_product/overlay/packages/apps/PackageInstaller/res/layout/grant_permissions.xml
@@ -50,7 +50,7 @@
             <CheckBox
                 android:id="@+id/do_not_ask_checkbox"
                 android:layout_width="wrap_content"
-                android:layout_height="@dimen/checkbox_height"
+                android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/checkbox_start_margin"
                 android:layout_marginEnd="@dimen/checkbox_end_margin"
                 android:gravity="center_vertical"
diff --git a/car_product/overlay/packages/apps/PackageInstaller/res/values/colors.xml b/car_product/overlay/packages/apps/PackageInstaller/res/values/colors.xml
new file mode 100644
index 0000000..c3f7b7b
--- /dev/null
+++ b/car_product/overlay/packages/apps/PackageInstaller/res/values/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+<resources>
+    <color name="checkbox_color_unchecked">@*android:color/car_tint</color>
+    <color name="checkbox_color_checked">@*android:color/accent_device_default_light</color>
+</resources>
\ No newline at end of file
diff --git a/car_product/overlay/packages/apps/PackageInstaller/res/values/dimens.xml b/car_product/overlay/packages/apps/PackageInstaller/res/values/dimens.xml
index 0fc8ed5..078ad7f 100644
--- a/car_product/overlay/packages/apps/PackageInstaller/res/values/dimens.xml
+++ b/car_product/overlay/packages/apps/PackageInstaller/res/values/dimens.xml
@@ -30,11 +30,13 @@
     <dimen name="checkbox_end_margin">@*android:dimen/car_keyline_1</dimen>
 
     <dimen name="checkbox_left_padding">@*android:dimen/car_keyline_1_keyline_3_diff</dimen>
-    <dimen name="checkbox_text_size">@*android:dimen/car_body3_size</dimen>
-    <dimen name="checkbox_height">@*android:dimen/car_single_line_list_item_height</dimen>
+    <dimen name="checkbox_text_size">@*android:dimen/car_label1_size</dimen>
+    <dimen name="checkbox_text_height">@*android:dimen/car_single_line_list_item_height</dimen>
 
     <dimen name="permission_dialog_button_margin_top">@*android:dimen/car_padding_2</dimen>
     <dimen name="permission_dialog_allow_button_height">@*android:dimen/car_dialog_action_bar_height</dimen>
 
     <dimen name="permission_dialog_appearance_padding_end">@*android:dimen/car_keyline_1</dimen>
+
+    <dimen name="checkbox_size">@*android:dimen/car_primary_icon_size</dimen>
 </resources>
\ No newline at end of file
diff --git a/service/res/drawable/exit_button_background.xml b/service/res/drawable/button_background.xml
similarity index 85%
rename from service/res/drawable/exit_button_background.xml
rename to service/res/drawable/button_background.xml
index 92d32fd..c714124 100644
--- a/service/res/drawable/exit_button_background.xml
+++ b/service/res/drawable/button_background.xml
@@ -14,6 +14,6 @@
 limitations under the License.
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <solid android:color="@color/exit_button_background"/>
-    <corners android:radius="@dimen/exit_button_radius"/>
+    <solid android:color="@color/button_background"/>
+    <corners android:radius="@dimen/button_radius"/>
 </shape>
diff --git a/service/res/drawable/exit_button_ripple_background.xml b/service/res/drawable/button_ripple_background.xml
similarity index 92%
rename from service/res/drawable/exit_button_ripple_background.xml
rename to service/res/drawable/button_ripple_background.xml
index 54fd00f..418c508 100644
--- a/service/res/drawable/exit_button_ripple_background.xml
+++ b/service/res/drawable/button_ripple_background.xml
@@ -16,5 +16,5 @@
 <ripple
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:color="@color/ripple_background">
-    <item android:drawable="@drawable/exit_button_background" />
+    <item android:drawable="@drawable/button_background" />
 </ripple>
diff --git a/service/res/layout/activity_blocking.xml b/service/res/layout/activity_blocking.xml
index 687afbe..5eddbf9 100644
--- a/service/res/layout/activity_blocking.xml
+++ b/service/res/layout/activity_blocking.xml
@@ -19,19 +19,55 @@
     android:layout_height="match_parent"
     android:orientation="vertical"
     android:background="@color/activity_blocking_activity_background"
-    android:padding="@dimen/blocking_activity_padding"
     android:gravity="center">
     <TextView
-        android:id="@+id/activity_blocked_title"
+        android:id="@+id/blocking_text"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
-        android:textColor="@color/blocking_text"
         android:textAppearance="@style/ActivityBlockingActivityText" />
+
+    <LinearLayout
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginTop="@dimen/common_margin"
+        android:orientation="horizontal"
+        android:gravity="center">
+        <ImageView
+            android:id="@+id/blocked_app_icon"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content" />
+        <TextView
+            android:id="@+id/blocked_app_name"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_marginStart="@dimen/common_margin"
+            android:textColor="@color/blocking_text"
+            android:textAppearance="@style/ActivityBlockingActivityText" />
+    </LinearLayout>
+
     <Button
         android:id="@+id/exit"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
-        android:layout_marginTop="@dimen/exit_button_top_margin"
+        android:layout_marginTop="@dimen/common_margin"
         android:text="@string/exit_button"
-        style="@style/ExitButtonStyle"/>
+        style="@style/ButtonStyle"/>
+
+    <!-- Widgets to display debug info. They should not show for non-user build. -->
+    <Button
+        android:id="@+id/toggle_debug_info"
+        android:visibility="gone"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginTop="@dimen/common_margin"
+        android:text="@string/debug_button_text"
+        style="@style/ButtonStyle"/>
+
+    <TextView
+        android:id="@+id/debug_info"
+        android:visibility="gone"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_marginTop="@dimen/common_margin"
+        android:textAppearance="@style/ActivityBlockingActivityText" />
 </LinearLayout>
diff --git a/service/res/values-h1920dp/dimens.xml b/service/res/values-h1920dp/dimens.xml
index 938fb17..42de507 100644
--- a/service/res/values-h1920dp/dimens.xml
+++ b/service/res/values-h1920dp/dimens.xml
@@ -19,8 +19,6 @@
 <resources>
     <!-- Text size in ActivityBlockingActivity. -->
     <dimen name="blocking_text_size">40sp</dimen>
-    <!-- Padding of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_padding">28dp</dimen>
-    <!-- Top margin of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_top_margin">20dp</dimen>
+    <!-- Padding of button in ActivityBlockingActivity. -->
+    <dimen name="button_padding">28dp</dimen>
 </resources>
diff --git a/service/res/values-h800dp/dimens.xml b/service/res/values-h800dp/dimens.xml
index 9594554..6dd33fe 100644
--- a/service/res/values-h800dp/dimens.xml
+++ b/service/res/values-h800dp/dimens.xml
@@ -17,6 +17,6 @@
 */
 -->
 <resources>
-    <!-- Padding of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_padding">28dp</dimen>
+    <!-- Padding of button in ActivityBlockingActivity. -->
+    <dimen name="button_padding">28dp</dimen>
 </resources>
diff --git a/service/res/values-night/colors.xml b/service/res/values-night/colors.xml
index 65f8fb1..6f30b68 100644
--- a/service/res/values-night/colors.xml
+++ b/service/res/values-night/colors.xml
@@ -18,17 +18,17 @@
 -->
 <resources>
     <!-- Semi-transparent background color of blocking activity. -->
-    <!-- In Call background scrim: black @ 80% -->
-    <color name="activity_blocking_activity_background">#cc000000</color>
+    <!-- In Call background scrim: black -->
+    <color name="activity_blocking_activity_background">@android:color/black</color>
 
     <!-- Color of text in blocking activity. -->
     <color name="blocking_text">#fff5f5f5</color>
 
-    <!-- Background color of exit button. -->
-    <color name="exit_button_background">#ff80cbc4</color>
+    <!-- Background color of button. -->
+    <color name="button_background">#ff80cbc4</color>
 
-    <!-- Color of exit button text. -->
-    <color name="exit_button_text">#ff212121</color>
+    <!-- Color of button text. -->
+    <color name="button_text">#ff212121</color>
 
     <!-- Ripple color. -->
     <color name="ripple_background">#3dffffff</color>
diff --git a/service/res/values-w1280dp/dimens.xml b/service/res/values-w1280dp/dimens.xml
deleted file mode 100644
index f5469f2..0000000
--- a/service/res/values-w1280dp/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<resources>
-    <!-- Padding of ActivityBlockingActivity. -->
-    <dimen name="blocking_activity_padding">148dp</dimen>
-</resources>
diff --git a/service/res/values-w1920dp/dimens.xml b/service/res/values-w1920dp/dimens.xml
deleted file mode 100644
index 75d2deb..0000000
--- a/service/res/values-w1920dp/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<resources>
-    <!-- Padding of ActivityBlockingActivity. -->
-    <dimen name="blocking_activity_padding">192dp</dimen>
-</resources>
diff --git a/service/res/values-w690dp/dimens.xml b/service/res/values-w690dp/dimens.xml
deleted file mode 100644
index 0b06ada..0000000
--- a/service/res/values-w690dp/dimens.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-<resources>
-    <!-- Padding of ActivityBlockingActivity. -->
-    <dimen name="blocking_activity_padding">112dp</dimen>
-</resources>
diff --git a/service/res/values/colors.xml b/service/res/values/colors.xml
index ed86a3b..6764116 100644
--- a/service/res/values/colors.xml
+++ b/service/res/values/colors.xml
@@ -18,18 +18,18 @@
 -->
 <resources>
     <!-- Semi-transparent background color of blocking activity. -->
-    <!-- In Call background scrim: grey 200 @ 90% -->
-    <color name="activity_blocking_activity_background">#e6eeeeee</color>
+    <!-- In Call background scrim: grey 200 -->
+    <color name="activity_blocking_activity_background">#ffeeeeee</color>
 
     <!-- Color of text in blocking activity. -->
     <color name="blocking_text">#ff212121</color>
 
-    <!-- Background color of exit button. -->
-    <color name="exit_button_background">#ff00796b</color>
+    <!-- Background color of button. -->
+    <color name="button_background">#ff00796b</color>
 
-    <!-- Color of exit button text. -->
-    <color name="exit_button_text">#fffafafa</color>
+    <!-- Color of button text. -->
+    <color name="button_text">#fffafafa</color>
 
-    <!-- Ripple color of exit button background. -->
+    <!-- Ripple color of button background. -->
     <color name="ripple_background">#3d000000</color>
 </resources>
diff --git a/service/res/values/dimens.xml b/service/res/values/dimens.xml
index f75a358..23653db 100644
--- a/service/res/values/dimens.xml
+++ b/service/res/values/dimens.xml
@@ -19,18 +19,14 @@
 <resources>
     <!-- Text size in ActivityBlockingActivity. -->
     <dimen name="blocking_text_size">32sp</dimen>
-    <!-- Padding of ActivityBlockingActivity. -->
-    <dimen name="blocking_activity_padding">20dp</dimen>
-
-    <!-- Minimum height of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_min_height">56dp</dimen>
-    <!-- Minimum width of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_min_width">156dp</dimen>
-    <!-- Padding of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_padding">16dp</dimen>
-    <!-- Radius of exit button in ActivityBlockingActivity. -->
-    <dimen name="exit_button_radius">4dp</dimen>
-    <!-- Top margin of exit button. It should be half the height of
-         button (exit_button_min_height). -->
-    <dimen name="exit_button_top_margin">28dp</dimen>
+    <!-- Widget margin. It should be half the height of button. -->
+    <dimen name="common_margin">28dp</dimen>
+    <!-- Minimum height of button in ActivityBlockingActivity. -->
+    <dimen name="button_min_height">56dp</dimen>
+    <!-- Minimum width of button in ActivityBlockingActivity. -->
+    <dimen name="button_min_width">156dp</dimen>
+    <!-- Padding of button in ActivityBlockingActivity. -->
+    <dimen name="button_padding">16dp</dimen>
+    <!-- Radius of button in ActivityBlockingActivity. -->
+    <dimen name="button_radius">4dp</dimen>
 </resources>
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml
index 2de39f1..599e41f 100644
--- a/service/res/values/strings.xml
+++ b/service/res/values/strings.xml
@@ -103,10 +103,12 @@
     <string name="car_can_bus_failure_desc">CAN bus does not respond. Unplug and plug back headunit
         box and restart the car</string>
 
-    <!-- Blocking activity: Message to show to user when an activity is not allowed during driving. [CHAR LIMIT=120] -->
-    <string name="activity_blocked_string">For your safety, this activity isn’t available while you’re driving</string>
-    <!-- Blocking activity: Button text that restarts the current blocked application. [CHAR LIMIT=10] -->
-    <string name="exit_button">OK</string>
+    <!-- Blocking activity: Message to show to user when a feature of current application is not allowed. [CHAR LIMIT=120] -->
+    <string name="activity_blocked_text">For your safety, this activity isn’t available while you’re driving</string>
+    <!-- Blocking activity: Text for button that shows debug info for non-user build. [CHAR LIMIT=10] -->
+    <string name="debug_button_text">Debug Info</string>
+    <!-- Blocking activity: Text for button that restarts the current blocked application. [CHAR LIMIT=15] -->
+    <string name="exit_button">Restart App</string>
 
     <!-- Permission text: apps can control diagnostic data [CHAR LIMIT=NONE] -->
     <string name="car_permission_label_diag_read">Diagnostic Data</string>
diff --git a/service/res/values/styles.xml b/service/res/values/styles.xml
index 4098e96..35b0b29 100644
--- a/service/res/values/styles.xml
+++ b/service/res/values/styles.xml
@@ -17,21 +17,22 @@
     <!-- TextAppearances for ActivityBlockingActivity. -->
     <style name="ActivityBlockingActivityText">
         <item name="android:fontFamily">sans-serif-medium</item>
+        <item name="android:textColor">@color/blocking_text</item>
         <item name="android:textStyle">normal</item>
         <item name="android:textSize">@dimen/blocking_text_size</item>
     </style>
 
-    <!-- Style of exit button. -->
-    <style name="ExitButtonStyle">
-        <item name="android:background">@drawable/exit_button_ripple_background</item>
+    <!-- Style for buttons in ActivityBlockingActivity. -->
+    <style name="ButtonStyle">
+        <item name="android:background">@drawable/button_ripple_background</item>
         <item name="android:fontFamily">sans-serif-medium</item>
-        <item name="android:minHeight">@dimen/exit_button_min_height</item>
-        <item name="android:minWidth">@dimen/exit_button_min_width</item>
-        <item name="android:paddingHorizontal">@dimen/exit_button_padding</item>
+        <item name="android:minHeight">@dimen/button_min_height</item>
+        <item name="android:minWidth">@dimen/button_min_width</item>
+        <item name="android:paddingHorizontal">@dimen/button_padding</item>
         <item name="android:textAllCaps">true</item>
         <item name="android:textAlignment">center</item>
         <item name="android:textAppearance">@style/ActivityBlockingActivityText</item>
-        <item name="android:textColor">@color/exit_button_text</item>
+        <item name="android:textColor">@color/button_text</item>
     </style>
 </resources>
 
diff --git a/service/src/com/android/car/BluetoothAutoConnectStateMachine.java b/service/src/com/android/car/BluetoothAutoConnectStateMachine.java
index 981db5b..cf9b98e 100644
--- a/service/src/com/android/car/BluetoothAutoConnectStateMachine.java
+++ b/service/src/com/android/car/BluetoothAutoConnectStateMachine.java
@@ -48,12 +48,9 @@
     public static final int CONNECT_TIMEOUT = 103;
     public static final int DEVICE_CONNECTED = 104;
     public static final int DEVICE_DISCONNECTED = 105;
-    // The following is used when PBAP and MAP should be connected to,
-    // after device connects on HFP.
-    public static final int CHECK_CLIENT_PROFILES = 1006;
+    public static final int ADAPTER_OFF = 106;
 
     public static final int CONNECTION_TIMEOUT_MS = 8000;
-    static final int CONNECT_MORE_PROFILES_TIMEOUT_MS = 2000;
 
 
     BluetoothAutoConnectStateMachine(BluetoothDeviceConnectionPolicy policy) {
@@ -84,9 +81,7 @@
 
     /**
      * Idle State is the Initial State, when the system is accepting incoming 'CONNECT' requests.
-     * Attempts a connection whenever the state transitions into Idle.
-     * If the policy finds a device to connect on a profile, transitions to Processing.
-     * If there is nothing to connect to, wait for the next 'CONNECT' message to try next.
+     * Upon 'CONNECT' message move to processing and beging connecting to devices.
      */
     private class Idle extends State {
         @Override
@@ -94,7 +89,6 @@
             if (DBG) {
                 Log.d(TAG, "Enter Idle");
             }
-            connectToBluetoothDevice();
         }
 
         @Override
@@ -107,29 +101,21 @@
                     if (DBG) {
                         Log.d(TAG, "Idle->Connect:");
                     }
-                    connectToBluetoothDevice();
+                    transitionTo(mProcessing);
                     break;
                 }
 
                 case DEVICE_CONNECTED: {
-                    if (DBG) {
-                        Log.d(TAG, "Idle->DeviceConnected: Ignored");
-                    }
-                    break;
-                }
-
-                case CHECK_CLIENT_PROFILES: {
-                    removeMessages(CHECK_CLIENT_PROFILES);
                     BluetoothDeviceConnectionPolicy.ConnectionParams params =
                             (BluetoothDeviceConnectionPolicy.ConnectionParams) msg.obj;
-                    BluetoothDevice device = params.getBluetoothDevice();
-                    // After pairing/disconnect, always try to connect to both PBAP and MAP
-                    if (DBG) {
-                        Log.d(TAG, "try to connect to PBAP/MAP after pairing or disconnect: "
-                                + Utils.getDeviceDebugInfo(device));
+                    if (params.getBluetoothProfile() == BluetoothProfile.HEADSET_CLIENT) {
+                        mPolicy.connectToDeviceOnProfile(BluetoothProfile.PBAP_CLIENT,
+                                params.getBluetoothDevice());
+                        mPolicy.connectToDeviceOnProfile(BluetoothProfile.MAP_CLIENT,
+                                params.getBluetoothDevice());
+                    } else if (DBG) {
+                        Log.d(TAG, "Idle->DeviceConnected: Ignored");
                     }
-                    mPolicy.connectToDeviceOnProfile(BluetoothProfile.PBAP_CLIENT, device);
-                    mPolicy.connectToDeviceOnProfile(BluetoothProfile.MAP_CLIENT, device);
                     break;
                 }
 
@@ -143,24 +129,6 @@
             return true;
         }
 
-        /**
-         * Instruct the policy to find and connect to a device on a connectable profile.
-         * If the policy reports that there is nothing to connect to, stay in the Idle state.
-         * If it found a {device, profile} combination to attempt a connection, move to
-         * Processing state
-         */
-        private void connectToBluetoothDevice() {
-            boolean deviceToConnectFound = mPolicy.findDeviceToConnect();
-            if (deviceToConnectFound) {
-                transitionTo(mProcessing);
-            } else {
-                // Stay in Idle State and wait for the next 'CONNECT' message.
-                if (DBG) {
-                    Log.d(TAG, "Idle->No device to connect");
-                }
-            }
-        }
-
         @Override
         public void exit() {
             if (DBG) {
@@ -173,20 +141,30 @@
     /**
      * Processing state indicates the system is processing a auto connect trigger and will ignore
      * connection requests.
+     * If there are no devices to connect or upon completion, transition back to idle.
      */
     private class Processing extends State {
+        int mConnectionsInProgress;
         @Override
         public void enter() {
             if (DBG) {
                 Log.d(TAG, "Enter Processing");
             }
-
+            mConnectionsInProgress = 0;
+            sendMessageDelayed(CONNECT_TIMEOUT, CONNECTION_TIMEOUT_MS);
+            for (Integer profile : mPolicy.mProfilesToConnect) {
+                connectDeviceOnProfile(profile);
+            }
+            if (mConnectionsInProgress == 0) {
+                transitionTo(mIdle);
+            }
         }
 
         @Override
         public boolean processMessage(Message msg) {
             if (DBG) {
                 Log.d(TAG, "Processing processMessage " + msg.what);
+                Log.d(TAG, "Connections in Progress = " + mConnectionsInProgress);
             }
             BluetoothDeviceConnectionPolicy.ConnectionParams params;
             switch (msg.what) {
@@ -203,10 +181,21 @@
                 case DEVICE_CONNECTED:
                     // fall through
                 case DEVICE_DISCONNECTED: {
-                    removeMessages(CONNECT_TIMEOUT);
-                    transitionTo(mIdle);
+                    mConnectionsInProgress--;
+                    params = (BluetoothDeviceConnectionPolicy.ConnectionParams) msg.obj;
+                    connectDeviceOnProfile(params.getBluetoothProfile());
+
+                    if (mConnectionsInProgress == 0) {
+                        transitionTo(mIdle);
+                    } else {
+                        removeMessages(CONNECT_TIMEOUT);
+                        sendMessageDelayed(CONNECT_TIMEOUT, CONNECTION_TIMEOUT_MS);
+                    }
                     break;
                 }
+                case ADAPTER_OFF:
+                    transitionTo(mIdle);
+                    break;
 
                 default:
                     if (DBG) {
@@ -222,6 +211,19 @@
             if (DBG) {
                 Log.d(TAG, "Exit Processing");
             }
+            removeMessages(CONNECT_TIMEOUT);
+
+        }
+
+        void connectDeviceOnProfile(int profile) {
+            BluetoothDevicesInfo devInfo = mPolicy.mProfileToConnectableDevicesMap.get(profile);
+            if (devInfo != null && devInfo.isProfileConnectableLocked()) {
+                BluetoothDevice device = devInfo.getNextDeviceInQueueLocked();
+                if (device != null) {
+                    mConnectionsInProgress++;
+                    mPolicy.connectToDeviceOnProfile(profile, device);
+                }
+            }
         }
     }
 
diff --git a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
index f9c8a1e..51bbf8d 100644
--- a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
+++ b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java
@@ -97,7 +97,7 @@
     private final Object mSetupLock = new Object();
 
     // The main data structure that holds on to the {profile:list of known and connectible devices}
-    private HashMap<Integer, BluetoothDevicesInfo> mProfileToConnectableDevicesMap;
+    HashMap<Integer, BluetoothDevicesInfo> mProfileToConnectableDevicesMap;
 
     /// TODO(vnori): fix this. b/70029056
     private static final int NUM_SUPPORTED_PHONE_CONNECTIONS = 4; // num of HFP and PBAP connections
@@ -133,10 +133,11 @@
     private final FastPairProvider mFastPairProvider;
 
     // The Bluetooth profiles that the CarService will try to auto-connect on.
-    private final List<Integer> mProfilesToConnect;
+    final List<Integer> mProfilesToConnect;
     private final List<Integer> mPrioritiesSupported;
     private static final int MAX_CONNECT_RETRIES = 1;
     private static final int PROFILE_NOT_AVAILABLE = -1;
+    private int mUserId;
 
     // Device & Profile currently being connected on
     private ConnectionParams mConnectionInFlight;
@@ -318,6 +319,8 @@
                     initiateConnection();
                 } else if (currState == BluetoothAdapter.STATE_OFF) {
                     // Write currently connected device snapshot to file.
+                    mBluetoothAutoConnectStateMachine.sendMessage(
+                            BluetoothAutoConnectStateMachine.ADAPTER_OFF);
                     writeDeviceInfoToSettings();
                     resetBluetoothDevicesConnectionInfo();
                 }
@@ -539,6 +542,7 @@
                 }
                 return;
             }
+            mUserId = ActivityManager.getCurrentUser();
             mBluetoothAutoConnectStateMachine = BluetoothAutoConnectStateMachine.make(this);
             readAndRebuildDeviceMapFromSettings();
             setupBluetoothEventsIntentFilterLocked();
@@ -1217,32 +1221,6 @@
                     + deviceThatConnected);
         }
 
-        // If the device just connected to HEADSET_CLIENT profile, initiate
-        // connections on PBAP & MAP profiles but let that begin after a timeout period.
-        // timeout allows A2DP profile to complete its connection, so that there is no race
-        // condition between
-        //         Phone trying to connect on A2DP
-        //         and, Car trying to connect on PBAP & MAP.
-        if (didConnect && profileToUpdate == BluetoothProfile.HEADSET_CLIENT) {
-            // Unlock the profiles PBAP, MAP in BluetoothDevicesInfo, so that they can be
-            // connected on.
-            for (Integer profile : Arrays.asList(BluetoothProfile.PBAP_CLIENT,
-                    BluetoothProfile.MAP_CLIENT)) {
-                BluetoothDevicesInfo devInfo = mProfileToConnectableDevicesMap.get(profile);
-                if (devInfo == null) {
-                    Log.e(TAG, "Unexpected: No device Queue for this profile: " + profile);
-                    return false;
-                }
-                devInfo.setDeviceAvailableToConnectLocked(true);
-            }
-            if (DBG) {
-                Log.d(TAG, "connect to PBAP/MAP after disconnect: ");
-            }
-            mBluetoothAutoConnectStateMachine.sendMessageDelayed(
-                    BluetoothAutoConnectStateMachine.CHECK_CLIENT_PROFILES, params,
-                    BluetoothAutoConnectStateMachine.CONNECT_MORE_PROFILES_TIMEOUT_MS);
-        }
-
         // If the connection update is on a different profile or device (a very rare possibility),
         // it is handled automatically.  Just logging it here.
         if (DBG) {
@@ -1422,18 +1400,17 @@
             if (DBG) {
                 Log.d(TAG, "Profile: " + profileToUpdate + " Writing: " + joinedDeviceNames);
             }
-            long userId = ActivityManager.getCurrentUser();
             switch (profileToUpdate) {
                 case BluetoothProfile.A2DP_SINK:
                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
                             KEY_BLUETOOTH_AUTOCONNECT_MUSIC_DEVICES,
-                            joinedDeviceNames, (int) userId);
+                            joinedDeviceNames, mUserId);
                     break;
 
                 case BluetoothProfile.HEADSET_CLIENT:
                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
                             KEY_BLUETOOTH_AUTOCONNECT_PHONE_DEVICES,
-                            joinedDeviceNames, (int) userId);
+                            joinedDeviceNames, mUserId);
                     break;
 
                 case BluetoothProfile.PBAP_CLIENT:
@@ -1443,12 +1420,12 @@
                 case BluetoothProfile.MAP_CLIENT:
                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
                             KEY_BLUETOOTH_AUTOCONNECT_MESSAGING_DEVICES,
-                            joinedDeviceNames, (int) userId);
+                            joinedDeviceNames, mUserId);
                     break;
                 case BluetoothProfile.PAN:
                     Settings.Secure.putStringForUser(mContext.getContentResolver(),
                             KEY_BLUETOOTH_AUTOCONNECT_NETWORK_DEVICES,
-                            joinedDeviceNames, (int) userId);
+                            joinedDeviceNames, mUserId);
                     break;
             }
         }
@@ -1489,26 +1466,25 @@
         }
         // Read from Settings.Secure for the current user.  There are 3 keys 1 each for Phone
         // (HFP & PBAP), 1 for Music (A2DP) and 1 for Messaging device (MAP)
-        long userId = ActivityManager.getCurrentUser();
         for (Integer profile : mProfilesToConnect) {
             switch (profile) {
                 case BluetoothProfile.A2DP_SINK:
                     devices = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                            KEY_BLUETOOTH_AUTOCONNECT_MUSIC_DEVICES, (int) userId);
+                            KEY_BLUETOOTH_AUTOCONNECT_MUSIC_DEVICES, mUserId);
                     break;
                 case BluetoothProfile.PBAP_CLIENT:
                     // fall through
                 case BluetoothProfile.HEADSET_CLIENT:
                     devices = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                            KEY_BLUETOOTH_AUTOCONNECT_PHONE_DEVICES, (int) userId);
+                            KEY_BLUETOOTH_AUTOCONNECT_PHONE_DEVICES, mUserId);
                     break;
                 case BluetoothProfile.MAP_CLIENT:
                     devices = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                            KEY_BLUETOOTH_AUTOCONNECT_MESSAGING_DEVICES, (int) userId);
+                            KEY_BLUETOOTH_AUTOCONNECT_MESSAGING_DEVICES, mUserId);
                     break;
                 case BluetoothProfile.PAN:
                     devices = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                            KEY_BLUETOOTH_AUTOCONNECT_NETWORK_DEVICES, (int) userId);
+                            KEY_BLUETOOTH_AUTOCONNECT_NETWORK_DEVICES, mUserId);
                 default:
                     Log.e(TAG, "Unexpected profile");
                     break;
diff --git a/service/src/com/android/car/Utils.java b/service/src/com/android/car/Utils.java
index 78f5a8e..284e610 100644
--- a/service/src/com/android/car/Utils.java
+++ b/service/src/com/android/car/Utils.java
@@ -10,6 +10,9 @@
     static final Boolean DBG = false;
 
     static String getDeviceDebugInfo(BluetoothDevice device) {
+        if (device == null) {
+            return "(null)";
+        }
         return "(name = " + device.getName() + ", addr = " + device.getAddress() + ")";
     }
 
diff --git a/service/src/com/android/car/pm/ActivityBlockingActivity.java b/service/src/com/android/car/pm/ActivityBlockingActivity.java
index b39910e..fd792a6 100644
--- a/service/src/com/android/car/pm/ActivityBlockingActivity.java
+++ b/service/src/com/android/car/pm/ActivityBlockingActivity.java
@@ -15,6 +15,11 @@
  */
 package com.android.car.pm;
 
+import static com.android.car.pm.CarPackageManagerService.BLOCKING_INTENT_EXTRA_BLOCKED_ACTIVITY_NAME;
+import static com.android.car.pm.CarPackageManagerService.BLOCKING_INTENT_EXTRA_BLOCKED_TASK_ID;
+import static com.android.car.pm.CarPackageManagerService.BLOCKING_INTENT_EXTRA_IS_ROOT_ACTIVITY_DO;
+import static com.android.car.pm.CarPackageManagerService.BLOCKING_INTENT_EXTRA_ROOT_ACTIVITY_NAME;
+
 import android.app.Activity;
 import android.car.Car;
 import android.car.CarNotConnectedException;
@@ -24,32 +29,39 @@
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
+import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
+
 import com.android.car.CarLog;
 import com.android.car.R;
 
 /**
  * Default activity that will be launched when the current foreground activity is not allowed.
- * Additional information on blocked Activity will be passed as extra in Intent
- * via {@link #INTENT_KEY_BLOCKED_ACTIVITY} key.
+ * Additional information on blocked Activity should be passed as intent extras.
  */
 public class ActivityBlockingActivity extends Activity {
-    public static final String INTENT_KEY_BLOCKED_ACTIVITY = "blocked_activity";
-    public static final String EXTRA_BLOCKED_TASK = "blocked_task";
-
     private static final int INVALID_TASK_ID = -1;
 
     private Car mCar;
     private CarUxRestrictionsManager mUxRManager;
 
-    private TextView mBlockedTitle;
+    private TextView mBlockingText;
+    private TextView mBlockedAppName;
+    private ImageView mBlockedAppIcon;
     private Button mExitButton;
+
     // Exiting depends on Car connection, which might not be available at the time exit was
     // requested (e.g. user presses Exit Button). In that case, we record exiting was requested, and
     // Car connection will perform exiting once it is established.
@@ -61,9 +73,12 @@
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_blocking);
 
-        mBlockedTitle = findViewById(R.id.activity_blocked_title);
+        mBlockingText = findViewById(R.id.blocking_text);
+        mBlockedAppName = findViewById(R.id.blocked_app_name);
+        mBlockedAppIcon = findViewById(R.id.blocked_app_icon);
         mExitButton = findViewById(R.id.exit);
-        mExitButton.setOnClickListener(v -> handleFinish());
+
+        mBlockingText.setText(getString(R.string.activity_blocked_text));
 
         // Listen to the CarUxRestrictions so this blocking activity can be dismissed when the
         // restrictions are lifted.
@@ -72,7 +87,7 @@
             public void onServiceConnected(ComponentName name, IBinder service) {
                 try {
                     if (mExitRequested) {
-                        handleFinish();
+                        handleRestartingTask();
                     }
                     mUxRManager = (CarUxRestrictionsManager) mCar.getCarManager(
                             Car.CAR_UX_RESTRICTION_SERVICE);
@@ -99,25 +114,82 @@
     protected void onResume() {
         super.onResume();
 
-        // Display message about the current blocked activity, and optionally show an exit button
+        // Display info about the current blocked activity, and optionally show an exit button
         // to restart the blocked task (stack of activities) if its root activity is DO.
+        mBlockedTaskId = getIntent().getIntExtra(BLOCKING_INTENT_EXTRA_BLOCKED_TASK_ID,
+                INVALID_TASK_ID);
 
         // blockedActivity is expected to be always passed in as the topmost activity of task.
-        String blockedActivity = getIntent().getStringExtra(INTENT_KEY_BLOCKED_ACTIVITY);
-        mBlockedTitle.setText(getString(R.string.activity_blocked_string));
-        if (Log.isLoggable(CarLog.TAG_AM, Log.DEBUG)) {
-            Log.d(CarLog.TAG_AM, "Blocking activity " + blockedActivity);
+        String blockedActivity = getIntent().getStringExtra(
+                BLOCKING_INTENT_EXTRA_BLOCKED_ACTIVITY_NAME);
+        if (!TextUtils.isEmpty(blockedActivity)) {
+            if (Log.isLoggable(CarLog.TAG_AM, Log.DEBUG)) {
+                Log.d(CarLog.TAG_AM, "Blocking activity " + blockedActivity);
+            }
+            // Show application icon and name of blocked activity.
+            Drawable appIcon = findApplicationIcon(blockedActivity);
+            if (appIcon != null) {
+                mBlockedAppIcon.setImageDrawable(appIcon);
+            } else {
+                mBlockedAppIcon.setVisibility(View.GONE);
+            }
+            mBlockedAppName.setText(findHumanReadableLabel(blockedActivity));
         }
 
-        // taskId is available as extra if the task can be restarted.
-        mBlockedTaskId = getIntent().getIntExtra(EXTRA_BLOCKED_TASK, INVALID_TASK_ID);
+        boolean isRootDO = getIntent().getBooleanExtra(
+                BLOCKING_INTENT_EXTRA_IS_ROOT_ACTIVITY_DO, false);
 
-        mExitButton.setVisibility(mBlockedTaskId == INVALID_TASK_ID ? View.GONE : View.VISIBLE);
-        if (Log.isLoggable(CarLog.TAG_AM, Log.DEBUG) && mBlockedTaskId == INVALID_TASK_ID) {
-            Log.d(CarLog.TAG_AM, "Blocked task ID is not available. Hiding exit button.");
+        // Display a button to restart task if root task is DO.
+        boolean showButton = mBlockedTaskId != INVALID_TASK_ID && isRootDO;
+        mExitButton.setVisibility(showButton ? View.VISIBLE : View.GONE);
+        mExitButton.setOnClickListener(v -> handleRestartingTask());
+
+        // Show more debug info for non-user build.
+        if (Build.IS_ENG || Build.IS_USERDEBUG) {
+            displayDebugInfo();
         }
     }
 
+    private void displayDebugInfo() {
+        String blockedActivity = getIntent().getStringExtra(
+                BLOCKING_INTENT_EXTRA_BLOCKED_ACTIVITY_NAME);
+        String rootActivity = getIntent().getStringExtra(BLOCKING_INTENT_EXTRA_ROOT_ACTIVITY_NAME);
+
+        TextView debugInfo = findViewById(R.id.debug_info);
+        debugInfo.setText(getDebugInfo(blockedActivity, rootActivity));
+
+        // We still want to ensure driving safety for non-user build;
+        // toggle visibility of debug info with this button.
+        Button toggleDebug = findViewById(R.id.toggle_debug_info);
+        toggleDebug.setVisibility(View.VISIBLE);
+        toggleDebug.setOnClickListener(v -> {
+            boolean isDebugVisible = debugInfo.getVisibility() == View.VISIBLE;
+            debugInfo.setVisibility(isDebugVisible ? View.GONE : View.VISIBLE);
+        });
+    }
+
+    private String getDebugInfo(String blockedActivity, String rootActivity) {
+        StringBuilder debug = new StringBuilder();
+
+        ComponentName blocked = ComponentName.unflattenFromString(blockedActivity);
+        debug.append("Blocked activity is ")
+                .append(blocked.getShortClassName())
+                .append("\nBlocked activity package is ")
+                .append(blocked.getPackageName());
+
+        if (rootActivity != null) {
+            ComponentName root = ComponentName.unflattenFromString(rootActivity);
+            // Optionally show root activity info if it differs from the blocked activity.
+            if (!root.equals(blocked)) {
+                debug.append("\n\nRoot activity is ").append(root.getShortClassName());
+            }
+            if (!root.getPackageName().equals(blocked.getPackageName())) {
+                debug.append("\nRoot activity package is ").append(root.getPackageName());
+            }
+        }
+        return debug.toString();
+    }
+
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
@@ -149,7 +221,51 @@
         }
     }
 
-    private void handleFinish() {
+    // Finds the icon of the application (package) the component belongs to.
+    @Nullable
+    private Drawable findApplicationIcon(String flattenComponentName) {
+        ComponentName componentName = ComponentName.unflattenFromString(flattenComponentName);
+        try {
+            return getPackageManager().getApplicationIcon(componentName.getPackageName());
+        } catch (PackageManager.NameNotFoundException e) {
+            if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
+                Log.i(CarLog.TAG_AM, "Could not find package for component name "
+                        + componentName.toString());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns a human-readable string for {@code flattenComponentName}.
+     *
+     * <p>It first attempts to return the application label for this activity. If that fails,
+     * it will return the last part in the activity name.
+     */
+    private String findHumanReadableLabel(String flattenComponentName) {
+        ComponentName componentName = ComponentName.unflattenFromString(flattenComponentName);
+        String label = null;
+        // Attempt to find application label.
+        try {
+            ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(
+                    componentName.getPackageName(), 0);
+            CharSequence appLabel = getPackageManager().getApplicationLabel(applicationInfo);
+            if (appLabel != null) {
+                label = appLabel.toString();
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
+                Log.i(CarLog.TAG_AM, "Could not find package for component name "
+                        + componentName.toString());
+            }
+        }
+        if (TextUtils.isEmpty(label)) {
+            label = componentName.getClass().getSimpleName();
+        }
+        return label;
+    }
+
+    private void handleRestartingTask() {
         if (!mCar.isConnected()) {
             mExitRequested = true;
             return;
@@ -158,9 +274,12 @@
             return;
         }
 
-        // Lock on self (assuming single instance) to avoid restarting the same task twice.
+        // Lock on self to avoid restarting the same task twice.
         synchronized (this) {
             try {
+                if (Log.isLoggable(CarLog.TAG_AM, Log.INFO)) {
+                    Log.i(CarLog.TAG_AM, "Restarting task " + mBlockedTaskId);
+                }
                 CarPackageManager carPm = (CarPackageManager)
                         mCar.getCarManager(Car.PACKAGE_SERVICE);
                 carPm.restartTask(mBlockedTaskId);
diff --git a/service/src/com/android/car/pm/CarPackageManagerService.java b/service/src/com/android/car/pm/CarPackageManagerService.java
index ed51a78..1c50db9 100644
--- a/service/src/com/android/car/pm/CarPackageManagerService.java
+++ b/service/src/com/android/car/pm/CarPackageManagerService.java
@@ -141,6 +141,32 @@
     // To track if we received the boot complete intent.
     private boolean mBootLockedIntentRx;
 
+    /**
+     * Name of blocked activity.
+     *
+     * @hide
+     */
+    public static final String BLOCKING_INTENT_EXTRA_BLOCKED_ACTIVITY_NAME = "blocked_activity";
+    /**
+     * int task id of the blocked task.
+     *
+     * @hide
+     */
+    public static final String BLOCKING_INTENT_EXTRA_BLOCKED_TASK_ID = "blocked_task_id";
+    /**
+     * Name of root activity of blocked task.
+     *
+     * @hide
+     */
+    public static final String BLOCKING_INTENT_EXTRA_ROOT_ACTIVITY_NAME = "root_activity_name";
+    /**
+     * Boolean indicating whether the root activity is distraction-optimized (DO).
+     * Blocking screen should show a button to restart the task if {@code true}.
+     *
+     * @hide
+     */
+    public static final String BLOCKING_INTENT_EXTRA_IS_ROOT_ACTIVITY_DO = "is_root_activity_do";
+
     public CarPackageManagerService(Context context,
             CarUxRestrictionsManagerService uxRestrictionsService,
             SystemActivityMonitoringService systemActivityMonitoringService) {
@@ -935,45 +961,64 @@
                     " not allowed, will block, number of tasks in stack:" +
                     topTask.stackInfo.taskIds.length);
         }
-        StringBuilder blockedActivityLog = new StringBuilder();
-        Intent newActivityIntent = new Intent();
-        newActivityIntent.setComponent(mActivityBlockingActivity);
-        newActivityIntent.putExtra(
-                ActivityBlockingActivity.INTENT_KEY_BLOCKED_ACTIVITY,
-                topTask.topActivity.flattenToString());
-        blockedActivityLog.append("Blocked activity ")
-                .append(topTask.topActivity.flattenToShortString())
-                .append(". Task id ").append(topTask.taskId);
 
-        // If root activity of blocked task is DO, also pass its task id into blocking activity,
-        // which uses the id to display a button for restarting the blocked task.
+        // Figure out the root activity of blocked task.
+        String taskRootActivity = null;
         for (int i = 0; i < topTask.stackInfo.taskIds.length; i++) {
             // topTask.taskId is the task that should be blocked.
             if (topTask.stackInfo.taskIds[i] == topTask.taskId) {
                 // stackInfo represents an ActivityStack. Its fields taskIds and taskNames
                 // are 1:1 mapped, where taskNames is the name of root activity in this task.
-                String taskRootActivity = topTask.stackInfo.taskNames[i];
-
-                ComponentName rootActivityName = ComponentName.unflattenFromString(
-                        taskRootActivity);
-                if (isActivityDistractionOptimized(
-                        rootActivityName.getPackageName(), rootActivityName.getClassName())) {
-                    newActivityIntent.putExtra(
-                            ActivityBlockingActivity.EXTRA_BLOCKED_TASK, topTask.taskId);
-                    if (Log.isLoggable(CarLog.TAG_PACKAGE, Log.INFO)) {
-                        Log.i(CarLog.TAG_PACKAGE, "Blocked task " + topTask.taskId
-                                + " has DO root activity " + taskRootActivity);
-                    }
-                    blockedActivityLog.append(". Root DO activity ")
-                            .append(rootActivityName.flattenToShortString());
-                }
+                taskRootActivity = topTask.stackInfo.taskNames[i];
                 break;
             }
         }
-        addLog(blockedActivityLog.toString());
+
+        boolean isRootDO = false;
+        if (taskRootActivity != null) {
+            ComponentName componentName = ComponentName.unflattenFromString(taskRootActivity);
+            isRootDO = isActivityDistractionOptimized(
+                    componentName.getPackageName(), componentName.getClassName());
+        }
+
+        Intent newActivityIntent = createBlockingActivityIntent(
+                mActivityBlockingActivity, topTask.topActivity.flattenToShortString(),
+                topTask.taskId, taskRootActivity, isRootDO);
+
+        // Intent contains all info to debug what is blocked - log into both logcat and dumpsys.
+        String log = "Starting blocking activity with intent: " + newActivityIntent.toUri(0);
+        if (Log.isLoggable(CarLog.TAG_PACKAGE, Log.INFO)) {
+            Log.i(CarLog.TAG_PACKAGE, log);
+        }
+        addLog(log);
         mSystemActivityMonitoringService.blockActivity(topTask, newActivityIntent);
     }
 
+    /**
+     * Creates an intent to start blocking activity.
+     *
+     * @param blockingActivity the activity to launch
+     * @param blockedActivity the activity being blocked
+     * @param blockedTaskId the blocked task id, which contains the blocked activity
+     * @param taskRootActivity root activity of the blocked task
+     *
+     * @return an intent to launch the blocking activity.
+     */
+    private static Intent createBlockingActivityIntent(ComponentName blockingActivity,
+            String blockedActivity, int blockedTaskId, String taskRootActivity, boolean isRootDo) {
+        Intent newActivityIntent = new Intent();
+        newActivityIntent.setComponent(blockingActivity);
+        newActivityIntent.putExtra(
+                BLOCKING_INTENT_EXTRA_BLOCKED_ACTIVITY_NAME, blockedActivity);
+        newActivityIntent.putExtra(
+                BLOCKING_INTENT_EXTRA_BLOCKED_TASK_ID, blockedTaskId);
+        newActivityIntent.putExtra(
+                BLOCKING_INTENT_EXTRA_ROOT_ACTIVITY_NAME, taskRootActivity);
+        newActivityIntent.putExtra(
+                BLOCKING_INTENT_EXTRA_IS_ROOT_ACTIVITY_DO, isRootDo);
+        return newActivityIntent;
+    }
+
     private void blockTopActivitiesIfNecessary() {
         boolean restricted = mUxRestrictionsListener.isRestricted();
         if (!restricted) {