1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package android.server.wm; 18 19 import static android.server.wm.app.Components.TEST_ACTIVITY; 20 import static android.view.Display.FLAG_PRIVATE; 21 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assume.assumeFalse; 25 import static org.junit.Assume.assumeTrue; 26 27 import android.app.ActivityManager; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.platform.test.annotations.Presubmit; 31 import android.server.wm.WindowManagerState.DisplayContent; 32 import android.util.Log; 33 34 import com.android.compatibility.common.util.SystemUtil; 35 36 import java.util.ArrayList; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 41 /** 42 * Build/Install/Run: 43 * atest CtsWindowManagerDeviceTestCases:MultiDisplayPrivateDisplayTests 44 * 45 * Tests if be allowed to launch/access an activity on private display 46 * in multi-display environment. 47 */ 48 @Presubmit 49 @android.server.wm.annotation.Group3 50 public class MultiDisplayPrivateDisplayTests extends MultiDisplayTestBase { 51 private static final String TAG = "MultiDisplayPrivateDisplayTests"; 52 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 53 private static final String INTERNAL_SYSTEM_WINDOW = 54 "android.permission.INTERNAL_SYSTEM_WINDOW"; 55 private ArrayList<Integer> mPrivateDisplayIds = new ArrayList<>(); 56 57 @Before 58 @Override setUp()59 public void setUp() throws Exception { 60 super.setUp(); 61 assumeTrue(supportsMultiDisplay()); 62 findPrivateDisplays(); 63 assumeFalse("Skipping test: no physical private display found.", 64 mPrivateDisplayIds.isEmpty()); 65 } 66 67 /** Saves physical private displays in mPrivateDisplayIds */ findPrivateDisplays()68 private void findPrivateDisplays() { 69 mPrivateDisplayIds.clear(); 70 mWmState.computeState(); 71 72 for (DisplayContent displayContent: getDisplaysStates()) { 73 int displayId = displayContent.mId; 74 DisplayContent display = mWmState.getDisplay(displayId); 75 if ((display.getFlags() & FLAG_PRIVATE) != 0) { 76 mPrivateDisplayIds.add(displayId); 77 } 78 } 79 } 80 81 /** 82 * Tests launching an activity on a private display without special permission must not be 83 * allowed. 84 */ 85 @Test testCantLaunchOnPrivateDisplay()86 public void testCantLaunchOnPrivateDisplay() throws Exception { 87 // try on each private display 88 for (int displayId: mPrivateDisplayIds) { 89 separateTestJournal(); 90 91 getLaunchActivityBuilder() 92 .setDisplayId(displayId) 93 .setTargetActivity(TEST_ACTIVITY) 94 .execute(); 95 96 assertSecurityExceptionFromActivityLauncher(); 97 98 mWmState.computeState(TEST_ACTIVITY); 99 assertFalse("Activity must not be launched on a private display", 100 mWmState.containsActivity(TEST_ACTIVITY)); 101 } 102 } 103 104 /** 105 * Tests 106 * {@link android.app.ActivityManager#isActivityStartAllowedOnDisplay(Context, int, Intent)} 107 * call to start an activity on private display is not allowed without special permission 108 */ 109 @Test testCantAccessPrivateDisplay()110 public void testCantAccessPrivateDisplay() throws Exception { 111 final ActivityManager activityManager = 112 (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE); 113 final Intent intent = new Intent(Intent.ACTION_VIEW).setComponent(TEST_ACTIVITY); 114 115 for (int displayId: mPrivateDisplayIds) { 116 assertFalse(activityManager.isActivityStartAllowedOnDisplay(mTargetContext, 117 displayId, intent)); 118 } 119 } 120 121 /** 122 * Tests 123 * {@link android.app.ActivityManager#isActivityStartAllowedOnDisplay(Context, int, Intent)} 124 * for a private display with INTERNAL_SYSTEM_WINDOW permission. 125 */ 126 @Test testCanAccessPrivateDisplayWithInternalPermission()127 public void testCanAccessPrivateDisplayWithInternalPermission() throws Exception { 128 final ActivityManager activityManager = 129 (ActivityManager) mTargetContext.getSystemService(Context.ACTIVITY_SERVICE); 130 final Intent intent = new Intent(Intent.ACTION_VIEW) 131 .setComponent(TEST_ACTIVITY); 132 133 for (int displayId: mPrivateDisplayIds) { 134 SystemUtil.runWithShellPermissionIdentity(() -> 135 assertTrue(activityManager.isActivityStartAllowedOnDisplay(mTargetContext, 136 displayId, intent)), INTERNAL_SYSTEM_WINDOW); 137 } 138 } 139 } 140