Show error dialog if activity is blocked from streaming

Bug: 203834118
Test: Tested with a virtual device with disallowed activities
Change-Id: I2edf93e3527c261756b52e6ec477e91afc2dd833
This commit is contained in:
Maurice Lam
2022-01-26 13:41:01 -08:00
parent 4795ed77af
commit 62f05520bf
5 changed files with 76 additions and 9 deletions

View File

@@ -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);
}
}

View File

@@ -5467,6 +5467,15 @@
<xliff:g id="app_name" example="Gmail">%1$s</xliff:g> is not available right now.
</string>
<!-- Title of the dialog shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title"><xliff:g id="activity" example="Permission dialog">%1$s</xliff:g> unavailable</string>
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message" product="tv">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your Android TV device instead.</string>
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message" product="tablet">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your tablet instead.</string>
<!-- Message shown when an app is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message" product="default">This can’t be accessed on your <xliff:g id="device" example="Chromebook">%1$s</xliff:g> at this time. Try on your phone instead.</string>
<!-- Message displayed in dialog when app is too old to run on this verison of android. [CHAR LIMIT=NONE] -->
<string name="deprecated_target_sdk_message">This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer.</string>
<!-- Title for button to see application detail in app store which it came from - it may allow user to update to newer version. [CHAR LIMIT=50] -->

View File

@@ -3265,6 +3265,9 @@
<java-symbol type="string" name="app_blocked_title" />
<java-symbol type="string" name="app_blocked_message" />
<java-symbol type="string" name="app_streaming_blocked_title" />
<java-symbol type="string" name="app_streaming_blocked_message" />
<!-- Used internally for assistant to launch activity transitions -->
<java-symbol type="id" name="cross_task_transition" />

View File

@@ -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<ComponentName> mAllowedActivities;
@Nullable
private final ArraySet<ComponentName> mBlockedActivities;
private Consumer<ActivityInfo> mActivityBlockedCallback;
@NonNull
final ArraySet<Integer> mRunningUids = new ArraySet<>();
@@ -81,10 +83,12 @@ class GenericWindowPolicyController extends DisplayWindowPolicyController {
@NonNull ArraySet<UserHandle> allowedUsers,
@Nullable Set<ComponentName> allowedActivities,
@Nullable Set<ComponentName> blockedActivities,
@NonNull ActivityListener activityListener) {
@NonNull ActivityListener activityListener,
@NonNull Consumer<ActivityInfo> 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

View File

@@ -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<UserHandle> getAllowedUserHandles() {
ArraySet<UserHandle> result = new ArraySet<>();
DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);