Merge "Update the strings on app unavailable alert dialog" into tm-dev

This commit is contained in:
Cliff Wu
2022-04-08 15:48:52 +00:00
committed by Android (Google) Code Review
5 changed files with 219 additions and 13 deletions

View File

@@ -36,6 +36,7 @@ public class BlockedAppStreamingActivity extends AlertActivity {
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";
private static final String BLOCKED_COMPONENT_SETTINGS = "com.android.settings";
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -56,13 +57,24 @@ public class BlockedAppStreamingActivity extends AlertActivity {
CharSequence streamedDeviceName = intent.getCharSequenceExtra(EXTRA_STREAMED_DEVICE);
if (!TextUtils.isEmpty(streamedDeviceName)) {
mAlertParams.mTitle =
TextUtils.equals(activityInfo.packageName,
getPackageManager().getPermissionControllerPackageName())
? getString(R.string.app_streaming_blocked_title_for_permission_dialog)
: getString(R.string.app_streaming_blocked_title, appLabel);
mAlertParams.mMessage =
getString(R.string.app_streaming_blocked_message, streamedDeviceName);
if (TextUtils.equals(activityInfo.packageName,
getPackageManager().getPermissionControllerPackageName())) {
mAlertParams.mTitle =
getString(R.string.app_streaming_blocked_title_for_permission_dialog);
mAlertParams.mMessage =
getString(R.string.app_streaming_blocked_message_for_permission_dialog,
streamedDeviceName);
} else if (TextUtils.equals(activityInfo.packageName, BLOCKED_COMPONENT_SETTINGS)) {
mAlertParams.mTitle =
getString(R.string.app_streaming_blocked_title_for_settings_dialog);
mAlertParams.mMessage =
getString(R.string.app_streaming_blocked_message, streamedDeviceName);
} else {
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);

View File

@@ -5459,12 +5459,36 @@
<string name="app_streaming_blocked_title"><xliff:g id="activity" example="Permission dialog">%1$s</xliff:g> unavailable</string>
<!-- Title of the dialog shown when the permissioncontroller is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_permission_dialog">Permission needed</string>
<!-- Title of the dialog shown when the camera permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_camera_dialog">Camera unavailable</string>
<!-- Title of the dialog shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_fingerprint_dialog">Continue on phone</string>
<!-- Title of the dialog shown when the microphone permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_microphone_dialog">Microphone unavailable</string>
<!-- Title of the dialog shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_settings_dialog" product="tv">Android TV settings unavailable</string>
<!-- Title of the dialog shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_settings_dialog" product="tablet">Tablet settings unavailable</string>
<!-- Title of the dialog shown when the settings is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_title_for_settings_dialog" product="default">Phone settings 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>
<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>. 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>
<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>. 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>
<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>. Try on your phone 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_for_permission_dialog" 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_for_permission_dialog" 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_for_permission_dialog" 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 shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv">This app is requesting additional security. Try on your Android TV device instead.</string>
<!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet">This app is requesting additional security. Try on your tablet instead.</string>
<!-- Message shown when the fingerprint permission is blocked from being streamed to a remote device. [CHAR LIMIT=NONE] -->
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default">This app is requesting additional security. 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>

View File

@@ -3285,7 +3285,13 @@
<java-symbol type="string" name="app_streaming_blocked_title" />
<java-symbol type="string" name="app_streaming_blocked_title_for_permission_dialog" />
<java-symbol type="string" name="app_streaming_blocked_title_for_camera_dialog" />
<java-symbol type="string" name="app_streaming_blocked_title_for_fingerprint_dialog" />
<java-symbol type="string" name="app_streaming_blocked_title_for_microphone_dialog" />
<java-symbol type="string" name="app_streaming_blocked_title_for_settings_dialog" />
<java-symbol type="string" name="app_streaming_blocked_message" />
<java-symbol type="string" name="app_streaming_blocked_message_for_permission_dialog" />
<java-symbol type="string" name="app_streaming_blocked_message_for_fingerprint_dialog" />
<!-- Used internally for assistant to launch activity transitions -->
<java-symbol type="id" name="cross_task_transition" />

View File

@@ -283,6 +283,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
return mVirtualAudioController;
}
@VisibleForTesting
SparseArray<GenericWindowPolicyController> getWindowPolicyControllersForTesting() {
return mWindowPolicyControllers;
}
@RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
@Override // Binder call
public void onAudioSessionStarting(int displayId,

View File

@@ -16,6 +16,8 @@
package com.android.server.companion.virtual;
import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -26,6 +28,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -36,14 +39,19 @@ import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
import android.Manifest;
import android.app.WindowConfiguration;
import android.app.admin.DevicePolicyManager;
import android.companion.AssociationInfo;
import android.companion.virtual.IVirtualDeviceActivityListener;
import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.audio.IAudioConfigChangedCallback;
import android.companion.virtual.audio.IAudioRoutingCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManagerInternal;
@@ -65,11 +73,13 @@ import android.os.WorkSource;
import android.platform.test.annotations.Presubmit;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
import android.view.DisplayInfo;
import android.view.KeyEvent;
import androidx.test.InstrumentationRegistry;
import com.android.internal.app.BlockedAppStreamingActivity;
import com.android.server.LocalServices;
import org.junit.Before;
@@ -80,11 +90,21 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Arrays;
@Presubmit
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class VirtualDeviceManagerServiceTest {
private static final String NONBLOCKED_APP_PACKAGE_NAME = "com.someapp";
private static final String PERMISSION_CONTROLLER_PACKAGE_NAME =
"com.android.permissioncontroller";
private static final String SETTINGS_PACKAGE_NAME = "com.android.settings";
private static final String VENDING_PACKAGE_NAME = "com.android.vending";
private static final String GOOGLE_DIALER_PACKAGE_NAME = "com.google.android.dialer";
private static final String GOOGLE_MAPS_PACKAGE_NAME = "com.google.android.apps.maps";
private static final String DEVICE_NAME = "device name";
private static final int DISPLAY_ID = 2;
private static final int PRODUCT_ID = 10;
@@ -94,10 +114,12 @@ public class VirtualDeviceManagerServiceTest {
private static final int HEIGHT = 1800;
private static final int WIDTH = 900;
private static final Binder BINDER = new Binder("binder");
private static final int FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES = 0x00000;
private Context mContext;
private VirtualDeviceImpl mDeviceImpl;
private InputController mInputController;
private AssociationInfo mAssociationInfo;
@Mock
private InputController.NativeWrapper mNativeWrapperMock;
@Mock
@@ -119,6 +141,30 @@ public class VirtualDeviceManagerServiceTest {
private IAudioRoutingCallback mRoutingCallback;
@Mock
private IAudioConfigChangedCallback mConfigChangedCallback;
@Mock
private ApplicationInfo mApplicationInfoMock;
private ArraySet<ComponentName> getBlockedActivities() {
ArraySet<ComponentName> blockedActivities = new ArraySet<>();
blockedActivities.add(new ComponentName(SETTINGS_PACKAGE_NAME, SETTINGS_PACKAGE_NAME));
blockedActivities.add(new ComponentName(VENDING_PACKAGE_NAME, VENDING_PACKAGE_NAME));
blockedActivities.add(
new ComponentName(GOOGLE_DIALER_PACKAGE_NAME, GOOGLE_DIALER_PACKAGE_NAME));
blockedActivities.add(
new ComponentName(GOOGLE_MAPS_PACKAGE_NAME, GOOGLE_MAPS_PACKAGE_NAME));
return blockedActivities;
}
private ArrayList<ActivityInfo> getActivityInfoList(
String packageName, String name, boolean displayOnRemoveDevices) {
ActivityInfo activityInfo = new ActivityInfo();
activityInfo.packageName = packageName;
activityInfo.name = name;
activityInfo.flags = displayOnRemoveDevices
? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES;
activityInfo.applicationInfo = mApplicationInfoMock;
return new ArrayList<>(Arrays.asList(activityInfo));
}
@Before
public void setUp() {
@@ -151,13 +197,18 @@ public class VirtualDeviceManagerServiceTest {
when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
mInputController = new InputController(new Object(), mNativeWrapperMock);
AssociationInfo associationInfo = new AssociationInfo(1, 0, null,
mAssociationInfo = new AssociationInfo(1, 0, null,
MacAddress.BROADCAST_ADDRESS, "", null, true, false, 0, 0);
VirtualDeviceParams params = new VirtualDeviceParams
.Builder()
.setBlockedActivities(getBlockedActivities())
.build();
mDeviceImpl = new VirtualDeviceImpl(mContext,
associationInfo, new Binder(), /* uid */ 0, mInputController,
mAssociationInfo, new Binder(), /* uid */ 0, mInputController,
(int associationId) -> {
}, mPendingTrampolineCallback, mActivityListener,
new VirtualDeviceParams.Builder().build());
params);
}
@Test
@@ -590,4 +641,112 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.setShowPointerIcon(true);
verify(mInputManagerInternalMock, times(3)).setPointerIconVisible(eq(true), anyInt());
}
@Test
public void openNonBlockedAppOnVirtualDisplay_doesNotStartBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME, /* displayOnRemoveDevices */ true);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext, never()).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
public void openPermissionControllerOnVirtualDisplay_startBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
PERMISSION_CONTROLLER_PACKAGE_NAME,
PERMISSION_CONTROLLER_PACKAGE_NAME, /* displayOnRemoveDevices */ false);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
public void openSettingsOnVirtualDisplay_startBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
SETTINGS_PACKAGE_NAME,
SETTINGS_PACKAGE_NAME, /* displayOnRemoveDevices */ true);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
public void openVendingOnVirtualDisplay_startBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
VENDING_PACKAGE_NAME,
VENDING_PACKAGE_NAME, /* displayOnRemoveDevices */ true);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
public void openGoogleDialerOnVirtualDisplay_startBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
GOOGLE_DIALER_PACKAGE_NAME,
GOOGLE_DIALER_PACKAGE_NAME, /* displayOnRemoveDevices */ true);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
@Test
public void openGoogleMapsOnVirtualDisplay_startBlockedAlertActivity() {
mDeviceImpl.onVirtualDisplayCreatedLocked(DISPLAY_ID);
GenericWindowPolicyController gwpc = mDeviceImpl.getWindowPolicyControllersForTesting().get(
DISPLAY_ID);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
GOOGLE_MAPS_PACKAGE_NAME,
GOOGLE_MAPS_PACKAGE_NAME, /* displayOnRemoveDevices */ true);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
activityInfos.get(0), mAssociationInfo.getDisplayName());
gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
}
}