1 /*
2  * Copyright 2015 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.misc.cts;
18 
19 import static com.android.media.codec.flags.Flags.codecImportance;
20 
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.content.Intent;
24 import android.media.MediaFormat;
25 import android.os.Build;
26 import android.platform.test.annotations.AppModeFull;
27 import android.platform.test.annotations.RequiresDevice;
28 import android.platform.test.annotations.RequiresFlagsEnabled;
29 
30 import androidx.test.ext.junit.runners.AndroidJUnit4;
31 import androidx.test.rule.ActivityTestRule;
32 
33 import com.android.compatibility.common.util.ApiLevelUtil;
34 import com.android.compatibility.common.util.FrameworkSpecificTest;
35 import com.android.compatibility.common.util.NonMainlineTest;
36 import com.android.media.codec.flags.Flags;
37 
38 import org.junit.Rule;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 
42 @RequiresDevice
43 @AppModeFull(reason = "TODO: evaluate and port to instant")
44 @FrameworkSpecificTest
45 @NonMainlineTest
46 @RunWith(AndroidJUnit4.class)
47 public class ResourceManagerTest {
48 
49     public static final boolean FIRST_SDK_IS_AT_LEAST_U =
50             ApiLevelUtil.isFirstApiAfter(Build.VERSION_CODES.TIRAMISU);
51     public static final boolean SDK_IS_AT_LEAST_U =
52             ApiLevelUtil.isAfter(Build.VERSION_CODES.TIRAMISU);
53 
54     @Rule
55     public final ActivityTestRule<ResourceManagerStubActivity> mActivityRule =
56             new ActivityTestRule<>(ResourceManagerStubActivity.class, false, false);
57 
doTestReclaimResource(int type1, int type2, boolean highResolutionForActivity1, boolean highResolutionForActivity2)58     private void doTestReclaimResource(int type1, int type2,
59             boolean highResolutionForActivity1,
60             boolean highResolutionForActivity2) throws Exception {
61         boolean highResolution = highResolutionForActivity1 || highResolutionForActivity2;
62         // Run high resolution test case only when the devices shipped on U.
63         if (SDK_IS_AT_LEAST_U || !highResolution) {
64             ResourceManagerStubActivity activity = mActivityRule.launchActivity(new Intent());
65             activity.testReclaimResource(type1, type2, highResolutionForActivity1,
66                     highResolutionForActivity2);
67             activity.finish();
68         } else {
69             assumeTrue("The Device should be on at least SDK U", false);
70         }
71     }
72 
doTestVideoCodecReclaim(boolean highResolution, String mimeType)73     private void doTestVideoCodecReclaim(boolean highResolution, String mimeType)
74             throws Exception {
75         // Run high resolution test case only when the devices shipped on U.
76         if (SDK_IS_AT_LEAST_U || !highResolution) {
77             ResourceManagerStubActivity activity = mActivityRule.launchActivity(new Intent());
78             activity.testVideoCodecReclaim(highResolution, mimeType);
79             activity.finish();
80         } else {
81             assumeTrue("The Device should be on at least SDK U", false);
82         }
83     }
84 
doTestCodecImportanceReclaim(boolean highResolution, String mimeType, boolean changeImportanceAtConfig)85     private void doTestCodecImportanceReclaim(boolean highResolution, String mimeType,
86             boolean changeImportanceAtConfig) throws Exception {
87         assumeTrue("Codec Importance Feature is OFF", codecImportance());
88         // Run high resolution test case only when the devices shipped on U.
89         if (SDK_IS_AT_LEAST_U || !highResolution) {
90             ResourceManagerStubActivity activity = mActivityRule.launchActivity(new Intent());
91             // Let the test pick the codec name, width, height.
92             String codecName = "none";
93             int width = 0;
94             int height = 0;
95             activity.doTestCodecImportanceReclaimResource(
96                     codecName, mimeType, width, height, highResolution, changeImportanceAtConfig);
97             activity.finish();
98         } else {
99             assumeTrue("The Device should be on at least SDK U", false);
100         }
101     }
102 
103     // Following 6 test cases verify the below usecase:
104     // Activity1 creates allowable number of secure and/or unsecure decoders at
105     // lowest resolution supported in the background.
106     // Activity2 creates 1 secure or unsecure decoder at the lowest supported resolution.
107     @Test
testReclaimResourceNonsecureVsNonsecure()108     public void testReclaimResourceNonsecureVsNonsecure() throws Exception {
109         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
110                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, false);
111     }
112 
113     @Test
testReclaimResourceNonsecureVsSecure()114     public void testReclaimResourceNonsecureVsSecure() throws Exception {
115         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
116                 ResourceManagerTestActivityBase.TYPE_SECURE, false, false);
117     }
118 
119     @Test
testReclaimResourceSecureVsNonsecure()120     public void testReclaimResourceSecureVsNonsecure() throws Exception {
121         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
122                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, false);
123     }
124 
125     @Test
testReclaimResourceSecureVsSecure()126     public void testReclaimResourceSecureVsSecure() throws Exception {
127         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
128                 ResourceManagerTestActivityBase.TYPE_SECURE, false, false);
129     }
130 
131     @Test
testReclaimResourceMixVsNonsecure()132     public void testReclaimResourceMixVsNonsecure() throws Exception {
133         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
134                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, false);
135     }
136 
137     @Test
testReclaimResourceMixVsSecure()138     public void testReclaimResourceMixVsSecure() throws Exception {
139         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
140                 ResourceManagerTestActivityBase.TYPE_SECURE, false, false);
141     }
142 
143     // Following 6 test cases verify the below usecase:
144     // Activity1 creates allowable number of secure and/or unsecure decoders at
145     // highest resolution supported in the background.
146     // Activity2 creates 1 secure or unsecure decoder at the highest supported resolution.
147     @Test
testReclaimResourceNonsecureVsNonsecureHighResolution()148     public void testReclaimResourceNonsecureVsNonsecureHighResolution() throws Exception {
149         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
150                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, true);
151     }
152 
153     @Test
testReclaimResourceNonsecureVsSecureHighResolution()154     public void testReclaimResourceNonsecureVsSecureHighResolution() throws Exception {
155         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
156                 ResourceManagerTestActivityBase.TYPE_SECURE, true, true);
157     }
158 
159     @Test
testReclaimResourceSecureVsNonsecureHighResolution()160     public void testReclaimResourceSecureVsNonsecureHighResolution() throws Exception {
161         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
162                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, true);
163     }
164 
165     @Test
testReclaimResourceSecureVsSecureHighResolution()166     public void testReclaimResourceSecureVsSecureHighResolution() throws Exception {
167         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
168                 ResourceManagerTestActivityBase.TYPE_SECURE, true, true);
169     }
170 
171     @Test
testReclaimResourceMixVsNonsecureHighResolution()172     public void testReclaimResourceMixVsNonsecureHighResolution() throws Exception {
173         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
174                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, true);
175     }
176 
177     @Test
testReclaimResourceMixVsSecureHighResolution()178     public void testReclaimResourceMixVsSecureHighResolution() throws Exception {
179         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
180                 ResourceManagerTestActivityBase.TYPE_SECURE, true, true);
181     }
182 
183     // Following 6 test cases verify the below usecase:
184     // Activity1 creates allowable number of secure and/or unsecure decoders at
185     // lowest resolution supported in the background.
186     // Activity2 creates 1 secure or unsecure decoder at the highest supported resolution.
187     @Test
testReclaimResourceNonsecureVsNonsecureLowHighResolution()188     public void testReclaimResourceNonsecureVsNonsecureLowHighResolution() throws Exception {
189         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
190                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, true);
191     }
192 
193     @Test
testReclaimResourceNonsecureVsSecureLowHighResolution()194     public void testReclaimResourceNonsecureVsSecureLowHighResolution() throws Exception {
195         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
196                 ResourceManagerTestActivityBase.TYPE_SECURE, false, true);
197     }
198 
199     @Test
testReclaimResourceSecureVsNonsecureLowHighResolution()200     public void testReclaimResourceSecureVsNonsecureLowHighResolution() throws Exception {
201         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
202                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, true);
203     }
204 
205     @Test
testReclaimResourceSecureVsSecureLowHighResolution()206     public void testReclaimResourceSecureVsSecureLowHighResolution() throws Exception {
207         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
208                 ResourceManagerTestActivityBase.TYPE_SECURE, false, true);
209     }
210 
211     @Test
testReclaimResourceMixVsNonsecureLowHighResolution()212     public void testReclaimResourceMixVsNonsecureLowHighResolution() throws Exception {
213         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
214                 ResourceManagerTestActivityBase.TYPE_NONSECURE, false, true);
215     }
216 
217     @Test
testReclaimResourceMixVsSecureLowHighResolution()218     public void testReclaimResourceMixVsSecureLowHighResolution() throws Exception {
219         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
220                 ResourceManagerTestActivityBase.TYPE_SECURE, false, true);
221     }
222 
223     // Following 6 test cases verify the below usecase:
224     // Activity1 creates allowable number of secure and/or unsecure decoders at
225     // highest resolution supported in the background.
226     // Activity2 creates 1 secure or unsecure decoder at the lowest supported resolution.
227     @Test
testReclaimResourceNonsecureVsNonsecureHighLowResolution()228     public void testReclaimResourceNonsecureVsNonsecureHighLowResolution() throws Exception {
229         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
230                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, false);
231     }
232 
233     @Test
testReclaimResourceNonsecureVsSecureHighLowResolution()234     public void testReclaimResourceNonsecureVsSecureHighLowResolution() throws Exception {
235         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
236                 ResourceManagerTestActivityBase.TYPE_SECURE, true, false);
237     }
238 
239     @Test
testReclaimResourceSecureVsNonsecureHighLowResolution()240     public void testReclaimResourceSecureVsNonsecureHighLowResolution() throws Exception {
241         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
242                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, false);
243     }
244 
245     @Test
testReclaimResourceSecureVsSecureHighLowResolution()246     public void testReclaimResourceSecureVsSecureHighLowResolution() throws Exception {
247         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
248                 ResourceManagerTestActivityBase.TYPE_SECURE, true, false);
249     }
250 
251     @Test
testReclaimResourceMixVsNonsecureHighLowResolution()252     public void testReclaimResourceMixVsNonsecureHighLowResolution() throws Exception {
253         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
254                 ResourceManagerTestActivityBase.TYPE_NONSECURE, true, false);
255     }
256 
257     @Test
testReclaimResourceMixVsSecureHighLowResolution()258     public void testReclaimResourceMixVsSecureHighLowResolution() throws Exception {
259         doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
260                 ResourceManagerTestActivityBase.TYPE_SECURE, true, false);
261     }
262 
263     // Activity1 creates allowable number of AVC decoders and encoders at
264     // lowest resolution supported in the background.
265     // Activity2 starts MediaRecorder using camera and AVC encoder at
266     // the lowest supported resolution.
267     @Test
testAVCVideoCodecReclaimLowResolution()268     public void testAVCVideoCodecReclaimLowResolution() throws Exception {
269         doTestVideoCodecReclaim(false, MediaFormat.MIMETYPE_VIDEO_AVC);
270     }
271 
272     // Activity1 creates allowable number of AVC decoders and encoders at
273     // highest resolution supported in the background.
274     // Activity2 starts MediaRecorder using camera and AVC encoder at
275     // the highest supported resolution.
276     @Test
testAVCVideoCodecReclaimHighResolution()277     public void testAVCVideoCodecReclaimHighResolution() throws Exception {
278         doTestVideoCodecReclaim(true, MediaFormat.MIMETYPE_VIDEO_AVC);
279     }
280 
281     // Activity1 creates allowable number of HEVC decoders and encoders at
282     // lowest resolution supported in the background.
283     // Activity2 starts MediaRecorder using camera and HEVC encoder at
284     // the lowest supported resolution.
285     @Test
testHEVCVideoCodecReclaimLowResolution()286     public void testHEVCVideoCodecReclaimLowResolution() throws Exception {
287         doTestVideoCodecReclaim(false, MediaFormat.MIMETYPE_VIDEO_HEVC);
288     }
289 
290     // Activity1 creates allowable number of HEVC decoders and encoders at
291     // highest resolution supported in the background.
292     // Activity2 starts MediaRecorder using camera and HEVC encoder at
293     // the highest supported resolution.
294     @Test
testHEVCVideoCodecReclaimHighResolution()295     public void testHEVCVideoCodecReclaimHighResolution() throws Exception {
296         doTestVideoCodecReclaim(true, MediaFormat.MIMETYPE_VIDEO_HEVC);
297     }
298 
299     // Activity creates allowable number of AVC decoders at
300     // lowest resolution supported.
301     // The first codec is configured at lower importance so that the test verifies
302     // that the first codec is reclaimed while starting a more important codec
303     // at the later stage (when all codec resources run out).
304     // Once the first (lower importance) is reclaimed, the test attempts to configure
305     // another lower importance codec, which it expects to fail.
306     @Test
307     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testAVCVideoCodecImportanceReclaimLowResolution()308     public void testAVCVideoCodecImportanceReclaimLowResolution() throws Exception {
309         doTestCodecImportanceReclaim(false, /*low resolution*/
310                                      MediaFormat.MIMETYPE_VIDEO_AVC, /*use avc codec*/
311                                      true /*change importance during codec configuration*/);
312     }
313 
314     // Activity creates allowable number of AVC decoders at
315     // highest resolution supported.
316     // The first codec is configured at lower importance so that the test verifies
317     // that the first codec is reclaimed while starting a more important codec
318     // at the later stage (when all codec resources run out).
319     // Once the first (lower importance) is reclaimed, the test attempts to configure
320     // another lower importance codec, which it expects to fail.
321     @Test
322     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testAVCVideoCodecImportanceReclaimHighResolution()323     public void testAVCVideoCodecImportanceReclaimHighResolution() throws Exception {
324         doTestCodecImportanceReclaim(true, /*high resolution */
325                                      MediaFormat.MIMETYPE_VIDEO_AVC, /*use avc codec*/
326                                      true /*change importance during codec configuration*/);
327     }
328 
329     // Activity creates allowable number of HEVC decoders at
330     // lowest resolution supported.
331     // The first codec is configured at lower importance so that the test verifies
332     // that the first codec is reclaimed while starting a more important codec
333     // at the later stage (when all codec resources run out).
334     // Once the first (lower importance) is reclaimed, the test attempts to configure
335     // another lower importance codec, which it expects to fail.
336     @Test
337     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testHEVCVideoCodecImportanceReclaimLowResolution()338     public void testHEVCVideoCodecImportanceReclaimLowResolution() throws Exception {
339         doTestCodecImportanceReclaim(false, /*low resolution*/
340                                      MediaFormat.MIMETYPE_VIDEO_HEVC, /*use hevc codec*/
341                                      true /*change importance during codec configuration*/);
342     }
343 
344     // Activity creates allowable number of HEVC decoders at
345     // highest resolution supported.
346     // The first codec is configured at lower importance so that the test verifies
347     // that the first codec is reclaimed while starting a more important codec
348     // at the later stage (when all codec resources run out).
349     // Once the first (lower importance) is reclaimed, the test attempts to configure
350     // another lower importance codec, which it expects to fail.
351     @Test
352     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testHEVCVideoCodecImportanceReclaimHighResolution()353     public void testHEVCVideoCodecImportanceReclaimHighResolution() throws Exception {
354         doTestCodecImportanceReclaim(true, /*high resolution */
355                                      MediaFormat.MIMETYPE_VIDEO_HEVC, /*use hevc codec*/
356                                      true /*change importance during codec configuration*/);
357     }
358 
359     // Activity creates allowable number of AVC decoders at
360     // lowest resolution supported.
361     // All the codecs are configured with the default importance (highest)
362     // But, when we get a INSUFFICIENT_RESOURCE, we lower the importance of the
363     // first codec so that we can create/start one more codec by reclaiming the
364     // first codec (that has lower importance now)
365     // Once the first (lower importance) is reclaimed, the test attempts to configure
366     // another lower importance codec, which it expects to fail.
367     @Test
368     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testAVCVideoCodecImportanceReclaimWithSetParamLowResolution()369     public void testAVCVideoCodecImportanceReclaimWithSetParamLowResolution() throws Exception {
370         doTestCodecImportanceReclaim(false, /*low resolution*/
371                                      MediaFormat.MIMETYPE_VIDEO_AVC, /*use avc codec*/
372                                      false /*change importance after codec config with setParam*/);
373     }
374 
375     // Activity creates allowable number of AVC decoders at
376     // highest resolution supported.
377     // All the codecs are configured with the default importance (highest)
378     // But, when we get a INSUFFICIENT_RESOURCE, we lower the importance of the
379     // first codec so that we can create/start one more codec by reclaiming the
380     // first codec (that has lower importance now)
381     // Once the first (lower importance) is reclaimed, the test attempts to configure
382     // another lower importance codec, which it expects to fail.
383     @Test
384     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testAVCVideoCodecImportanceReclaimWithSetParamHighResolution()385     public void testAVCVideoCodecImportanceReclaimWithSetParamHighResolution() throws Exception {
386         doTestCodecImportanceReclaim(true, /*high resolution*/
387                                      MediaFormat.MIMETYPE_VIDEO_AVC, /*use avc codec*/
388                                      false /*change importance after codec config with setParam*/);
389     }
390 
391     // Activity creates allowable number of HEVC decoders at
392     // lowest resolution supported.
393     // All the codecs are configured with the default importance (highest)
394     // But, when we get a INSUFFICIENT_RESOURCE, we lower the importance of the
395     // first codec so that we can create/start one more codec by reclaiming the
396     // first codec (that has lower importance now)
397     // Once the first (lower importance) is reclaimed, the test attempts to configure
398     // another lower importance codec, which it expects to fail.
399     @Test
400     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testHEVCVideoCodecImportanceReclaimWithSetParamLowResolution()401     public void testHEVCVideoCodecImportanceReclaimWithSetParamLowResolution() throws Exception {
402         doTestCodecImportanceReclaim(false, /*low resolution*/
403                                      MediaFormat.MIMETYPE_VIDEO_HEVC, /*use hevc codec*/
404                                      false /*change importance after codec config with setParam*/);
405     }
406 
407     // Activity creates allowable number of HEVC decoders at
408     // highest resolution supported.
409     // All the codecs are configured with the default importance (highest)
410     // But, when we get a INSUFFICIENT_RESOURCE, we lower the importance of the
411     // first codec so that we can create/start one more codec by reclaiming the
412     // first codec (that has lower importance now)
413     // Once the first (lower importance) is reclaimed, the test attempts to configure
414     // another lower importance codec, which it expects to fail.
415     @Test
416     @RequiresFlagsEnabled(Flags.FLAG_CODEC_IMPORTANCE)
testHEVCVideoCodecImportanceReclaimWithSetParamHighResolution()417     public void testHEVCVideoCodecImportanceReclaimWithSetParamHighResolution() throws Exception {
418         doTestCodecImportanceReclaim(true, /*high resolution */
419                                      MediaFormat.MIMETYPE_VIDEO_HEVC, /*use hevc codec*/
420                                      false /*change importance after codec config with setParam*/);
421     }
422 }
423