Merge "Update blocking screen."
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/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) {