CameraDeviceBinderTest.java revision b6c38e9de1a2824ce599d7074fa4a226926177c1
1/* 2 * Copyright (C) 2013 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 17package com.android.mediaframeworktest.integration; 18 19import android.graphics.SurfaceTexture; 20import android.hardware.camera2.CameraMetadata; 21import android.hardware.camera2.CameraProperties; 22import android.hardware.camera2.CaptureRequest; 23import android.hardware.camera2.ICameraDeviceCallbacks; 24import android.hardware.camera2.ICameraDeviceUser; 25import android.hardware.camera2.utils.BinderHolder; 26import android.os.RemoteException; 27import android.test.AndroidTestCase; 28import android.test.suitebuilder.annotation.SmallTest; 29import android.util.Log; 30import android.view.Surface; 31 32import static android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW; 33 34import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner; 35 36import org.mockito.ArgumentMatcher; 37import static org.mockito.Mockito.*; 38 39public class CameraDeviceBinderTest extends AndroidTestCase { 40 private static String TAG = "CameraDeviceBinderTest"; 41 // Number of streaming callbacks need to check. 42 private static int NUM_CALLBACKS_CHECKED = 10; 43 // Wait for capture result timeout value: 1500ms 44 private final static int WAIT_FOR_COMPLETE_TIMEOUT_MS = 1500; 45 46 private int mCameraId; 47 private ICameraDeviceUser mCameraUser; 48 private CameraBinderTestUtils mUtils; 49 private ICameraDeviceCallbacks.Stub mMockCb; 50 private Surface mSurface; 51 // Need hold a Surfacetexture reference during a test execution, otherwise, 52 // it could be GCed during a test, which causes camera run into bad state. 53 private SurfaceTexture mSurfaceTexture; 54 55 public CameraDeviceBinderTest() { 56 } 57 58 public class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { 59 60 @Override 61 public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException { 62 } 63 64 @Override 65 public void onResultReceived(int frameId, CameraMetadata result) throws RemoteException { 66 } 67 } 68 69 class IsMetadataNotEmpty extends ArgumentMatcher<CameraMetadata> { 70 public boolean matches(Object obj) { 71 return !((CameraMetadata) obj).isEmpty(); 72 } 73 } 74 75 private void createDefaultSurface() { 76 mSurfaceTexture = new SurfaceTexture(/* ignored */0); 77 mSurfaceTexture.setDefaultBufferSize(640, 480); 78 mSurface = new Surface(mSurfaceTexture); 79 } 80 81 private CaptureRequest createDefaultRequest(boolean needStream) throws Exception { 82 CameraMetadata metadata = new CameraMetadata(); 83 assertTrue(metadata.isEmpty()); 84 85 CaptureRequest request = new CaptureRequest(); 86 assertTrue(request.isEmpty()); 87 88 int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata); 89 assertEquals(CameraBinderTestUtils.NO_ERROR, status); 90 assertFalse(metadata.isEmpty()); 91 92 request.swap(metadata); 93 assertFalse(request.isEmpty()); 94 assertTrue(metadata.isEmpty()); 95 if (needStream) { 96 int streamId = mCameraUser.createStream(/* ignored */10, /* ignored */20, 97 /* ignored */30, mSurface); 98 assertEquals(0, streamId); 99 request.addTarget(mSurface); 100 } 101 return request; 102 } 103 104 private int submitCameraRequest(CaptureRequest request, boolean streaming) throws Exception { 105 int requestId = mCameraUser.submitRequest(request, streaming); 106 assertTrue("Request IDs should be non-negative", requestId >= 0); 107 return requestId; 108 } 109 110 @Override 111 protected void setUp() throws Exception { 112 super.setUp(); 113 114 /** 115 * Workaround for mockito and JB-MR2 incompatibility 116 * 117 * Avoid java.lang.IllegalArgumentException: dexcache == null 118 * https://code.google.com/p/dexmaker/issues/detail?id=2 119 */ 120 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 121 mUtils = new CameraBinderTestUtils(getContext()); 122 123 // This cannot be set in the constructor, since the onCreate isn't 124 // called yet 125 mCameraId = MediaFrameworkIntegrationTestRunner.mCameraId; 126 127 ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks(); 128 129 String clientPackageName = getContext().getPackageName(); 130 131 mMockCb = spy(dummyCallbacks); 132 133 BinderHolder holder = new BinderHolder(); 134 mUtils.getCameraService().connectDevice(mMockCb, mCameraId, 135 clientPackageName, CameraBinderTestUtils.USE_CALLING_UID, holder); 136 mCameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder()); 137 assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser); 138 createDefaultSurface(); 139 140 Log.v(TAG, String.format("Camera %s connected", mCameraId)); 141 } 142 143 @Override 144 protected void tearDown() throws Exception { 145 mCameraUser.disconnect(); 146 mCameraUser = null; 147 mSurface.release(); 148 mSurfaceTexture.release(); 149 } 150 151 @SmallTest 152 public void testCreateDefaultRequest() throws Exception { 153 CameraMetadata metadata = new CameraMetadata(); 154 assertTrue(metadata.isEmpty()); 155 156 int status = mCameraUser.createDefaultRequest(TEMPLATE_PREVIEW, /* out */metadata); 157 assertEquals(CameraBinderTestUtils.NO_ERROR, status); 158 assertFalse(metadata.isEmpty()); 159 160 metadata.close(); 161 } 162 163 @SmallTest 164 public void testCreateStream() throws Exception { 165 int streamId = mCameraUser.createStream(/* ignored */10, /* ignored */20, /* ignored */30, 166 mSurface); 167 assertEquals(0, streamId); 168 169 assertEquals(CameraBinderTestUtils.ALREADY_EXISTS, 170 mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, mSurface)); 171 172 assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId)); 173 } 174 175 @SmallTest 176 public void testDeleteInvalidStream() throws Exception { 177 assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(-1)); 178 assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0)); 179 assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(1)); 180 assertEquals(CameraBinderTestUtils.BAD_VALUE, mCameraUser.deleteStream(0xC0FFEE)); 181 } 182 183 @SmallTest 184 public void testCreateStreamTwo() throws Exception { 185 186 // Create first stream 187 int streamId = mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, 188 mSurface); 189 assertEquals(0, streamId); 190 191 assertEquals(CameraBinderTestUtils.ALREADY_EXISTS, 192 mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, mSurface)); 193 194 // Create second stream with a different surface. 195 SurfaceTexture surfaceTexture = new SurfaceTexture(/* ignored */0); 196 surfaceTexture.setDefaultBufferSize(640, 480); 197 Surface surface2 = new Surface(surfaceTexture); 198 199 int streamId2 = mCameraUser.createStream(/* ignored */0, /* ignored */0, /* ignored */0, 200 surface2); 201 assertEquals(1, streamId2); 202 203 // Clean up streams 204 assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId)); 205 assertEquals(CameraBinderTestUtils.NO_ERROR, mCameraUser.deleteStream(streamId2)); 206 } 207 208 @SmallTest 209 public void testSubmitBadRequest() throws Exception { 210 211 CaptureRequest request = createDefaultRequest(/* needStream */false); 212 int status = mCameraUser.submitRequest(request, /* streaming */false); 213 assertEquals("Expected submitRequest to return BAD_VALUE " + 214 "since we had 0 surface targets set.", CameraBinderTestUtils.BAD_VALUE, status); 215 216 request.addTarget(mSurface); 217 status = mCameraUser.submitRequest(request, /* streaming */false); 218 assertEquals("Expected submitRequest to return BAD_VALUE since " + 219 "the target surface wasn't registered with createStream.", 220 CameraBinderTestUtils.BAD_VALUE, status); 221 222 request.close(); 223 } 224 225 @SmallTest 226 public void testSubmitGoodRequest() throws Exception { 227 228 CaptureRequest request = createDefaultRequest(/* needStream */true); 229 230 // Submit valid request twice. 231 int requestId1 = submitCameraRequest(request, /* streaming */false); 232 int requestId2 = submitCameraRequest(request, /* streaming */false); 233 assertNotSame("Request IDs should be unique for multiple requests", requestId1, requestId2); 234 235 request.close(); 236 } 237 238 @SmallTest 239 public void testSubmitStreamingRequest() throws Exception { 240 241 CaptureRequest request = createDefaultRequest(/* needStream */true); 242 243 // Submit valid request once (non-streaming), and another time 244 // (streaming) 245 int requestId1 = submitCameraRequest(request, /* streaming */false); 246 247 int requestIdStreaming = submitCameraRequest(request, /* streaming */true); 248 assertNotSame("Request IDs should be unique for multiple requests", requestId1, 249 requestIdStreaming); 250 251 int status = mCameraUser.cancelRequest(-1); 252 assertEquals("Invalid request IDs should not be cancellable", 253 CameraBinderTestUtils.BAD_VALUE, status); 254 255 status = mCameraUser.cancelRequest(requestId1); 256 assertEquals("Non-streaming request IDs should not be cancellable", 257 CameraBinderTestUtils.BAD_VALUE, status); 258 259 status = mCameraUser.cancelRequest(requestIdStreaming); 260 assertEquals("Streaming request IDs should be cancellable", CameraBinderTestUtils.NO_ERROR, 261 status); 262 263 request.close(); 264 } 265 266 @SmallTest 267 public void testCameraInfo() throws RemoteException { 268 CameraMetadata info = new CameraMetadata(); 269 270 int status = mCameraUser.getCameraInfo(/*out*/info); 271 assertEquals(CameraBinderTestUtils.NO_ERROR, status); 272 273 assertFalse(info.isEmpty()); 274 assertNotNull(info.get(CameraProperties.SCALER_AVAILABLE_FORMATS)); 275 } 276 277 @SmallTest 278 public void testWaitUntilIdle() throws Exception { 279 CaptureRequest request = createDefaultRequest(/* needStream */true); 280 int requestIdStreaming = submitCameraRequest(request, /* streaming */true); 281 282 // Test Bad case first: waitUntilIdle when there is active repeating request 283 int status = mCameraUser.waitUntilIdle(); 284 assertEquals("waitUntilIdle is invalid operation when there is active repeating request", 285 CameraBinderTestUtils.INVALID_OPERATION, status); 286 287 // Test good case, waitUntilIdle when there is no active repeating request 288 status = mCameraUser.cancelRequest(requestIdStreaming); 289 assertEquals(CameraBinderTestUtils.NO_ERROR, status); 290 status = mCameraUser.waitUntilIdle(); 291 assertEquals(CameraBinderTestUtils.NO_ERROR, status); 292 } 293 294 @SmallTest 295 public void testCaptureResultCallbacks() throws Exception { 296 IsMetadataNotEmpty matcher = new IsMetadataNotEmpty(); 297 CaptureRequest request = createDefaultRequest(/* needStream */true); 298 299 // Test both single request and streaming request. 300 int requestId1 = submitCameraRequest(request, /* streaming */false); 301 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).times(1)).onResultReceived( 302 eq(requestId1), 303 argThat(matcher)); 304 305 int streamingId = submitCameraRequest(request, /* streaming */true); 306 verify(mMockCb, timeout(WAIT_FOR_COMPLETE_TIMEOUT_MS).atLeast(NUM_CALLBACKS_CHECKED)) 307 .onResultReceived( 308 eq(streamingId), 309 argThat(matcher)); 310 request.close(); 311 } 312} 313