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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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] -->
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user