• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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.hardware.multiprocess.camera.cts;
18 
19 import static junit.framework.Assert.*;
20 
21 import static org.mockito.Mockito.*;
22 
23 import android.app.Activity;
24 import android.app.ActivityManager;
25 import android.app.Instrumentation;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.hardware.camera2.CameraCharacteristics;
29 import android.hardware.camera2.cts.Camera2ParameterizedTestCase;
30 import android.hardware.camera2.cts.helpers.StaticMetadata;
31 import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
32 import android.hardware.camera2.params.SharedSessionConfiguration;
33 import android.hardware.camera2.params.SharedSessionConfiguration.SharedOutputConfiguration;
34 import android.os.Bundle;
35 import android.os.Message;
36 import android.os.Messenger;
37 import android.os.RemoteException;
38 import android.os.ResultReceiver;
39 import android.os.SystemClock;
40 import android.platform.test.annotations.RequiresFlagsEnabled;
41 import android.platform.test.flag.junit.CheckFlagsRule;
42 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
43 import android.util.Log;
44 
45 import androidx.test.InstrumentationRegistry;
46 import androidx.test.uiautomator.UiDevice;
47 
48 import com.android.internal.camera.flags.Flags;
49 
50 import org.junit.Rule;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 import org.junit.runners.Parameterized;
54 
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.HashMap;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.concurrent.TimeoutException;
61 
62 /** Tests for shared camera access where multiple clients can access a camera. */
63 @RunWith(Parameterized.class)
64 public final class SharedCameraTest extends Camera2ParameterizedTestCase {
65     private static final String TAG = "SharedCameraTest";
66     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
67     private static final int SETUP_TIMEOUT = 5000; // Remote camera setup timeout (ms).
68     private static final int WAIT_TIME = 3000; // Time to wait for process to launch (ms).
69     private static final int EVICTION_TIMEOUT = 1000; // Remote camera eviction timeout (ms).
70     private static final long PREVIEW_TIME_MS = 2000;
71     private ErrorLoggingService.ErrorServiceConnection mErrorServiceConnection;
72     private int mProcessPid = -1;
73     private int mProcessPid2 = -1;
74     private Context mContext;
75     private ActivityManager mActivityManager;
76     private String mCameraId;
77     private Messenger mRemoteMessenger;
78     private Messenger mRemoteMessenger2;
79     private CameraResultReceiver mResultReceiver;
80     private CameraResultReceiver mResultReceiver2;
81     private UiDevice mUiDevice;
82     protected HashMap<String, StaticMetadata> mAllStaticInfo;
83 
84     @Rule
85     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
86 
87     /** Load validation jni on initialization. */
88     static {
89         System.loadLibrary("ctscamera2_jni");
90     }
91 
92     private class CameraResultReceiver extends ResultReceiver {
93         boolean mIsFirstClient = false;
94 
CameraResultReceiver(boolean isFirstClient)95         protected CameraResultReceiver(boolean isFirstClient) {
96             super(null);
97             mIsFirstClient = isFirstClient;
98         }
99 
100         @Override
onReceiveResult(int resultCode, Bundle resultData)101         protected void onReceiveResult(int resultCode, Bundle resultData) {
102             if (resultCode == Activity.RESULT_OK) {
103                 if (mIsFirstClient) {
104                     mRemoteMessenger =
105                             (Messenger)
106                                     resultData.getParcelable(TestConstants.EXTRA_REMOTE_MESSENGER);
107                 } else {
108                     mRemoteMessenger2 =
109                             (Messenger)
110                                     resultData.getParcelable(TestConstants.EXTRA_REMOTE_MESSENGER);
111                 }
112             }
113         }
114     }
115 
116     @Override
setUp()117     public void setUp() throws Exception {
118         super.setUp();
119         mContext = InstrumentationRegistry.getTargetContext();
120         /**
121          * Workaround for mockito and JB-MR2 incompatibility
122          *
123          * <p>Avoid java.lang.IllegalArgumentException: dexcache == null
124          * https://code.google.com/p/dexmaker/issues/detail?id=2
125          */
126         System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
127         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
128         mUiDevice = UiDevice.getInstance(instrumentation);
129         mActivityManager = mContext.getSystemService(ActivityManager.class);
130         mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(mContext);
131         mErrorServiceConnection.start();
132 
133         mResultReceiver = new CameraResultReceiver(/* isFirstClient */ true);
134 
135         mProcessPid =
136                 startRemoteProcess(
137                         SharedCameraActivity.class, "SharedCameraActivityProcess", mResultReceiver);
138 
139         mAllStaticInfo = new HashMap<String, StaticMetadata>();
140         List<String> hiddenPhysicalIds = new ArrayList<>();
141         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
142         for (String cameraId : cameraIdsUnderTest) {
143             CameraCharacteristics props = mCameraManager.getCameraCharacteristics(cameraId);
144             StaticMetadata staticMetadata =
145                     new StaticMetadata(props, CheckLevel.ASSERT, /*collector*/ null);
146             mAllStaticInfo.put(cameraId, staticMetadata);
147 
148             for (String physicalId : props.getPhysicalCameraIds()) {
149                 if (!Arrays.asList(cameraIdsUnderTest).contains(physicalId)
150                         && !hiddenPhysicalIds.contains(physicalId)) {
151                     hiddenPhysicalIds.add(physicalId);
152                     props = mCameraManager.getCameraCharacteristics(physicalId);
153                     staticMetadata =
154                             new StaticMetadata(
155                                     mCameraManager.getCameraCharacteristics(physicalId),
156                                     CheckLevel.ASSERT, /*collector*/
157                                     null);
158                     mAllStaticInfo.put(physicalId, staticMetadata);
159                 }
160             }
161         }
162     }
163 
164     @Override
tearDown()165     public void tearDown() throws Exception {
166         if (mProcessPid2 != -1) {
167             android.os.Process.killProcess(mProcessPid2);
168             mProcessPid2 = -1;
169             Thread.sleep(WAIT_TIME);
170         }
171         if (mProcessPid != -1) {
172             android.os.Process.killProcess(mProcessPid);
173             mProcessPid = -1;
174             Thread.sleep(WAIT_TIME);
175         }
176         if (mErrorServiceConnection != null) {
177             mErrorServiceConnection.stop();
178             mErrorServiceConnection = null;
179         }
180         mContext = null;
181         mActivityManager = null;
182         super.tearDown();
183     }
184 
185     @Test
186     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testOpenMixedMode()187     public void testOpenMixedMode() throws Exception {
188         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
189         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
190         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
191             mCameraId = cameraIdsUnderTest[i];
192             if (!mAllStaticInfo.get(mCameraId).sharedSessionConfigurationPresent()) {
193                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
194                 continue;
195             }
196             long nativeSharedTest =
197                     openSharedCameraNativeClient(mCameraId, /*isPrimaryClient*/true);
198             openCameraJavaClient(mCameraId);
199             assertCameraEvictedNativeClient(nativeSharedTest);
200             closeNativeClient(nativeSharedTest);
201             closeCameraJavaClient();
202             openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/true);
203             nativeSharedTest = openCameraNativeClient(mCameraId, /*expectFail*/true);
204             closeCameraJavaClient();
205             closeNativeClient(nativeSharedTest, /*expectCameraAlreadyClosed*/true);
206         }
207     }
208 
209     @Test
210     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSharedSessionCreationInvalidConfig()211     public void testSharedSessionCreationInvalidConfig() throws Exception {
212         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
213         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
214         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
215             mCameraId = cameraIdsUnderTest[i];
216             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
217                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
218                 continue;
219             }
220             SharedSessionConfiguration sharedSessionConfig =
221                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
222             assertNotNull("Shared session configuration is null", sharedSessionConfig);
223             int surfaceViewIdx = getSurfaceViewStreamIdx(sharedSessionConfig);
224             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
225             if ((surfaceViewIdx == -1) && (imageReaderIdx == -1)) {
226                 Log.i(
227                         TAG,
228                         "Camera "
229                                 + mCameraId
230                                 + " does not have any streams supporting either surface"
231                                 + " view or ImageReader for shared session, skipping");
232                 continue;
233             }
234             try {
235                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/ true);
236                 performCreateSharedSessionInvalidConfigsJavaClient();
237             } finally {
238                 closeCameraJavaClient();
239             }
240         }
241     }
242 
243     @Test
244     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSharedSessionUnsupportedOperations()245     public void testSharedSessionUnsupportedOperations() throws Exception {
246         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
247         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
248         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
249             mCameraId = cameraIdsUnderTest[i];
250             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
251                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
252                 continue;
253             }
254             SharedSessionConfiguration sharedSessionConfig =
255                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
256             assertNotNull("Shared session configuration is null", sharedSessionConfig);
257             int surfaceViewIdx = getSurfaceViewStreamIdx(sharedSessionConfig);
258             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
259             if ((surfaceViewIdx == -1) && (imageReaderIdx == -1)) {
260                 Log.i(
261                         TAG,
262                         "Camera "
263                                 + mCameraId
264                                 + " does not have any stream supporting either surface view or"
265                                 + " image reader, skipping");
266                 continue;
267             }
268             long nativeSharedTest = 0;
269             try {
270                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/ true);
271                 performCreateSharedSessionUnsupportedOperationsJavaClient();
272                 ArrayList<Integer> sharedStreamArray = new ArrayList<>();
273                 if (imageReaderIdx != -1) {
274                     sharedStreamArray.add(TestConstants.SURFACE_TYPE_IMAGE_READER);
275                 } else if (surfaceViewIdx != -1) {
276                     sharedStreamArray.add(TestConstants.SURFACE_TYPE_SURFACE_VIEW);
277                 }
278                 createSharedSessionJavaClient(sharedStreamArray);
279                 performUnsupportedCaptureSessionCommandsJavaClient();
280                 if (imageReaderIdx != -1) {
281                     SharedOutputConfiguration imgReaderConfig =
282                             sharedSessionConfig.getOutputStreamsInformation().get(imageReaderIdx);
283                     int imgWidth = imgReaderConfig.getSize().getWidth();
284                     int imgHeight = imgReaderConfig.getSize().getHeight();
285                     int imgFormat = imgReaderConfig.getFormat();
286                     assertCameraDeviceSharingSupportedNativeClient(mCameraId,
287                             /*sharingSupported*/true);
288                     nativeSharedTest = openSharedCameraNativeClient(mCameraId,
289                             /*isPrimaryClient*/false);
290                     testPerformUnsupportedOperationsNative(nativeSharedTest, imgWidth, imgHeight,
291                             imgFormat);
292                     createCaptureSessionNative(nativeSharedTest, imgWidth, imgHeight, imgFormat);
293                     testUnsupportedCaptureSessionCommandsNative(nativeSharedTest);
294                 }
295             } finally {
296                 try {
297                     closeCameraJavaClient();
298                 } finally {
299                     if (nativeSharedTest != 0) {
300                         closeNativeClient(nativeSharedTest);
301                     }
302                 }
303             }
304         }
305     }
306 
307     @Test
308     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSharedSessionTwoJavaClients()309     public void testSharedSessionTwoJavaClients() throws Exception {
310         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
311         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
312         // initialize client 2 process
313         mResultReceiver2 = new CameraResultReceiver(/* isFirstClient */ false);
314         mProcessPid2 =
315                 startRemoteProcess(
316                         SharedCameraActivitySecondaryClient.class,
317                         "SharedCameraActivityProcess2",
318                         mResultReceiver2);
319         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
320             mCameraId = cameraIdsUnderTest[i];
321             if (!mAllStaticInfo.get(mCameraId).sharedSessionConfigurationPresent()) {
322                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
323                 continue;
324             }
325             SharedSessionConfiguration sharedSessionConfig =
326                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
327             assertNotNull("Shared session configuration is null", sharedSessionConfig);
328             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
329             if (imageReaderIdx == -1) {
330                 Log.i(
331                         TAG,
332                         "Camera "
333                                 + mCameraId
334                                 + " does not have a stream supporting image reader and for shared"
335                                 + " session, skipping");
336                 continue;
337             }
338             assertCameraDeviceSharingSupportedJavaClient(mCameraId, /*sharingSupported*/ true);
339             try {
340                 openSharedCameraJavaClient(mCameraId, /* isPrimaryClient */ true);
341                 // starting new client with same priority replaces the old client as the primary
342                 openSharedCameraJavaClient(
343                         mCameraId, /* isPrimaryClient */
344                         true,
345                         /*expectedFail*/ false,
346                         mRemoteMessenger2);
347                 ArrayList<Integer> sharedStreamArray = new ArrayList<>();
348                 sharedStreamArray.add(TestConstants.SURFACE_TYPE_IMAGE_READER);
349                 createSharedSessionJavaClient(sharedStreamArray, mRemoteMessenger2);
350                 startPreviewJavaClient(sharedStreamArray, mRemoteMessenger2);
351                 createSharedSessionJavaClient(sharedStreamArray);
352                 startPreviewJavaClient(sharedStreamArray);
353                 SystemClock.sleep(PREVIEW_TIME_MS);
354                 stopPreviewJavaClient();
355                 stopPreviewJavaClient(mRemoteMessenger2);
356             } finally {
357                 closeCameraJavaClient();
358                 closeCameraJavaClient(mRemoteMessenger2);
359             }
360         }
361     }
362 
363     @Test
364     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testCameraDeviceSharingSupported()365     public void testCameraDeviceSharingSupported() throws Exception {
366         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
367         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
368         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
369             mCameraId = cameraIdsUnderTest[i];
370             if (!mAllStaticInfo.get(mCameraId).sharedSessionConfigurationPresent()) {
371                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
372                 continue;
373             }
374             assertTrue(
375                     "Camera device sharing is only supported for system cameras. Camera "
376                             + mCameraId
377                             + " is not a system camera.",
378                     mAdoptShellPerm);
379             assertCameraDeviceSharingSupportedJavaClient(mCameraId, /*sharingSupported*/true);
380             long nativeSharedTest = 0;
381             try {
382                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/true);
383                 assertCameraDeviceSharingSupportedNativeClient(mCameraId, /*sharingSupported*/true);
384                 nativeSharedTest =
385                         openSharedCameraNativeClient(mCameraId, /*isPrimaryClient*/false);
386                 // Verify that attempting to open the camera didn't cause anything weird to happen
387                 // in the other process.
388                 List<ErrorLoggingService.LogEvent> eventList2 = null;
389                 boolean timeoutExceptionHit = false;
390                 try {
391                     eventList2 = mErrorServiceConnection.getLog(EVICTION_TIMEOUT);
392                 } catch (TimeoutException e) {
393                     timeoutExceptionHit = true;
394                 }
395                 TestUtils.assertNone("SharedCameraActivity received unexpected events: ",
396                         eventList2);
397                 assertTrue("SharedCameraActivity error service exited early", timeoutExceptionHit);
398             } finally {
399                 try {
400                     closeCameraJavaClient();
401                 } finally {
402                     if (nativeSharedTest != 0) {
403                         closeNativeClient(nativeSharedTest);
404                     }
405                 }
406             }
407         }
408     }
409 
410     @Test
411     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testCameraDeviceSharingNotSupported()412     public void testCameraDeviceSharingNotSupported() throws Exception {
413         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
414         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
415         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
416             mCameraId = cameraIdsUnderTest[i];
417             if (mAllStaticInfo.get(mCameraId).sharedSessionConfigurationPresent()) {
418                 Log.i(TAG, "Camera " + mCameraId + " does support camera sharing, skipping");
419                 continue;
420             }
421             assertCameraDeviceSharingSupportedJavaClient(mCameraId, /*sharingSupported*/false);
422             openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/true, /*expectedFail*/true);
423             assertCameraDeviceSharingSupportedNativeClient(mCameraId, /*sharingSupported*/false);
424             long nativeSharedTest =
425                     openSharedCameraNativeClient(
426                             mCameraId, /*isPrimaryClient*/ false, /*expectedFail*/ true);
427             closeNativeClient(nativeSharedTest, /*expectCameraAlreadyClosed*/ true);
428         }
429     }
430 
431     @Test
432     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testClientSharedAccessPriorityChanged()433     public void testClientSharedAccessPriorityChanged() throws Exception {
434         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
435         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
436         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
437             mCameraId = cameraIdsUnderTest[i];
438             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
439                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
440                 continue;
441             }
442             long nativeSharedTest =
443                     openSharedCameraNativeClient(mCameraId, /*isPrimaryClient*/ true);
444             openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/ true);
445             assertClientAccessPriorityChangedNative(nativeSharedTest, /*isPrimaryClient*/ false);
446             mUiDevice.pressHome();
447             SystemClock.sleep(WAIT_TIME);
448             assertClientAccessPriorityChangedNative(nativeSharedTest, /*isPrimaryClient*/ true);
449             assertClientAccessPriorityChangedJava(/*isPrimaryClient*/ false);
450             forceCtsActivityToTop();
451             assertClientAccessPriorityChangedNative(nativeSharedTest, /*isPrimaryClient*/ false);
452             assertClientAccessPriorityChangedJava(/*isPrimaryClient*/ true);
453             closeCameraJavaClient();
454             assertClientAccessPriorityChangedNative(nativeSharedTest, /*isPrimaryClient*/ true);
455             closeNativeClient(nativeSharedTest);
456         }
457     }
458 
459     @Test
460     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSharedSessionCreationDifferentStreams()461     public void testSharedSessionCreationDifferentStreams() throws Exception {
462         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
463         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
464         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
465             mCameraId = cameraIdsUnderTest[i];
466             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
467                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
468                 continue;
469             }
470             SharedSessionConfiguration sharedSessionConfig =
471                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
472             assertNotNull("Shared session configuration is null", sharedSessionConfig);
473             if (sharedSessionConfig.getOutputStreamsInformation().size() < 2) {
474                 Log.i(
475                         TAG,
476                         "Camera "
477                                 + mCameraId
478                                 + " has less than two streams for "
479                                 + "shared session, skipping");
480                 continue;
481             }
482             int surfaceViewIdx = getSurfaceViewStreamIdx(sharedSessionConfig);
483             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
484             if ((surfaceViewIdx == -1) || (imageReaderIdx == -1)) {
485                 Log.i(
486                         TAG,
487                         "Camera "
488                                 + mCameraId
489                                 + " does not have two different streams supporting surface view and"
490                                 + " ImageReader for shared session, skipping");
491                 continue;
492             }
493             int imgWidth, imgHeight, imgFormat;
494             SharedOutputConfiguration imgReaderConfig =
495                     sharedSessionConfig.getOutputStreamsInformation().get(imageReaderIdx);
496             imgWidth = imgReaderConfig.getSize().getWidth();
497             imgHeight = imgReaderConfig.getSize().getHeight();
498             imgFormat = imgReaderConfig.getFormat();
499             long nativeSharedTest = 0;
500             try {
501                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/ true);
502                 nativeSharedTest =
503                         openSharedCameraNativeClient(mCameraId, /*isPrimaryClient*/ false);
504                 ArrayList<Integer> sharedStreamArray = new ArrayList<>();
505                 sharedStreamArray.add(TestConstants.SURFACE_TYPE_SURFACE_VIEW);
506                 createSharedSessionJavaClient(sharedStreamArray);
507                 startPreviewJavaClient(sharedStreamArray);
508                 SystemClock.sleep(PREVIEW_TIME_MS);
509                 createCaptureSessionNative(nativeSharedTest, imgWidth, imgHeight, imgFormat);
510                 startSharedStreamingNative(nativeSharedTest);
511                 SystemClock.sleep(PREVIEW_TIME_MS);
512                 stopSharedStreamingNative(nativeSharedTest);
513                 closeSessionNative(nativeSharedTest);
514                 stopPreviewJavaClient();
515             } finally {
516                 try {
517                     closeCameraJavaClient();
518                 } finally {
519                     if (nativeSharedTest != 0) {
520                         closeNativeClient(nativeSharedTest);
521                     }
522                 }
523             }
524         }
525     }
526 
527     @Test
528     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSharedSessionCreationSameStreams()529     public void testSharedSessionCreationSameStreams() throws Exception {
530         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
531         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
532         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
533             mCameraId = cameraIdsUnderTest[i];
534             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
535                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
536                 continue;
537             }
538             SharedSessionConfiguration sharedSessionConfig =
539                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
540             assertNotNull("Shared session configuration is null", sharedSessionConfig);
541             int surfaceViewIdx = getSurfaceViewStreamIdx(sharedSessionConfig);
542             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
543             ArrayList<Integer> sharedStreamArray = new ArrayList<>();
544             if (surfaceViewIdx != -1) {
545                 sharedStreamArray.add(TestConstants.SURFACE_TYPE_SURFACE_VIEW);
546             }
547             int imgWidth = -1;
548             int imgHeight = -1;
549             int imgFormat = -1;
550             if (imageReaderIdx != -1) {
551                 sharedStreamArray.add(TestConstants.SURFACE_TYPE_IMAGE_READER);
552                 SharedOutputConfiguration imgReaderConfig =
553                         sharedSessionConfig.getOutputStreamsInformation().get(imageReaderIdx);
554                 imgWidth = imgReaderConfig.getSize().getWidth();
555                 imgHeight = imgReaderConfig.getSize().getHeight();
556                 imgFormat = imgReaderConfig.getFormat();
557             }
558             long nativeSharedTest = 0;
559             try {
560                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/true);
561                 nativeSharedTest = openSharedCameraNativeClient(mCameraId,
562                         /*isPrimaryClient*/false);
563                 createSharedSessionJavaClient(sharedStreamArray);
564                 startPreviewJavaClient(sharedStreamArray);
565                 SystemClock.sleep(PREVIEW_TIME_MS);
566                 createCaptureSessionNative(nativeSharedTest, imgWidth, imgHeight, imgFormat);
567                 startSharedStreamingNative(nativeSharedTest);
568                 SystemClock.sleep(PREVIEW_TIME_MS);
569                 stopSharedStreamingNative(nativeSharedTest);
570                 closeSessionNative(nativeSharedTest);
571                 stopPreviewJavaClient();
572             } finally {
573                 try {
574                     closeCameraJavaClient();
575                 } finally {
576                     if (nativeSharedTest != 0) {
577                         closeNativeClient(nativeSharedTest);
578                     }
579                 }
580             }
581         }
582     }
583 
584     @Test
585     @RequiresFlagsEnabled(Flags.FLAG_CAMERA_MULTI_CLIENT)
testSecondaryClientStreamingBeforePrimary()586     public void testSecondaryClientStreamingBeforePrimary() throws Exception {
587         String[] cameraIdsUnderTest = getCameraIdsUnderTest();
588         if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(cameraIdsUnderTest));
589         for (int i = 0; i < cameraIdsUnderTest.length; i++) {
590             mCameraId = cameraIdsUnderTest[i];
591             if (!mCameraManager.isCameraDeviceSharingSupported(mCameraId)) {
592                 Log.i(TAG, "Camera " + mCameraId + " does not support camera sharing, skipping");
593                 continue;
594             }
595             SharedSessionConfiguration sharedSessionConfig =
596                     mAllStaticInfo.get(mCameraId).getSharedSessionConfiguration();
597             assertNotNull("Shared session configuration is null", sharedSessionConfig);
598             int surfaceViewIdx = getSurfaceViewStreamIdx(sharedSessionConfig);
599             int imageReaderIdx = getImageReaderStreamIdx(sharedSessionConfig);
600             ArrayList<Integer> sharedStreamArray = new ArrayList<>();
601             if (surfaceViewIdx != -1) {
602                 sharedStreamArray.add(TestConstants.SURFACE_TYPE_SURFACE_VIEW);
603             }
604             int imgWidth = -1;
605             int imgHeight = -1;
606             int imgFormat = -1;
607             if (imageReaderIdx != -1) {
608                 SharedOutputConfiguration imgReaderConfig =
609                         sharedSessionConfig.getOutputStreamsInformation().get(imageReaderIdx);
610                 imgWidth = imgReaderConfig.getSize().getWidth();
611                 imgHeight = imgReaderConfig.getSize().getHeight();
612                 imgFormat = imgReaderConfig.getFormat();
613             }
614             long nativeSharedTest = 0;
615             try {
616                 openSharedCameraJavaClient(mCameraId, /*isPrimaryClient*/true);
617                 nativeSharedTest = openSharedCameraNativeClient(mCameraId,
618                         /*isPrimaryClient*/false);
619                 createCaptureSessionNative(nativeSharedTest, imgWidth, imgHeight, imgFormat);
620                 startSharedStreamingNative(nativeSharedTest);
621                 SystemClock.sleep(PREVIEW_TIME_MS);
622                 stopSharedStreamingNative(nativeSharedTest);
623                 createSharedSessionJavaClient(sharedStreamArray);
624                 startPreviewJavaClient(sharedStreamArray);
625                 startSharedStreamingNative(nativeSharedTest);
626                 SystemClock.sleep(PREVIEW_TIME_MS);
627                 stopSharedStreamingNative(nativeSharedTest);
628                 closeSessionNative(nativeSharedTest);
629                 stopPreviewJavaClient();
630             } finally {
631                 try {
632                     closeCameraJavaClient();
633                 } finally {
634                     if (nativeSharedTest != 0) {
635                         closeNativeClient(nativeSharedTest);
636                     }
637                 }
638             }
639         }
640     }
641 
getSurfaceViewStreamIdx(SharedSessionConfiguration sharedSessionConfig)642     private int getSurfaceViewStreamIdx(SharedSessionConfiguration sharedSessionConfig) {
643         int surfaceViewIdx = -1;
644         List<SharedOutputConfiguration> sharedConfigs =
645                 sharedSessionConfig.getOutputStreamsInformation();
646         for (int i = 0; i < sharedConfigs.size(); i++) {
647             SharedOutputConfiguration outputStream = sharedConfigs.get(i);
648             if (outputStream.getSurfaceType() == TestConstants.SURFACE_TYPE_SURFACE_VIEW) {
649                 surfaceViewIdx = i;
650                 break;
651             }
652         }
653         return surfaceViewIdx;
654     }
655 
getImageReaderStreamIdx(SharedSessionConfiguration sharedSessionConfig)656     private int getImageReaderStreamIdx(SharedSessionConfiguration sharedSessionConfig) {
657         int imageReaderIdx = -1;
658         List<SharedOutputConfiguration> sharedConfigs =
659                 sharedSessionConfig.getOutputStreamsInformation();
660         for (int i = 0; i < sharedConfigs.size(); i++) {
661             SharedOutputConfiguration outputStream = sharedConfigs.get(i);
662             if (outputStream.getSurfaceType() == TestConstants.SURFACE_TYPE_IMAGE_READER) {
663                 imageReaderIdx = i;
664                 break;
665             }
666         }
667         return imageReaderIdx;
668     }
669 
assertCameraDeviceSharingSupportedJavaClient(String cameraId, boolean expectedTrue)670     private void assertCameraDeviceSharingSupportedJavaClient(String cameraId, boolean expectedTrue)
671             throws Exception {
672         assertEquals(
673                 "isCameraDeviceSharingSupported expected to return " + expectedTrue
674                 + " for camera id " + cameraId,
675                 expectedTrue, mCameraManager.isCameraDeviceSharingSupported(cameraId));
676     }
677 
assertCameraDeviceSharingSupportedNativeClient(String cameraId, boolean expectedTrue)678     private void assertCameraDeviceSharingSupportedNativeClient(String cameraId,
679             boolean expectedTrue) throws Exception {
680         boolean[] outBoolean = new boolean[1];
681         assertTrue(
682                 "testIsCameraDeviceSharingSupportedNative fail, see log for details",
683                 testIsCameraDeviceSharingSupportedNative(cameraId, outBoolean));
684         assertEquals(
685                 "isCameraDeviceSharingSupported expected to return " + expectedTrue
686                 + " for camera id " + cameraId,
687                 expectedTrue, outBoolean[0]);
688     }
689 
openSharedCameraJavaClient(String cameraId, boolean isPrimaryClient)690     private void openSharedCameraJavaClient(String cameraId, boolean isPrimaryClient)
691             throws Exception {
692         openSharedCameraJavaClient(
693                 cameraId, isPrimaryClient, /*expectFail*/ false, mRemoteMessenger);
694     }
695 
openSharedCameraJavaClient( String cameraId, boolean isPrimaryClient, boolean expectFail)696     private void openSharedCameraJavaClient(
697             String cameraId, boolean isPrimaryClient, boolean expectFail) throws Exception {
698         openSharedCameraJavaClient(cameraId, isPrimaryClient, expectFail, mRemoteMessenger);
699     }
700 
openSharedCameraJavaClient( String cameraId, boolean isPrimaryClient, boolean expectFail, Messenger remoteMessenger)701     private void openSharedCameraJavaClient(
702             String cameraId, boolean isPrimaryClient, boolean expectFail, Messenger remoteMessenger)
703             throws Exception {
704         Message msg = Message.obtain(null, TestConstants.OP_OPEN_CAMERA_SHARED);
705         msg.getData().putString(TestConstants.EXTRA_CAMERA_ID, cameraId);
706         boolean remoteExceptionHit = false;
707         try {
708             remoteMessenger.send(msg);
709         } catch (RemoteException e) {
710             remoteExceptionHit = true;
711         }
712         assertFalse(
713                 "Error in sending open camera command to SharedCameraActivity", remoteExceptionHit);
714         int expectedEvent;
715         if (expectFail) {
716             expectedEvent = TestConstants.EVENT_CAMERA_ERROR;
717         } else {
718             expectedEvent =
719                     isPrimaryClient
720                             ? TestConstants.EVENT_CAMERA_CONNECT_SHARED_PRIMARY
721                             : TestConstants.EVENT_CAMERA_CONNECT_SHARED_SECONDARY;
722         }
723         List<ErrorLoggingService.LogEvent> events =
724                 mErrorServiceConnection.getLog(SETUP_TIMEOUT, expectedEvent);
725         assertNotNull(
726                 "Did not receive any events from the camera device in remote process!", events);
727         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
728         assertTrue(eventTagCountMap.containsKey(expectedEvent));
729     }
730 
startPreviewJavaClient(ArrayList<Integer> sharedStreamArray)731     private void startPreviewJavaClient(ArrayList<Integer> sharedStreamArray) throws Exception {
732         startPreviewJavaClient(sharedStreamArray, mRemoteMessenger);
733     }
734 
startPreviewJavaClient(ArrayList<Integer> sharedStreamArray, Messenger remoteMessenger)735     private void startPreviewJavaClient(ArrayList<Integer> sharedStreamArray,
736             Messenger remoteMessenger) throws Exception {
737         Message msg = Message.obtain(null, TestConstants.OP_START_PREVIEW);
738         msg.getData()
739                 .putIntegerArrayList(TestConstants.EXTRA_SHARED_STREAM_ARRAY, sharedStreamArray);
740         boolean remoteExceptionHit = false;
741         try {
742             remoteMessenger.send(msg);
743         } catch (RemoteException e) {
744             remoteExceptionHit = true;
745         }
746         assertFalse(
747                 "Error in sending startPreview command to SharedCameraActivity",
748                 remoteExceptionHit);
749         List<ErrorLoggingService.LogEvent> events =
750                 mErrorServiceConnection.getLog(
751                         SETUP_TIMEOUT, TestConstants.EVENT_CAMERA_PREVIEW_STARTED);
752         assertNotNull(
753                 "Did not receive any events from the camera device in remote process!", events);
754         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
755         assertTrue(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_PREVIEW_STARTED));
756     }
757 
stopPreviewJavaClient()758     private void stopPreviewJavaClient() throws Exception {
759         stopPreviewJavaClient(mRemoteMessenger);
760     }
761 
stopPreviewJavaClient(Messenger remoteMessenger)762     private void stopPreviewJavaClient(Messenger remoteMessenger) throws Exception {
763         Message msg = Message.obtain(null, TestConstants.OP_STOP_PREVIEW);
764         boolean remoteExceptionHit = false;
765         try {
766             remoteMessenger.send(msg);
767         } catch (RemoteException e) {
768             remoteExceptionHit = true;
769         }
770         assertFalse(
771                 "Error in sending stopPreview command to SharedCameraActivity", remoteExceptionHit);
772         List<ErrorLoggingService.LogEvent> events =
773                 mErrorServiceConnection.getLog(
774                         SETUP_TIMEOUT, TestConstants.EVENT_CAMERA_PREVIEW_COMPLETED);
775         assertNotNull(
776                 "Did not receive any events from the camera device in remote process!", events);
777         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
778         assertTrue(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_PREVIEW_COMPLETED));
779     }
780 
createSharedSessionJavaClient(ArrayList<Integer> sharedStreamArray)781     private void createSharedSessionJavaClient(ArrayList<Integer> sharedStreamArray)
782             throws Exception {
783         createSharedSessionJavaClient(sharedStreamArray, mRemoteMessenger);
784     }
785 
createSharedSessionJavaClient( ArrayList<Integer> sharedStreamArray, Messenger remoteMessenger)786     private void createSharedSessionJavaClient(
787             ArrayList<Integer> sharedStreamArray, Messenger remoteMessenger) throws Exception {
788         Message msg = Message.obtain(null, TestConstants.OP_CREATE_SHARED_SESSION);
789         msg.getData()
790                 .putIntegerArrayList(TestConstants.EXTRA_SHARED_STREAM_ARRAY, sharedStreamArray);
791         boolean remoteExceptionHit = false;
792         try {
793             remoteMessenger.send(msg);
794         } catch (RemoteException e) {
795             remoteExceptionHit = true;
796         }
797         assertFalse(
798                 "Error in sending createSharedSession command to SharedCameraActivity",
799                 remoteExceptionHit);
800         List<ErrorLoggingService.LogEvent> events =
801                 mErrorServiceConnection.getLog(
802                         SETUP_TIMEOUT, TestConstants.EVENT_CAMERA_SESSION_CONFIGURED);
803         assertNotNull(
804                 "Did not receive any events from the camera device in remote process!", events);
805         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
806         assertTrue(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_SESSION_CONFIGURED));
807     }
808 
performCreateSharedSessionInvalidConfigsJavaClient()809     private void performCreateSharedSessionInvalidConfigsJavaClient() throws Exception {
810         Message msg = Message.obtain(null, TestConstants.OP_CREATE_SHARED_SESSION_INVALID_CONFIGS);
811         boolean remoteExceptionHit = false;
812         try {
813             mRemoteMessenger.send(msg);
814         } catch (RemoteException e) {
815             remoteExceptionHit = true;
816         }
817         assertFalse(
818                 "Error in sending createSharedSession command to SharedCameraActivity",
819                 remoteExceptionHit);
820         List<ErrorLoggingService.LogEvent> events = mErrorServiceConnection.getLog(SETUP_TIMEOUT);
821         assertNotNull(
822                 "Did not receive any events from the camera device in remote process!", events);
823         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
824         assertFalse(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_SESSION_CONFIGURED));
825         assertTrue(
826                 eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_SESSION_CONFIGURE_FAILED));
827     }
828 
performCreateSharedSessionUnsupportedOperationsJavaClient()829     private void performCreateSharedSessionUnsupportedOperationsJavaClient() throws Exception {
830         Message msg = Message.obtain(null, TestConstants.OP_PERFORM_UNSUPPORTED_COMMANDS);
831         boolean remoteExceptionHit = false;
832         try {
833             mRemoteMessenger.send(msg);
834         } catch (RemoteException e) {
835             remoteExceptionHit = true;
836         }
837         assertFalse(
838                 "Error in sending OP_PERFORM_UNSUPPORTED_COMMANDS command to SharedCameraActivity",
839                 remoteExceptionHit);
840         List<ErrorLoggingService.LogEvent> events = mErrorServiceConnection.getLog(SETUP_TIMEOUT);
841         assertNotNull(
842                 "Did not receive any events from the camera device in remote process!", events);
843         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
844         assertFalse(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_SESSION_CONFIGURED));
845         assertTrue(
846                 eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_SESSION_CONFIGURE_FAILED));
847     }
848 
performUnsupportedCaptureSessionCommandsJavaClient()849     private void performUnsupportedCaptureSessionCommandsJavaClient() throws Exception {
850         Message msg =
851                 Message.obtain(null, TestConstants.OP_PERFORM_UNSUPPORTED_CAPTURE_SESSION_COMMANDS);
852         boolean remoteExceptionHit = false;
853         try {
854             mRemoteMessenger.send(msg);
855         } catch (RemoteException e) {
856             remoteExceptionHit = true;
857         }
858         assertFalse(
859                 "Error in sending OP_PERFORM_UNSUPPORTED_CAPTURE_SESSION_COMMANDS command to"
860                         + " SharedCameraActivity",
861                 remoteExceptionHit);
862         List<ErrorLoggingService.LogEvent> events = mErrorServiceConnection.getLog(SETUP_TIMEOUT);
863         assertNotNull(
864                 "Did not receive any events from the camera device in remote process!", events);
865         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
866         assertFalse(
867                 eventTagCountMap.containsKey(
868                         TestConstants.EVENT_CAMERA_UNSUPPORTED_ACTIVITY_STARTED));
869         assertTrue(
870                 eventTagCountMap.containsKey(
871                         TestConstants.EVENT_CAMERA_UNSUPPORTED_ACTIVITY_FAILED));
872     }
873 
openSharedCameraNativeClient(String cameraId, boolean isPrimaryClient)874     private long openSharedCameraNativeClient(String cameraId, boolean isPrimaryClient)
875             throws Exception {
876         return testInitAndOpenSharedCameraNative(cameraId, isPrimaryClient, /*expectFail*/false);
877     }
878 
openSharedCameraNativeClient(String cameraId, boolean isPrimaryClient, boolean expectFail)879     private long openSharedCameraNativeClient(String cameraId, boolean isPrimaryClient,
880             boolean expectFail) throws Exception {
881         long nativeSharedTest = testInitAndOpenSharedCameraNative(cameraId, isPrimaryClient,
882                 expectFail);
883         assertTrue(
884                 "testInitAndOpenSharedCameraNative fail, see log for details",
885                 nativeSharedTest != 0);
886         return nativeSharedTest;
887     }
888 
openCameraJavaClient(String cameraId)889     private void openCameraJavaClient(String cameraId) throws Exception {
890         Message msg = Message.obtain(null, TestConstants.OP_OPEN_CAMERA);
891         msg.getData().putString(TestConstants.EXTRA_CAMERA_ID, cameraId);
892         boolean remoteExceptionHit = false;
893         try {
894             mRemoteMessenger.send(msg);
895         } catch (RemoteException e) {
896             remoteExceptionHit = true;
897         }
898         assertFalse(
899                 "Error in sending open camera command to SharedCameraActivity", remoteExceptionHit);
900         List<ErrorLoggingService.LogEvent> events =
901                 mErrorServiceConnection.getLog(SETUP_TIMEOUT, TestConstants.EVENT_CAMERA_CONNECT);
902         assertNotNull("Camera device not connected in remote process!", events);
903         TestUtils.assertOnly(TestConstants.EVENT_CAMERA_CONNECT, events);
904     }
905 
openCameraNativeClient(String cameraId)906     private long openCameraNativeClient(String cameraId) throws Exception {
907         return openCameraNativeClient(cameraId, /* expectFail */ false);
908     }
909 
openCameraNativeClient(String cameraId, boolean expectFail)910     private long openCameraNativeClient(String cameraId, boolean expectFail) throws Exception {
911         long nativeSharedTest = testInitAndOpenCameraNative(cameraId, expectFail);
912         assertTrue("testInitAndOpenCameraNative fail, see log for details", nativeSharedTest != 0);
913         return nativeSharedTest;
914     }
915 
closeCameraJavaClient()916     private void closeCameraJavaClient() throws Exception {
917         closeCameraJavaClient(mRemoteMessenger);
918     }
919 
closeCameraJavaClient(Messenger remoteMessenger)920     private void closeCameraJavaClient(Messenger remoteMessenger) throws Exception {
921         Message msg = Message.obtain(null, TestConstants.OP_CLOSE_CAMERA);
922         boolean remoteExceptionHit = false;
923         try {
924             remoteMessenger.send(msg);
925         } catch (RemoteException e) {
926             remoteExceptionHit = true;
927         }
928         assertFalse(
929                 "Error in sending close camera command to SharedCameraActivity",
930                 remoteExceptionHit);
931         List<ErrorLoggingService.LogEvent> events =
932                 mErrorServiceConnection.getLog(SETUP_TIMEOUT, TestConstants.EVENT_CAMERA_CLOSED);
933         assertNotNull(
934                 "Did not receive any events from the camera device in remote process!", events);
935         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
936         assertTrue(eventTagCountMap.containsKey(TestConstants.EVENT_CAMERA_CLOSED));
937     }
938 
assertClientAccessPriorityChangedJava(boolean isPrimaryClient)939     private void assertClientAccessPriorityChangedJava(boolean isPrimaryClient) throws Exception {
940         int expectedEvent;
941         expectedEvent = isPrimaryClient
942                 ? TestConstants.EVENT_CLIENT_ACCESS_PRIORITIES_CHANGED_TO_PRIMARY :
943                 TestConstants.EVENT_CLIENT_ACCESS_PRIORITIES_CHANGED_TO_SECONDARY;
944         List<ErrorLoggingService.LogEvent> events =
945                 mErrorServiceConnection.getLog(SETUP_TIMEOUT, expectedEvent);
946         assertNotNull(
947                 "Did not receive any events from the camera device in remote process!", events);
948         Map<Integer, Integer> eventTagCountMap = TestUtils.getEventTagCountMap(events);
949         assertTrue(eventTagCountMap.containsKey(expectedEvent));
950     }
951 
assertClientAccessPriorityChangedNative( long nativeSharedTest, boolean isPrimaryClient)952     private void assertClientAccessPriorityChangedNative(
953             long nativeSharedTest, boolean isPrimaryClient) throws Exception {
954         assertTrue(
955                 "testClientAccessPriorityChangedNative fail, see log for details",
956                 testClientAccessPriorityChangedNative(nativeSharedTest, isPrimaryClient));
957     }
958 
closeNativeClient(long nativeSharedTest)959     private void closeNativeClient(long nativeSharedTest) throws Exception {
960         closeNativeClient(nativeSharedTest, /* expectCameraAlreadyClosed */ false);
961     }
962 
closeNativeClient(long nativeSharedTest, boolean expectCameraAlreadyClosed)963     private void closeNativeClient(long nativeSharedTest, boolean expectCameraAlreadyClosed)
964             throws Exception {
965         assertTrue(
966                 "testDeInitAndCloseSharedCameraNative fail, see log for details",
967                 testDeInitAndCloseSharedCameraNative(nativeSharedTest, expectCameraAlreadyClosed));
968     }
969 
assertCameraEvictedNativeClient(long nativeSharedTest)970     private void assertCameraEvictedNativeClient(long nativeSharedTest) throws Exception {
971         assertTrue(
972                 "testIsCameraEvictedNative fail, see log for details",
973                 testIsCameraEvictedNative(nativeSharedTest));
974     }
975 
createCaptureSessionNative(long nativeSharedTest, int imgWidth, int imgHeight, int imgFormat)976     private void createCaptureSessionNative(long nativeSharedTest, int imgWidth, int imgHeight,
977             int imgFormat) {
978         assertTrue(
979                 "testCreateCaptureSessionNative fail, see log for details",
980                 testCreateCaptureSessionNative(nativeSharedTest, imgWidth, imgHeight, imgFormat));
981     }
982 
startSharedStreamingNative(long nativeSharedTest)983     private void startSharedStreamingNative(long nativeSharedTest) {
984         assertTrue(
985                 "testStartStreamingNative fail, see log for details",
986                 testStartSharedStreamingNative(nativeSharedTest));
987     }
988 
stopSharedStreamingNative(long nativeSharedTest)989     private void stopSharedStreamingNative(long nativeSharedTest) {
990         assertTrue(
991                 "testStopStreamingNative fail, see log for details",
992                 testStopSharedStreamingNative(nativeSharedTest));
993     }
994 
closeSessionNative(long nativeSharedTest)995     private void closeSessionNative(long nativeSharedTest) {
996         assertTrue(
997                 "testCloseSessionNative fail, see log for details",
998                  testCloseSessionNative(nativeSharedTest));
999     }
1000 
1001     /**
1002      * Start an activity of the given class running in a remote process with the given name.
1003      *
1004      * @param klass the class of the {@link android.app.Activity} to start.
1005      * @param processName the remote activity name.
1006      * @param resultReceiver.
1007      * @throws InterruptedException
1008      */
startRemoteProcess( java.lang.Class<?> klass, String processName, ResultReceiver resultReceiver)1009     public int startRemoteProcess(
1010             java.lang.Class<?> klass, String processName, ResultReceiver resultReceiver)
1011             throws InterruptedException {
1012         String cameraActivityName = mContext.getPackageName() + ":" + processName;
1013         // Ensure no running activity process with same name
1014         List<ActivityManager.RunningAppProcessInfo> list =
1015                 mActivityManager.getRunningAppProcesses();
1016         assertEquals("Activity " + cameraActivityName + " already running.", -1,
1017                 TestUtils.getPid(cameraActivityName, list));
1018         Intent activityIntent = new Intent(mContext, klass);
1019         activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1020         activityIntent.putExtra(TestConstants.EXTRA_RESULT_RECEIVER, resultReceiver);
1021         mContext.startActivity(activityIntent);
1022         Thread.sleep(WAIT_TIME);
1023 
1024         // Fail if activity isn't running
1025         list = mActivityManager.getRunningAppProcesses();
1026         int processPid = TestUtils.getPid(cameraActivityName, list);
1027         assertTrue(
1028                 "Activity "
1029                         + cameraActivityName
1030                         + " not found in list of running app"
1031                         + " processes.",
1032                 -1 != processPid);
1033         return processPid;
1034     }
1035 
1036     /**
1037      * Ensure the CTS activity becomes foreground again instead of launcher.
1038      */
forceCtsActivityToTop()1039     private void forceCtsActivityToTop() throws InterruptedException {
1040         Intent bringToTopIntent = new Intent(mContext, SharedCameraActivity.class);
1041         bringToTopIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
1042                 | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
1043         mContext.startActivity(bringToTopIntent);
1044         Thread.sleep(WAIT_TIME);
1045     }
1046 
testIsCameraDeviceSharingSupportedNative(String cameraId, boolean[] outResult)1047     private static native boolean testIsCameraDeviceSharingSupportedNative(String cameraId,
1048             boolean[] outResult);
testInitAndOpenSharedCameraNative(String cameraId, boolean primaryClient, boolean expectFail)1049     private static native long testInitAndOpenSharedCameraNative(String cameraId,
1050             boolean primaryClient, boolean expectFail);
testInitAndOpenCameraNative(String cameraId, boolean expectFail)1051     private static native long testInitAndOpenCameraNative(String cameraId, boolean expectFail);
testIsCameraEvictedNative(long sharedTestContext)1052     private static native boolean testIsCameraEvictedNative(long sharedTestContext);
testDeInitAndCloseSharedCameraNative( long sharedTestContext, boolean expectCameraAlreadyClosed)1053     private static native boolean testDeInitAndCloseSharedCameraNative(
1054             long sharedTestContext, boolean expectCameraAlreadyClosed);
testCreateCaptureSessionNative(long sharedTestContext, int width, int height, int format)1055     private static native boolean testCreateCaptureSessionNative(long sharedTestContext, int width,
1056             int height, int format);
testCloseSessionNative(long sharedTestContext)1057     private static native boolean testCloseSessionNative(long sharedTestContext);
testStartSharedStreamingNative(long sharedTestContext)1058     private static native boolean testStartSharedStreamingNative(long sharedTestContext);
testStopSharedStreamingNative(long sharedTestContext)1059     private static native boolean testStopSharedStreamingNative(long sharedTestContext);
testPerformUnsupportedOperationsNative(long sharedTestContext, int width, int height, int format)1060     private static native boolean testPerformUnsupportedOperationsNative(long sharedTestContext,
1061             int width, int height, int format);
testUnsupportedCaptureSessionCommandsNative( long sharedTestContext)1062     private static native boolean testUnsupportedCaptureSessionCommandsNative(
1063             long sharedTestContext);
testClientAccessPriorityChangedNative(long sharedTestContext, boolean primaryClient)1064     private static native boolean testClientAccessPriorityChangedNative(long sharedTestContext,
1065             boolean primaryClient);
1066 }
1067