• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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