/* * Copyright (C) 2019 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 android.server.wm; import static android.server.wm.app.Components.TEST_ACTIVITY; import static android.view.Display.FLAG_PRIVATE; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.platform.test.annotations.Presubmit; import android.server.wm.WindowManagerState.DisplayContent; import android.util.Log; import com.android.compatibility.common.util.SystemUtil; import java.util.ArrayList; import org.junit.Before; import org.junit.Test; /** * Build/Install/Run: * atest CtsWindowManagerDeviceTestCases:MultiDisplayPrivateDisplayTests * * Tests if be allowed to launch/access an activity on private display * in multi-display environment. */ @Presubmit @android.server.wm.annotation.Group3 public class MultiDisplayPrivateDisplayTests extends MultiDisplayTestBase { private static final String TAG = "MultiDisplayPrivateDisplayTests"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final String INTERNAL_SYSTEM_WINDOW = "android.permission.INTERNAL_SYSTEM_WINDOW"; private ArrayList mPrivateDisplayIds = new ArrayList<>(); @Before @Override public void setUp() throws Exception { super.setUp(); assumeTrue(supportsMultiDisplay()); findPrivateDisplays(); assumeFalse("Skipping test: no physical private display found.", mPrivateDisplayIds.isEmpty()); } /** Saves physical private displays in mPrivateDisplayIds */ private void findPrivateDisplays() { mPrivateDisplayIds.clear(); mWmState.computeState(); for (DisplayContent displayContent: getDisplaysStates()) { int displayId = displayContent.mId; DisplayContent display = mWmState.getDisplay(displayId); if ((display.getFlags() & FLAG_PRIVATE) != 0) { mPrivateDisplayIds.add(displayId); } } } /** * Tests launching an activity on a private display without special permission must not be * allowed. */ @Test public void testCantLaunchOnPrivateDisplay() throws Exception { // try on each private display for (int displayId: mPrivateDisplayIds) { separateTestJournal(); getLaunchActivityBuilder() .setDisplayId(displayId) .setTargetActivity(TEST_ACTIVITY) .execute(); assertSecurityExceptionFromActivityLauncher(); mWmState.computeState(TEST_ACTIVITY); assertFalse("Activity must not be launched on a private display", mWmState.containsActivity(TEST_ACTIVITY)); } } /** * Tests * {@link android.app.ActivityManager#isActivityStartAllowedOnDisplay(Context, int, Intent)} * call to start an activity on private display is not allowed without special permission */ @Test public void testCantAccessPrivateDisplay() throws Exception { final ActivityManager activityManager = (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE); final Intent intent = new Intent(Intent.ACTION_VIEW).setComponent(TEST_ACTIVITY); for (int displayId: mPrivateDisplayIds) { assertFalse(activityManager.isActivityStartAllowedOnDisplay(mTargetContext, displayId, intent)); } } /** * Tests * {@link android.app.ActivityManager#isActivityStartAllowedOnDisplay(Context, int, Intent)} * for a private display with INTERNAL_SYSTEM_WINDOW permission. */ @Test public void testCanAccessPrivateDisplayWithInternalPermission() throws Exception { final ActivityManager activityManager = (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE); final Intent intent = new Intent(Intent.ACTION_VIEW) .setComponent(TEST_ACTIVITY); for (int displayId: mPrivateDisplayIds) { SystemUtil.runWithShellPermissionIdentity(() -> assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext, displayId, intent)), INTERNAL_SYSTEM_WINDOW); } } }