diff options
| author | 2022-03-29 22:42:07 +0800 | |
|---|---|---|
| committer | 2022-04-06 13:56:35 +0000 | |
| commit | e230a7d8fdff5b9a981b4d00a88bee584290e275 (patch) | |
| tree | e06c5be475e8705702ec5764133accb3c2b44bbc | |
| parent | 7038aedd7c997cd9d3f8caf83c9331c2d281f09d (diff) | |
Update the strings on app unavailable alert dialog
- Update strings on Settings unavailable alert dialog to match
UX guidelines.
- Update strings on other apps unavailable alert dialog to
match UX guidelines.
- Add the test cases.
Bug: 227283466
Test: Manual, atest FrameworksServicesTests:VirtualDeviceManagerServiceTest
Change-Id: I9a527db49e3f6e6d3c147a18a3e4c8e403cda6bd
5 files changed, 219 insertions, 13 deletions
diff --git a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java index 2d6c77fdc41b..ca111a49235e 100644 --- a/core/java/com/android/internal/app/BlockedAppStreamingActivity.java +++ b/core/java/com/android/internal/app/BlockedAppStreamingActivity.java @@ -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); diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 3d73a02fca4a..b5aa38b6729b 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -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> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index dd69fa0bebb2..f20db16d3497 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3284,7 +3284,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" /> 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 e4b839af8b2e..235d28691fac 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -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, diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index c96b4d66f293..d1b015674b3a 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -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()); + } } |