• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.media.projection;
18 
19 import static android.Manifest.permission.MANAGE_MEDIA_PROJECTION;
20 import static android.media.projection.MediaProjection.MEDIA_PROJECTION_REQUIRES_CALLBACK;
21 import static android.view.Display.DEFAULT_DISPLAY;
22 
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
24 
25 import static com.google.common.truth.Truth.assertThat;
26 
27 import static libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
28 import static libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
29 
30 import static org.junit.Assert.assertThrows;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.ArgumentMatchers.nullable;
33 import static org.mockito.Mockito.doReturn;
34 
35 import android.annotation.Nullable;
36 import android.app.ActivityOptions.LaunchCookie;
37 import android.compat.testing.PlatformCompatChangeRule;
38 import android.hardware.display.DisplayManager;
39 import android.hardware.display.VirtualDisplay;
40 import android.hardware.display.VirtualDisplayConfig;
41 import android.os.Handler;
42 import android.os.Looper;
43 import android.os.RemoteException;
44 import android.os.test.FakePermissionEnforcer;
45 import android.platform.test.annotations.Presubmit;
46 import android.testing.TestableContext;
47 import android.view.Display;
48 
49 import androidx.test.ext.junit.runners.AndroidJUnit4;
50 import androidx.test.filters.SmallTest;
51 import androidx.test.platform.app.InstrumentationRegistry;
52 
53 import org.junit.After;
54 import org.junit.Before;
55 import org.junit.Rule;
56 import org.junit.Test;
57 import org.junit.rules.TestRule;
58 import org.junit.runner.RunWith;
59 import org.mockito.Mock;
60 import org.mockito.MockitoSession;
61 import org.mockito.quality.Strictness;
62 
63 
64 /**
65  * Tests for the {@link MediaProjection} class.
66  *
67  * Build/Install/Run:
68  * atest MediaProjectionTests:MediaProjectionTest
69  */
70 @SmallTest
71 @Presubmit
72 @RunWith(AndroidJUnit4.class)
73 public class MediaProjectionTest {
74     // Values for creating a VirtualDisplay.
75     private static final String VIRTUAL_DISPLAY_NAME = "MEDIA_PROJECTION_VIRTUAL_DISPLAY";
76     private static final int VIRTUAL_DISPLAY_WIDTH = 500;
77     private static final int VIRTUAL_DISPLAY_HEIGHT = 600;
78     private static final int VIRTUAL_DISPLAY_DENSITY = 100;
79     private static final int VIRTUAL_DISPLAY_FLAGS = 0;
80 
81     private final Handler mHandler = new Handler(Looper.getMainLooper());
82     // Fake the connection to the system server.
83     private FakeIMediaProjection mFakeIMediaProjection;
84     // Callback registered by an app.
85     private MediaProjection mMediaProjection;
86 
87     @Mock
88     private MediaProjection.Callback mMediaProjectionCallback;
89     @Mock
90     private Display mDisplay;
91     @Mock
92     private VirtualDisplay.Callback mVirtualDisplayCallback;
93     @Mock
94     private VirtualDisplay mVirtualDisplay;
95     @Mock
96     private DisplayManager mDisplayManager;
97 
98     @Rule
99     public TestRule compatChangeRule = new PlatformCompatChangeRule();
100 
101     @Rule
102     public final TestableContext mTestableContext = new TestableContext(
103             InstrumentationRegistry.getInstrumentation().getTargetContext());
104 
105     private MockitoSession mMockingSession;
106 
107     @Before
setup()108     public void setup() throws Exception {
109         mMockingSession =
110                 mockitoSession()
111                         .initMocks(this)
112                         .strictness(Strictness.LENIENT)
113                         .startMocking();
114 
115         FakePermissionEnforcer permissionEnforcer = new FakePermissionEnforcer();
116         permissionEnforcer.grant(MANAGE_MEDIA_PROJECTION);
117         // Support the MediaProjection instance.
118         mFakeIMediaProjection = new FakeIMediaProjection(permissionEnforcer);
119         mFakeIMediaProjection.setLaunchCookie(new LaunchCookie());
120         mMediaProjection = new MediaProjection(mTestableContext, mFakeIMediaProjection,
121                 mDisplayManager);
122 
123         // Support creation of the VirtualDisplay.
124         mTestableContext.addMockSystemService(DisplayManager.class, mDisplayManager);
125         doReturn(mDisplay).when(mVirtualDisplay).getDisplay();
126         doReturn(DEFAULT_DISPLAY + 7).when(mDisplay).getDisplayId();
127         doReturn(mVirtualDisplay).when(mDisplayManager).createVirtualDisplay(
128                 any(MediaProjection.class), any(VirtualDisplayConfig.class),
129                 nullable(VirtualDisplay.Callback.class), nullable(Handler.class));
130     }
131 
132     @After
tearDown()133     public void tearDown() {
134         mMockingSession.finishMocking();
135     }
136 
137     @Test
testConstruction()138     public void testConstruction() throws RemoteException {
139         assertThat(mMediaProjection).isNotNull();
140         assertThat(mFakeIMediaProjection.mIsStarted).isTrue();
141     }
142 
143     @Test
testRegisterCallback_null()144     public void testRegisterCallback_null() {
145         assertThrows(NullPointerException.class,
146                 () -> mMediaProjection.registerCallback(null, mHandler));
147     }
148 
149     @Test
testUnregisterCallback_null()150     public void testUnregisterCallback_null() {
151         mMediaProjection.registerCallback(mMediaProjectionCallback, mHandler);
152         assertThrows(NullPointerException.class,
153                 () -> mMediaProjection.unregisterCallback(null));
154     }
155 
156     @Test
157     @DisableCompatChanges({MEDIA_PROJECTION_REQUIRES_CALLBACK})
createVirtualDisplay_noCallbackRequired_missingMediaProjectionCallback()158     public void createVirtualDisplay_noCallbackRequired_missingMediaProjectionCallback() {
159         assertThat(createVirtualDisplay(null)).isNotNull();
160         assertThat(createVirtualDisplay(mVirtualDisplayCallback)).isNotNull();
161     }
162 
163     @Test
164     @DisableCompatChanges({MEDIA_PROJECTION_REQUIRES_CALLBACK})
createVirtualDisplay_noCallbackRequired_givenMediaProjectionCallback()165     public void createVirtualDisplay_noCallbackRequired_givenMediaProjectionCallback() {
166         mMediaProjection.registerCallback(mMediaProjectionCallback, mHandler);
167         assertThat(createVirtualDisplay(null)).isNotNull();
168         assertThat(createVirtualDisplay(mVirtualDisplayCallback)).isNotNull();
169     }
170 
171     @Test
172     @EnableCompatChanges({MEDIA_PROJECTION_REQUIRES_CALLBACK})
createVirtualDisplay_callbackRequired_missingMediaProjectionCallback()173     public void createVirtualDisplay_callbackRequired_missingMediaProjectionCallback() {
174         assertThrows(IllegalStateException.class,
175                 () -> createVirtualDisplay(mVirtualDisplayCallback));
176     }
177 
178     @Test
179     @EnableCompatChanges({MEDIA_PROJECTION_REQUIRES_CALLBACK})
createVirtualDisplay_callbackRequired_givenMediaProjectionCallback()180     public void createVirtualDisplay_callbackRequired_givenMediaProjectionCallback() {
181         mMediaProjection.registerCallback(mMediaProjectionCallback, mHandler);
182         assertThat(createVirtualDisplay(null)).isNotNull();
183         assertThat(createVirtualDisplay(mVirtualDisplayCallback)).isNotNull();
184     }
185 
createVirtualDisplay(@ullable VirtualDisplay.Callback callback)186     private VirtualDisplay createVirtualDisplay(@Nullable VirtualDisplay.Callback callback) {
187         // No recording will take place with a null surface.
188         return mMediaProjection.createVirtualDisplay(
189                 VIRTUAL_DISPLAY_NAME, VIRTUAL_DISPLAY_WIDTH,
190                 VIRTUAL_DISPLAY_HEIGHT, VIRTUAL_DISPLAY_DENSITY,
191                 VIRTUAL_DISPLAY_FLAGS, /* surface = */ null,
192                 callback, /* handler= */ mHandler);
193     }
194 }
195