From 62f05520bf246c4d5552d0da2effd1592bbdebbf Mon Sep 17 00:00:00 2001 From: Maurice Lam Date: Wed, 26 Jan 2022 13:41:01 -0800 Subject: [PATCH] Show error dialog if activity is blocked from streaming Bug: 203834118 Test: Tested with a virtual device with disallowed activities Change-Id: I2edf93e3527c261756b52e6ec477e91afc2dd833 --- .../internal/app/BlockedAppActivity.java | 44 ++++++++++++++++--- core/res/res/values/strings.xml | 9 ++++ core/res/res/values/symbols.xml | 3 ++ .../GenericWindowPolicyController.java | 13 +++++- .../companion/virtual/VirtualDeviceImpl.java | 16 ++++++- 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/app/BlockedAppActivity.java b/core/java/com/android/internal/app/BlockedAppActivity.java index fbdbbfb06b780..65526eba3e54c 100644 --- a/core/java/com/android/internal/app/BlockedAppActivity.java +++ b/core/java/com/android/internal/app/BlockedAppActivity.java @@ -17,6 +17,7 @@ package com.android.internal.app; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Bundle; @@ -35,6 +36,9 @@ public class BlockedAppActivity extends AlertActivity { private static final String TAG = "BlockedAppActivity"; private static final String PACKAGE_NAME = "com.android.internal.app"; private static final String EXTRA_BLOCKED_PACKAGE = PACKAGE_NAME + ".extra.BLOCKED_PACKAGE"; + private static final String EXTRA_BLOCKED_ACTIVITY_INFO = + PACKAGE_NAME + ".extra.BLOCKED_ACTIVITY_INFO"; + private static final String EXTRA_STREAMED_DEVICE = PACKAGE_NAME + ".extra.STREAMED_DEVICE"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -48,17 +52,30 @@ public class BlockedAppActivity extends AlertActivity { return; } + CharSequence appLabel = null; String packageName = intent.getStringExtra(EXTRA_BLOCKED_PACKAGE); - if (TextUtils.isEmpty(packageName)) { - Slog.wtf(TAG, "Invalid package: " + packageName); + ActivityInfo activityInfo = intent.getParcelableExtra(EXTRA_BLOCKED_ACTIVITY_INFO); + if (activityInfo != null) { + appLabel = activityInfo.loadLabel(getPackageManager()); + } else if (!TextUtils.isEmpty(packageName)) { + appLabel = getAppLabel(userId, packageName); + } + + if (TextUtils.isEmpty(appLabel)) { + Slog.wtf(TAG, "Invalid package: " + packageName + " or activity info: " + activityInfo); finish(); return; } - CharSequence appLabel = getAppLabel(userId, packageName); - - mAlertParams.mTitle = getString(R.string.app_blocked_title); - mAlertParams.mMessage = getString(R.string.app_blocked_message, appLabel); + CharSequence streamedDeviceName = intent.getCharSequenceExtra(EXTRA_STREAMED_DEVICE); + if (!TextUtils.isEmpty(streamedDeviceName)) { + mAlertParams.mTitle = getString(R.string.app_streaming_blocked_title, appLabel); + mAlertParams.mMessage = + getString(R.string.app_streaming_blocked_message, streamedDeviceName); + } else { + mAlertParams.mTitle = getString(R.string.app_blocked_title); + mAlertParams.mMessage = getString(R.string.app_blocked_message, appLabel); + } mAlertParams.mPositiveButtonText = getString(android.R.string.ok); setupAlert(); } @@ -83,4 +100,19 @@ public class BlockedAppActivity extends AlertActivity { .putExtra(Intent.EXTRA_USER_ID, userId) .putExtra(EXTRA_BLOCKED_PACKAGE, packageName); } + + /** + * Creates an intent that launches {@link BlockedAppActivity} when app streaming is blocked. + * + * Using this method and providing a non-empty {@code streamedDeviceName} will cause the dialog + * to use streaming-specific error messages. + */ + public static Intent createStreamingBlockedIntent(int userId, ActivityInfo activityInfo, + CharSequence streamedDeviceName) { + return new Intent() + .setClassName("android", BlockedAppActivity.class.getName()) + .putExtra(Intent.EXTRA_USER_ID, userId) + .putExtra(EXTRA_BLOCKED_ACTIVITY_INFO, activityInfo) + .putExtra(EXTRA_STREAMED_DEVICE, streamedDeviceName); + } } diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 59ad302c8aeec..996a13370426b 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5467,6 +5467,15 @@ %1$s is not available right now. + + %1$s unavailable + + This can’t be accessed on your %1$s at this time. Try on your Android TV device instead. + + This can’t be accessed on your %1$s at this time. Try on your tablet instead. + + This can’t be accessed on your %1$s at this time. Try on your phone instead. + This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 6ae2829124b7e..4faee4382f4d6 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3265,6 +3265,9 @@ + + + diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index 75acf81a4a3cc..bb49ba059d236 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -39,6 +39,7 @@ import android.window.DisplayWindowPolicyController; import java.util.List; import java.util.Set; +import java.util.function.Consumer; /** @@ -61,6 +62,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { private final ArraySet mAllowedActivities; @Nullable private final ArraySet mBlockedActivities; + private Consumer mActivityBlockedCallback; @NonNull final ArraySet mRunningUids = new ArraySet<>(); @@ -81,10 +83,12 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @NonNull ArraySet allowedUsers, @Nullable Set allowedActivities, @Nullable Set blockedActivities, - @NonNull ActivityListener activityListener) { + @NonNull ActivityListener activityListener, + @NonNull Consumer activityBlockedCallback) { mAllowedUsers = allowedUsers; mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities); mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities); + mActivityBlockedCallback = activityBlockedCallback; setInterestedWindowFlags(windowFlags, systemWindowFlags); mActivityListener = activityListener; } @@ -96,6 +100,7 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { for (int i = 0; i < activityCount; i++) { final ActivityInfo aInfo = activities.get(i); if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) { + mActivityBlockedCallback.accept(aInfo); return false; } } @@ -105,7 +110,11 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController { @Override public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags, int systemWindowFlags) { - return canContainActivity(activityInfo, windowFlags, systemWindowFlags); + if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) { + mActivityBlockedCallback.accept(activityInfo); + return false; + } + return true; } @Override diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 95b9e58a9dfdd..98a5ec1c3681b 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -34,6 +34,8 @@ import android.companion.virtual.VirtualDeviceManager.ActivityListener; import android.companion.virtual.VirtualDeviceParams; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.PointF; import android.hardware.display.DisplayManager; @@ -57,6 +59,7 @@ import android.util.SparseArray; import android.window.DisplayWindowPolicyController; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.BlockedAppActivity; import com.android.server.LocalServices; import java.io.FileDescriptor; @@ -418,7 +421,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub getAllowedUserHandles(), mParams.getAllowedActivities(), mParams.getBlockedActivities(), - createListenerAdapter(displayId)); + createListenerAdapter(displayId), + activityInfo -> onActivityBlocked(displayId, activityInfo)); mWindowPolicyControllers.put(displayId, dwpc); return dwpc; } @@ -441,6 +445,16 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } } + private void onActivityBlocked(int displayId, ActivityInfo activityInfo) { + Intent intent = BlockedAppActivity.createStreamingBlockedIntent( + UserHandle.getUserId(activityInfo.applicationInfo.uid), activityInfo, + mAssociationInfo.getDisplayName()); + mContext.startActivityAsUser( + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(), + mContext.getUser()); + } + private ArraySet getAllowedUserHandles() { ArraySet result = new ArraySet<>(); DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);