diff options
4 files changed, 969 insertions, 16 deletions
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 b56b47f9c727..9dd0dca47f0e 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -121,7 +121,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @NonNull @GuardedBy("mGenericWindowPolicyControllerLock") - final ArraySet<Integer> mRunningUids = new ArraySet<>(); + private final ArraySet<Integer> mRunningUids = new ArraySet<>(); @Nullable private final ActivityListener mActivityListener; @Nullable private final PipBlockedCallback mPipBlockedCallback; @Nullable private final IntentListenerCallback mIntentListenerCallback; diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java new file mode 100644 index 000000000000..a7c8a6cee0d9 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java @@ -0,0 +1,890 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.companion.virtual; + +import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; +import static android.view.WindowManager.LayoutParams.FLAG_SECURE; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.WindowConfiguration; +import android.companion.virtual.IVirtualDeviceIntentInterceptor; +import android.companion.virtual.VirtualDeviceManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.net.Uri; +import android.os.RemoteException; +import android.os.UserHandle; +import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; +import android.util.ArraySet; +import android.view.Display; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.internal.app.BlockedAppStreamingActivity; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +@Presubmit +@RunWith(AndroidJUnit4.class) +public class GenericWindowPolicyControllerTest { + + private static final int DISPLAY_ID = Display.DEFAULT_DISPLAY + 1; + private static final int TEST_UID = 1234567; + private static final String DISPLAY_CATEGORY = "com.display.category"; + private static final String NONBLOCKED_APP_PACKAGE_NAME = "com.someapp"; + private static final String BLOCKED_PACKAGE_NAME = "com.blockedapp"; + private static final int FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES = 0x00000; + private static final String TEST_SITE = "http://test"; + private static final ComponentName BLOCKED_APP_STREAMING_COMPONENT = + new ComponentName("android", BlockedAppStreamingActivity.class.getName()); + private static final ComponentName BLOCKED_COMPONENT = new ComponentName(BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME); + private static final ComponentName NONBLOCKED_COMPONENT = new ComponentName( + NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME); + + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Mock + private GenericWindowPolicyController.PipBlockedCallback mPipBlockedCallback; + @Mock + private VirtualDeviceManager.ActivityListener mActivityListener; + @Mock + private GenericWindowPolicyController.IntentListenerCallback mIntentListenerCallback; + @Mock + private GenericWindowPolicyController.ActivityBlockedCallback mActivityBlockedCallback; + @Mock + private GenericWindowPolicyController.RunningAppsChangedListener mRunningAppsChangedListener; + @Mock + private GenericWindowPolicyController.SecureWindowCallback mSecureWindowCallback; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void showTasksInHostDeviceRecents() { + GenericWindowPolicyController gwpc = createGwpc(); + + gwpc.setShowInHostDeviceRecents(true); + assertThat(gwpc.canShowTasksInHostDeviceRecents()).isTrue(); + + gwpc.setShowInHostDeviceRecents(false); + assertThat(gwpc.canShowTasksInHostDeviceRecents()).isFalse(); + } + + @Test + public void containsUid() { + GenericWindowPolicyController gwpc = createGwpc(); + + assertThat(gwpc.containsUid(TEST_UID)).isFalse(); + + gwpc.onRunningAppsChanged(new ArraySet<>(Arrays.asList(TEST_UID))); + assertThat(gwpc.containsUid(TEST_UID)).isTrue(); + + gwpc.onRunningAppsChanged(new ArraySet<>()); + assertThat(gwpc.containsUid(TEST_UID)).isFalse(); + } + + @Test + public void isEnteringPipAllowed_falseByDefault() { + GenericWindowPolicyController gwpc = createGwpc(); + + assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isFalse(); + verify(mPipBlockedCallback).onEnteringPipBlocked(TEST_UID); + } + + @Test + public void isEnteringPipAllowed_dpcSupportsPinned_allowed() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setSupportedWindowingModes(new HashSet<>( + Arrays.asList(WindowConfiguration.WINDOWING_MODE_FULLSCREEN, + WindowConfiguration.WINDOWING_MODE_PINNED))); + assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isTrue(); + verify(mPipBlockedCallback, never()).onEnteringPipBlocked(TEST_UID); + } + + @Test + public void openNonBlockedAppOnVirtualDisplay_isNotBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void activityDoesNotSupportDisplayOnRemoteDevices_isBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ false, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void openBlockedComponentOnVirtualDisplay_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithBlockedComponent(BLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void addActivityPolicyExemption_openBlockedOnVirtualDisplay_isBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + gwpc.setActivityLaunchDefaultAllowed(true); + gwpc.addActivityPolicyExemption(BLOCKED_COMPONENT); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void openNotAllowedComponentOnBlocklistVirtualDisplay_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithAllowedComponent(NONBLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void addActivityPolicyExemption_openNotAllowedOnVirtualDisplay_isBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + gwpc.setActivityLaunchDefaultAllowed(false); + gwpc.addActivityPolicyExemption(NONBLOCKED_COMPONENT); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void openAllowedComponentOnBlocklistVirtualDisplay_startsActivity() { + GenericWindowPolicyController gwpc = createGwpcWithAllowedComponent(NONBLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void addActivityPolicyExemption_openAllowedOnVirtualDisplay_startsActivity() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + gwpc.setActivityLaunchDefaultAllowed(false); + gwpc.addActivityPolicyExemption(NONBLOCKED_COMPONENT); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_mismatchingUserHandle_isBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null, + /* uid */ UserHandle.PER_USER_RANGE + 1); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_blockedAppStreamingComponent_isNeverBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_APP_STREAMING_COMPONENT.getPackageName(), + BLOCKED_APP_STREAMING_COMPONENT.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_blockedAppStreamingComponentExplicitlyBlocked_isNeverBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithBlockedComponent( + BLOCKED_APP_STREAMING_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_APP_STREAMING_COMPONENT.getPackageName(), + BLOCKED_APP_STREAMING_COMPONENT.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_blockedAppStreamingComponentExemptFromStreaming_isNeverBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + gwpc.setActivityLaunchDefaultAllowed(true); + gwpc.addActivityPolicyExemption(BLOCKED_APP_STREAMING_COMPONENT); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_APP_STREAMING_COMPONENT.getPackageName(), + BLOCKED_APP_STREAMING_COMPONENT.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_blockedAppStreamingComponentNotAllowlisted_isNeverBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithAllowedComponent(NONBLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_APP_STREAMING_COMPONENT.getPackageName(), + BLOCKED_APP_STREAMING_COMPONENT.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_blockedAppStreamingComponentNotExemptFromBlocklist_isNeverBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + gwpc.setActivityLaunchDefaultAllowed(false); + gwpc.addActivityPolicyExemption(NONBLOCKED_COMPONENT); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_APP_STREAMING_COMPONENT.getPackageName(), + BLOCKED_APP_STREAMING_COMPONENT.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_customDisplayCategoryMatches_isNotBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithDisplayCategory(DISPLAY_CATEGORY); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ DISPLAY_CATEGORY); + + assertActivityCanBeLaunched(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_customDisplayCategoryDoesNotMatch_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithDisplayCategory(DISPLAY_CATEGORY); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ "some.random.category"); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void canActivityBeLaunched_crossTaskLaunch_fromDefaultDisplay_isNotBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, Display.DEFAULT_DISPLAY, true, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + @Test + public void canActivityBeLaunched_crossTaskLaunchFromVirtualDisplay_notExplicitlyBlocked_isNotBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithCrossTaskNavigationBlockedFor( + BLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertActivityCanBeLaunched(gwpc, DISPLAY_ID, true, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + @Test + public void canActivityBeLaunched_crossTaskLaunchFromVirtualDisplay_explicitlyBlocked_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithCrossTaskNavigationBlockedFor( + BLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, DISPLAY_ID, true, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + @Test + public void canActivityBeLaunched_crossTaskLaunchFromVirtualDisplay_notAllowed_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithCrossTaskNavigationAllowed( + NONBLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, DISPLAY_ID, true, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + @Test + public void canActivityBeLaunched_crossTaskLaunchFromVirtualDisplay_allowed_isNotBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithCrossTaskNavigationAllowed( + NONBLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityCanBeLaunched(gwpc, DISPLAY_ID, true, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + @Test + public void canActivityBeLaunched_unsupportedWindowingMode_isBlocked() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, DISPLAY_ID, true, WindowConfiguration.WINDOWING_MODE_PINNED, + activityInfo); + } + + @Test + public void canActivityBeLaunched_permissionComponent_isBlocked() { + GenericWindowPolicyController gwpc = createGwpcWithPermissionComponent(BLOCKED_COMPONENT); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + BLOCKED_PACKAGE_NAME, + BLOCKED_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertActivityIsBlocked(gwpc, activityInfo); + } + + @Test + public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() { + ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID)); + GenericWindowPolicyController gwpc = createGwpc(); + + gwpc.registerRunningAppsChangedListener(mRunningAppsChangedListener); + gwpc.onRunningAppsChanged(uids); + + assertThat(gwpc.getRunningAppsChangedListenersSizeForTesting()).isEqualTo(1); + verify(mRunningAppsChangedListener).onRunningAppsChanged(uids); + } + + @Test + public void onRunningAppsChanged_empty_onDisplayEmpty() { + ArraySet<Integer> uids = new ArraySet<>(); + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + gwpc.onRunningAppsChanged(uids); + + assertThat(gwpc.getRunningAppsChangedListenersSizeForTesting()).isEqualTo(0); + verify(mActivityListener).onDisplayEmpty(DISPLAY_ID); + } + + @Test + public void noRunningAppsChangedListener_onRunningAppsChanged_doesNotThrowException() { + ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID)); + GenericWindowPolicyController gwpc = createGwpc(); + + gwpc.onRunningAppsChanged(uids); + + assertThat(gwpc.getRunningAppsChangedListenersSizeForTesting()).isEqualTo(0); + verify(mRunningAppsChangedListener, never()).onRunningAppsChanged(uids); + } + + @Test + public void registerUnregisterRunningAppsChangedListener_onRunningAppsChanged_doesNotThrowException() { + ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID)); + GenericWindowPolicyController gwpc = createGwpc(); + + gwpc.registerRunningAppsChangedListener(mRunningAppsChangedListener); + gwpc.unregisterRunningAppsChangedListener(mRunningAppsChangedListener); + gwpc.onRunningAppsChanged(uids); + + assertThat(gwpc.getRunningAppsChangedListenersSizeForTesting()).isEqualTo(0); + verify(mRunningAppsChangedListener, never()).onRunningAppsChanged(uids); + } + + @Test + public void canActivityBeLaunched_intentInterceptedWhenRegistered_activityNoLaunch() + throws RemoteException { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(TEST_SITE)); + + IVirtualDeviceIntentInterceptor.Stub interceptor = + mock(IVirtualDeviceIntentInterceptor.Stub.class); + doNothing().when(interceptor).onIntentIntercepted(any()); + doReturn(interceptor).when(interceptor).asBinder(); + doReturn(interceptor).when(interceptor).queryLocalInterface(anyString()); + + GenericWindowPolicyController gwpc = createGwpc(); + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + // register interceptor and intercept intent + when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(true); + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + .isFalse(); + + // unregister interceptor and launch activity + when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false); + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + .isTrue(); + } + + @Test + public void canActivityBeLaunched_noMatchIntentFilter_activityLaunches() { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("testing")); + + GenericWindowPolicyController gwpc = createGwpc(); + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + // register interceptor with different filter + when(mIntentListenerCallback.shouldInterceptIntent(any(Intent.class))).thenReturn(false); + assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID, /*isNewTask=*/false)) + .isTrue(); + verify(mIntentListenerCallback).shouldInterceptIntent(any(Intent.class)); + } + + @Test + public void onTopActivitychanged_null_noCallback() { + GenericWindowPolicyController gwpc = createGwpc(); + + gwpc.onTopActivityChanged(null, 0, 0); + verify(mActivityListener, never()) + .onTopActivityChanged(anyInt(), any(ComponentName.class), anyInt()); + } + + @Test + public void onTopActivitychanged_activityListenerCallbackObserved() { + int userId = 1000; + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + gwpc.onTopActivityChanged(BLOCKED_COMPONENT, 0, userId); + verify(mActivityListener) + .onTopActivityChanged(eq(DISPLAY_ID), eq(BLOCKED_COMPONENT), eq(userId)); + } + + @Test + public void keepActivityOnWindowFlagsChanged_noChange() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertThat(gwpc.keepActivityOnWindowFlagsChanged(activityInfo, 0, 0)).isTrue(); + + verify(mSecureWindowCallback, never()).onSecureWindowShown(DISPLAY_ID, + activityInfo.applicationInfo.uid); + verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo); + } + + @Test + public void keepActivityOnWindowFlagsChanged_flagSecure_isAllowedAfterTM() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertThat(gwpc.keepActivityOnWindowFlagsChanged(activityInfo, FLAG_SECURE, 0)).isTrue(); + + verify(mSecureWindowCallback).onSecureWindowShown(DISPLAY_ID, + activityInfo.applicationInfo.uid); + verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo); + } + + @Test + public void keepActivityOnWindowFlagsChanged_systemFlagHideNonSystemOverlayWindows_isAllowedAfterTM() { + GenericWindowPolicyController gwpc = createGwpc(); + gwpc.setDisplayId(DISPLAY_ID); + + ActivityInfo activityInfo = getActivityInfo( + NONBLOCKED_APP_PACKAGE_NAME, + NONBLOCKED_APP_PACKAGE_NAME, + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + + assertThat(gwpc.keepActivityOnWindowFlagsChanged(activityInfo, 0, + SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS)).isTrue(); + + verify(mSecureWindowCallback, never()).onSecureWindowShown(DISPLAY_ID, + activityInfo.applicationInfo.uid); + verify(mActivityBlockedCallback, never()).onActivityBlocked(DISPLAY_ID, activityInfo); + } + + @Test + public void getCustomHomeComponent_noneSet() { + GenericWindowPolicyController gwpc = createGwpc(); + + assertThat(gwpc.getCustomHomeComponent()).isNull(); + } + + @Test + public void getCustomHomeComponent_returnsHomeComponent() { + GenericWindowPolicyController gwpc = createGwpcWithCustomHomeComponent( + NONBLOCKED_COMPONENT); + + assertThat(gwpc.getCustomHomeComponent()).isEqualTo(NONBLOCKED_COMPONENT); + } + + private GenericWindowPolicyController createGwpc() { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ mSecureWindowCallback, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithCustomHomeComponent( + ComponentName homeComponent) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ homeComponent); + } + + private GenericWindowPolicyController createGwpcWithBlockedComponent( + ComponentName blockedComponent) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ Collections.singleton(blockedComponent), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithAllowedComponent( + ComponentName allowedComponent) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ false, + /* activityPolicyExemptions= */ Collections.singleton(allowedComponent), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithDisplayCategory( + String displayCategory) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ Collections.singleton(displayCategory), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithCrossTaskNavigationBlockedFor( + ComponentName blockedComponent) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ true, + /* crossTaskNavigationExemptions= */ Collections.singleton(blockedComponent), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithCrossTaskNavigationAllowed( + ComponentName allowedComponent) { + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ false, + /* crossTaskNavigationExemptions= */ Collections.singleton(allowedComponent), + /* permissionDialogComponent= */ null, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private GenericWindowPolicyController createGwpcWithPermissionComponent( + ComponentName permissionComponent) { + //TODO instert the component + return new GenericWindowPolicyController( + 0, + 0, + /* allowedUsers= */ new ArraySet<>(getCurrentUserId()), + /* activityLaunchAllowedByDefault= */ true, + /* activityPolicyExemptions= */ new ArraySet<>(), + /* crossTaskNavigationAllowedByDefault= */ false, + /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent= */ permissionComponent, + /* activityListener= */ mActivityListener, + /* pipBlockedCallback= */ mPipBlockedCallback, + /* activityBlockedCallback= */ mActivityBlockedCallback, + /* secureWindowCallback= */ null, + /* intentListenerCallback= */ mIntentListenerCallback, + /* displayCategories= */ new ArraySet<>(), + /* showTasksInHostDeviceRecents= */ true, + /* customHomeComponent= */ null); + } + + private Set<UserHandle> getCurrentUserId() { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + return new ArraySet<>(Arrays.asList(context.getUser())); + } + + private ActivityInfo getActivityInfo( + String packageName, String name, boolean displayOnRemoteDevices, + String requiredDisplayCategory) { + return getActivityInfo(packageName, name, displayOnRemoteDevices, requiredDisplayCategory, + 0); + } + + private ActivityInfo getActivityInfo( + String packageName, String name, boolean displayOnRemoteDevices, + String requiredDisplayCategory, int uid) { + ApplicationInfo applicationInfo = new ApplicationInfo(); + applicationInfo.uid = uid; + + ActivityInfo activityInfo = new ActivityInfo(); + activityInfo.packageName = packageName; + activityInfo.name = name; + activityInfo.flags = displayOnRemoteDevices + ? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES; + activityInfo.applicationInfo = applicationInfo; + activityInfo.requiredDisplayCategory = requiredDisplayCategory; + return activityInfo; + } + + private void assertActivityCanBeLaunched(GenericWindowPolicyController gwpc, + ActivityInfo activityInfo) { + assertActivityCanBeLaunched(gwpc, DISPLAY_ID, false, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + private void assertActivityCanBeLaunched(GenericWindowPolicyController gwpc, int fromDisplay, + boolean isNewTask, int windowingMode, ActivityInfo activityInfo) { + assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay, + isNewTask)).isTrue(); + + verify(mActivityBlockedCallback, never()).onActivityBlocked(fromDisplay, activityInfo); + verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class)); + } + + private void assertActivityIsBlocked(GenericWindowPolicyController gwpc, + ActivityInfo activityInfo) { + assertActivityIsBlocked(gwpc, DISPLAY_ID, false, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, activityInfo); + } + + private void assertActivityIsBlocked(GenericWindowPolicyController gwpc, int fromDisplay, + boolean isNewTask, int windowingMode, ActivityInfo activityInfo) { + assertThat(gwpc.canActivityBeLaunched(activityInfo, null, windowingMode, fromDisplay, + isNewTask)).isFalse(); + + verify(mActivityBlockedCallback).onActivityBlocked(fromDisplay, activityInfo); + verify(mIntentListenerCallback, never()).shouldInterceptIntent(any(Intent.class)); + } +} 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 1e6306cb4071..263d4701eba1 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 @@ -24,6 +24,7 @@ import static android.content.Context.DEVICE_ID_DEFAULT; import static android.content.Context.DEVICE_ID_INVALID; import static android.content.Intent.ACTION_VIEW; import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES; +import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -70,6 +71,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.hardware.Sensor; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; @@ -303,7 +305,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoveDevices= */ true, + /* displayOnRemoteDevices= */ true, targetDisplayCategory); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -314,12 +316,12 @@ public class VirtualDeviceManagerServiceTest { private ActivityInfo getActivityInfo( - String packageName, String name, boolean displayOnRemoveDevices, + String packageName, String name, boolean displayOnRemoteDevices, String requiredDisplayCategory) { ActivityInfo activityInfo = new ActivityInfo(); activityInfo.packageName = packageName; activityInfo.name = name; - activityInfo.flags = displayOnRemoveDevices + activityInfo.flags = displayOnRemoteDevices ? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES; activityInfo.applicationInfo = mApplicationInfoMock; activityInfo.requiredDisplayCategory = requiredDisplayCategory; @@ -1427,7 +1429,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1448,7 +1450,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( PERMISSION_CONTROLLER_PACKAGE_NAME, PERMISSION_CONTROLLER_PACKAGE_NAME, - /* displayOnRemoveDevices */ false, + /* displayOnRemoteDevices */ false, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1513,7 +1515,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( SETTINGS_PACKAGE_NAME, SETTINGS_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1534,7 +1536,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( VENDING_PACKAGE_NAME, VENDING_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1555,7 +1557,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( GOOGLE_DIALER_PACKAGE_NAME, GOOGLE_DIALER_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1576,7 +1578,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( GOOGLE_MAPS_PACKAGE_NAME, GOOGLE_MAPS_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( activityInfo, mAssociationInfo.getDisplayName()); @@ -1616,6 +1618,54 @@ public class VirtualDeviceManagerServiceTest { } @Test + public void canActivityBeLaunched_permissionDialog_flagDisabled_isBlocked() { + mSetFlagsRule.disableFlags(Flags.FLAG_STREAM_PERMISSIONS); + VirtualDeviceParams params = new VirtualDeviceParams.Builder().build(); + mDeviceImpl.close(); + mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); + doNothing().when(mContext).startActivityAsUser(any(), any(), any()); + + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( + DISPLAY_ID_1); + ComponentName permissionComponent = getPermissionDialogComponent(); + ActivityInfo activityInfo = getActivityInfo( + permissionComponent.getPackageName(), + permissionComponent.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertThat(gwpc.canActivityBeLaunched(activityInfo, null, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + .isFalse(); + + Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( + activityInfo, mAssociationInfo.getDisplayName()); + verify(mContext).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + + @Test + public void canActivityBeLaunched_permissionDialog_flagEnabled_isStreamed() { + mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS); + VirtualDeviceParams params = new VirtualDeviceParams.Builder().build(); + mDeviceImpl.close(); + mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params); + + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( + DISPLAY_ID_1); + ComponentName permissionComponent = getPermissionDialogComponent(); + ActivityInfo activityInfo = getActivityInfo( + permissionComponent.getPackageName(), + permissionComponent.getClassName(), + /* displayOnRemoteDevices */ true, + /* targetDisplayCategory */ null); + assertThat(gwpc.canActivityBeLaunched(activityInfo, null, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) + .isTrue(); + } + + @Test public void canActivityBeLaunched_activityCanLaunch() { Intent intent = new Intent(ACTION_VIEW, Uri.parse(TEST_SITE)); addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); @@ -1624,7 +1674,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); assertThat(gwpc.canActivityBeLaunched(activityInfo, intent, WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false)) @@ -1648,7 +1698,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); IntentFilter intentFilter = new IntentFilter(Intent.ACTION_VIEW); @@ -1691,7 +1741,7 @@ public class VirtualDeviceManagerServiceTest { ActivityInfo activityInfo = getActivityInfo( NONBLOCKED_APP_PACKAGE_NAME, NONBLOCKED_APP_PACKAGE_NAME, - /* displayOnRemoveDevices */ true, + /* displayOnRemoteDevices */ true, /* targetDisplayCategory */ null); IntentFilter intentFilter = new IntentFilter(Intent.ACTION_VIEW); @@ -1812,6 +1862,13 @@ public class VirtualDeviceManagerServiceTest { NONBLOCKED_APP_PACKAGE_NAME); } + private ComponentName getPermissionDialogComponent() { + Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS); + PackageManager packageManager = mContext.getPackageManager(); + intent.setPackage(packageManager.getPermissionControllerPackageName()); + return intent.resolveActivity(packageManager); + } + /** Helper class to drop permissions temporarily and restore them at the end of a test. */ static final class DropShellPermissionsTemporarily implements AutoCloseable { DropShellPermissionsTemporarily() { diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java index 90d9452fb9c3..07dd59d2e2d8 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java @@ -32,11 +32,12 @@ import android.companion.virtual.VirtualDevice; import android.companion.virtual.flags.Flags; import android.os.Parcel; import android.platform.test.annotations.Presubmit; -import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.SetFlagsRule; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -51,6 +52,9 @@ public class VirtualDeviceTest { private static final String DEVICE_NAME = "VirtualDeviceName"; private static final String DISPLAY_NAME = "DisplayName"; + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Mock private IVirtualDevice mVirtualDevice; @@ -101,9 +105,10 @@ public class VirtualDeviceTest { assertThat(device.getDisplayName().toString()).isEqualTo(DISPLAY_NAME); } - @RequiresFlagsEnabled(Flags.FLAG_VDM_PUBLIC_APIS) @Test public void virtualDevice_getDisplayIds() throws Exception { + mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); + VirtualDevice virtualDevice = new VirtualDevice( mVirtualDevice, VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null); @@ -116,9 +121,10 @@ public class VirtualDeviceTest { assertThat(virtualDevice.getDisplayIds()).isEqualTo(displayIds); } - @RequiresFlagsEnabled(Flags.FLAG_VDM_PUBLIC_APIS) @Test public void virtualDevice_hasCustomSensorSupport() throws Exception { + mSetFlagsRule.enableFlags(Flags.FLAG_VDM_PUBLIC_APIS); + VirtualDevice virtualDevice = new VirtualDevice( mVirtualDevice, VIRTUAL_DEVICE_ID, /*persistentId=*/null, /*name=*/null); |