blob: 5f8f7729990c12013aa9d2adbd38748e10ac916a [file] [log] [blame]
Igor Murashkin634a5152013-02-20 17:15:11 -08001/*
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
17#include <gtest/gtest.h>
18#include <iostream>
19
Igor Murashkin53765732013-02-20 17:41:57 -080020#include <binder/IPCThreadState.h>
21#include <utils/Thread.h>
22
Igor Murashkin634a5152013-02-20 17:15:11 -080023#include "Camera.h"
24#include "ProCamera.h"
Igor Murashkin53765732013-02-20 17:41:57 -080025#include <utils/Vector.h>
26#include <utils/Mutex.h>
27#include <utils/Condition.h>
Igor Murashkin634a5152013-02-20 17:15:11 -080028
Igor Murashkin68506fd2013-02-20 17:57:31 -080029#include <gui/SurfaceComposerClient.h>
30#include <gui/Surface.h>
31
32#include <system/camera_metadata.h>
33#include <hardware/camera2.h> // for CAMERA2_TEMPLATE_PREVIEW only
Igor Murashkindcb07d52013-02-21 14:18:10 -080034#include <camera/CameraMetadata.h>
Igor Murashkin68506fd2013-02-20 17:57:31 -080035
Igor Murashkinbfc99152013-02-27 12:55:20 -080036#include <camera/ICameraServiceListener.h>
37
Igor Murashkin634a5152013-02-20 17:15:11 -080038namespace android {
39namespace camera2 {
40namespace tests {
41namespace client {
42
43#define CAMERA_ID 0
44#define TEST_DEBUGGING 0
45
Igor Murashkin68506fd2013-02-20 17:57:31 -080046#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
Igor Murashkin5835cc42013-02-20 19:29:53 -080047#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
48
Igor Murashkineb72e172013-02-21 11:43:14 -080049#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
Igor Murashkin5835cc42013-02-20 19:29:53 -080050#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
51
Igor Murashkindcb07d52013-02-21 14:18:10 -080052// defaults for display "test"
Igor Murashkinbfc99152013-02-27 12:55:20 -080053#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y8
54#define TEST_DISPLAY_WIDTH 320
55#define TEST_DISPLAY_HEIGHT 240
Igor Murashkindcb07d52013-02-21 14:18:10 -080056
Igor Murashkin5835cc42013-02-20 19:29:53 -080057#define TEST_CPU_FRAME_COUNT 2
58#define TEST_CPU_HEAP_COUNT 5
Igor Murashkin53765732013-02-20 17:41:57 -080059
Igor Murashkin4bc4a382013-02-20 13:36:17 -080060#define TEST_FRAME_PROCESSING_DELAY_US 200000 // 200 ms
61
Igor Murashkin634a5152013-02-20 17:15:11 -080062#if TEST_DEBUGGING
63#define dout std::cerr
64#else
65#define dout if (0) std::cerr
66#endif
67
Igor Murashkin39f79f72013-01-30 10:14:24 -080068#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
69#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
70
71class ProCameraTest;
72
Igor Murashkinbfc99152013-02-27 12:55:20 -080073struct ServiceListener : public BnCameraServiceListener {
74
75 ServiceListener() :
76 mLatestStatus(STATUS_UNKNOWN),
77 mPrevStatus(STATUS_UNKNOWN)
78 {
79 }
80
81 void onStatusChanged(Status status, int32_t cameraId) {
82 dout << "On status changed: 0x" << std::hex
83 << status << " cameraId " << cameraId
84 << std::endl;
85
86 Mutex::Autolock al(mMutex);
87
88 mLatestStatus = status;
89 mCondition.broadcast();
90 }
91
92 status_t waitForStatusChange(Status& newStatus) {
93 Mutex::Autolock al(mMutex);
94
95 if (mLatestStatus != mPrevStatus) {
96 newStatus = mLatestStatus;
97 mPrevStatus = mLatestStatus;
98 return OK;
99 }
100
101 status_t stat = mCondition.waitRelative(mMutex,
102 TEST_LISTENER_TIMEOUT);
103
104 if (stat == OK) {
105 newStatus = mLatestStatus;
106 mPrevStatus = mLatestStatus;
107 }
108
109 return stat;
110 }
111
112 Condition mCondition;
113 Mutex mMutex;
114
115 Status mLatestStatus;
116 Status mPrevStatus;
117};
118
Igor Murashkin5835cc42013-02-20 19:29:53 -0800119enum ProEvent {
Igor Murashkin53765732013-02-20 17:41:57 -0800120 UNKNOWN,
121 ACQUIRED,
122 RELEASED,
Igor Murashkin5835cc42013-02-20 19:29:53 -0800123 STOLEN,
124 BUFFER_RECEIVED,
Igor Murashkina91537e2013-02-21 12:02:29 -0800125 RESULT_RECEIVED,
Igor Murashkin53765732013-02-20 17:41:57 -0800126};
127
Igor Murashkina91537e2013-02-21 12:02:29 -0800128inline int ProEvent_Mask(ProEvent e) {
129 return (1 << static_cast<int>(e));
130}
131
Igor Murashkin5835cc42013-02-20 19:29:53 -0800132typedef Vector<ProEvent> EventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800133
134class ProCameraTestThread : public Thread
135{
136public:
137 ProCameraTestThread() {
138 }
139
140 virtual bool threadLoop() {
141 mProc = ProcessState::self();
142 mProc->startThreadPool();
143
144 IPCThreadState *ptr = IPCThreadState::self();
145
Igor Murashkin53765732013-02-20 17:41:57 -0800146 ptr->joinThreadPool();
Igor Murashkin53765732013-02-20 17:41:57 -0800147
148 return false;
149 }
150
151 sp<ProcessState> mProc;
152};
153
154class ProCameraTestListener : public ProCameraListener {
155
156public:
Igor Murashkina91537e2013-02-21 12:02:29 -0800157 static const int EVENT_MASK_ALL = 0xFFFFFFFF;
158
159 ProCameraTestListener() {
160 mEventMask = EVENT_MASK_ALL;
161 }
162
Igor Murashkin53765732013-02-20 17:41:57 -0800163 status_t WaitForEvent() {
164 Mutex::Autolock cal(mConditionMutex);
165
166 {
167 Mutex::Autolock al(mListenerMutex);
168
Igor Murashkin5835cc42013-02-20 19:29:53 -0800169 if (mProEventList.size() > 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800170 return OK;
171 }
172 }
173
174 return mListenerCondition.waitRelative(mConditionMutex,
175 TEST_LISTENER_TIMEOUT);
176 }
177
178 /* Read events into out. Existing queue is flushed */
179 void ReadEvents(EventList& out) {
180 Mutex::Autolock al(mListenerMutex);
181
Igor Murashkin5835cc42013-02-20 19:29:53 -0800182 for (size_t i = 0; i < mProEventList.size(); ++i) {
183 out.push(mProEventList[i]);
Igor Murashkin53765732013-02-20 17:41:57 -0800184 }
185
Igor Murashkin5835cc42013-02-20 19:29:53 -0800186 mProEventList.clear();
Igor Murashkin53765732013-02-20 17:41:57 -0800187 }
188
189 /**
190 * Dequeue 1 event from the event queue.
191 * Returns UNKNOWN if queue is empty
192 */
Igor Murashkin5835cc42013-02-20 19:29:53 -0800193 ProEvent ReadEvent() {
Igor Murashkin53765732013-02-20 17:41:57 -0800194 Mutex::Autolock al(mListenerMutex);
195
Igor Murashkin5835cc42013-02-20 19:29:53 -0800196 if (mProEventList.size() == 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800197 return UNKNOWN;
198 }
199
Igor Murashkin5835cc42013-02-20 19:29:53 -0800200 ProEvent ev = mProEventList[0];
201 mProEventList.removeAt(0);
Igor Murashkin53765732013-02-20 17:41:57 -0800202
203 return ev;
204 }
205
Igor Murashkina91537e2013-02-21 12:02:29 -0800206 void SetEventMask(int eventMask) {
207 Mutex::Autolock al(mListenerMutex);
208 mEventMask = eventMask;
209 }
210
Igor Murashkin53765732013-02-20 17:41:57 -0800211private:
Igor Murashkin5835cc42013-02-20 19:29:53 -0800212 void QueueEvent(ProEvent ev) {
Igor Murashkina91537e2013-02-21 12:02:29 -0800213 bool eventAdded = false;
Igor Murashkin53765732013-02-20 17:41:57 -0800214 {
215 Mutex::Autolock al(mListenerMutex);
Igor Murashkina91537e2013-02-21 12:02:29 -0800216
217 if (ProEvent_Mask(ev) & mEventMask) {
218 mProEventList.push(ev);
219 eventAdded = true;
220 }
Igor Murashkin53765732013-02-20 17:41:57 -0800221 }
222
Igor Murashkina91537e2013-02-21 12:02:29 -0800223 if (eventAdded) {
224 mListenerCondition.broadcast();
225 }
Igor Murashkin53765732013-02-20 17:41:57 -0800226 }
227
228protected:
229
230 //////////////////////////////////////////////////
231 ///////// ProCameraListener //////////////////////
232 //////////////////////////////////////////////////
233
234
235 // Lock has been acquired. Write operations now available.
236 virtual void onLockAcquired() {
237 QueueEvent(ACQUIRED);
238 }
239 // Lock has been released with exclusiveUnlock
240 virtual void onLockReleased() {
241 QueueEvent(RELEASED);
242 }
243
244 // Lock has been stolen by another client.
245 virtual void onLockStolen() {
246 QueueEvent(STOLEN);
247 }
248
249 // Lock free.
250 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
251
252 dout << "Trigger notify: " << ext1 << " " << ext2
253 << " " << ext3 << std::endl;
254 }
255
Igor Murashkin5835cc42013-02-20 19:29:53 -0800256 virtual void onBufferReceived(int streamId,
257 const CpuConsumer::LockedBuffer& buf) {
258
259 dout << "Buffer received on streamId = " << streamId <<
Igor Murashkina140a6e2013-02-21 14:45:03 -0800260 ", dataPtr = " << (void*)buf.data <<
261 ", timestamp = " << buf.timestamp << std::endl;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800262
263 QueueEvent(BUFFER_RECEIVED);
264
265 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800266 virtual void onResultReceived(int32_t frameId,
267 camera_metadata* request) {
268 dout << "Result received frameId = " << frameId
269 << ", requestPtr = " << (void*)request << std::endl;
270 QueueEvent(RESULT_RECEIVED);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800271 free_camera_metadata(request);
272 }
273
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800274 virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
275 dout << "Notify received: msg " << std::hex << msg
276 << ", ext1: " << std::hex << ext1 << ", ext2: " << std::hex << ext2
277 << std::endl;
278 }
Igor Murashkin53765732013-02-20 17:41:57 -0800279
Igor Murashkin5835cc42013-02-20 19:29:53 -0800280 Vector<ProEvent> mProEventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800281 Mutex mListenerMutex;
282 Mutex mConditionMutex;
283 Condition mListenerCondition;
Igor Murashkina91537e2013-02-21 12:02:29 -0800284 int mEventMask;
Igor Murashkin53765732013-02-20 17:41:57 -0800285};
286
Igor Murashkin634a5152013-02-20 17:15:11 -0800287class ProCameraTest : public ::testing::Test {
288
Igor Murashkin53765732013-02-20 17:41:57 -0800289public:
290 ProCameraTest() {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800291 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
292 if (displaySecsEnv != NULL) {
293 mDisplaySecs = atoi(displaySecsEnv);
294 if (mDisplaySecs < 0) {
295 mDisplaySecs = 0;
296 }
297 } else {
298 mDisplaySecs = 0;
299 }
300
301 char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
302 if (displayFmtEnv != NULL) {
303 mDisplayFmt = FormatFromString(displayFmtEnv);
304 } else {
305 mDisplayFmt = TEST_DISPLAY_FORMAT;
306 }
307
308 char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
309 if (displayWidthEnv != NULL) {
310 mDisplayW = atoi(displayWidthEnv);
311 if (mDisplayW < 0) {
312 mDisplayW = 0;
313 }
314 } else {
315 mDisplayW = TEST_DISPLAY_WIDTH;
316 }
317
318 char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
319 if (displayHeightEnv != NULL) {
320 mDisplayH = atoi(displayHeightEnv);
321 if (mDisplayH < 0) {
322 mDisplayH = 0;
323 }
324 } else {
325 mDisplayH = TEST_DISPLAY_HEIGHT;
326 }
Igor Murashkin53765732013-02-20 17:41:57 -0800327 }
328
Igor Murashkin39f79f72013-01-30 10:14:24 -0800329 static void SetUpTestCase() {
330 // Binder Thread Pool Initialization
Igor Murashkin53765732013-02-20 17:41:57 -0800331 mTestThread = new ProCameraTestThread();
332 mTestThread->run("ProCameraTestThread");
Igor Murashkin39f79f72013-01-30 10:14:24 -0800333 }
Igor Murashkin53765732013-02-20 17:41:57 -0800334
Igor Murashkin39f79f72013-01-30 10:14:24 -0800335 virtual void SetUp() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800336 mCamera = ProCamera::connect(CAMERA_ID);
337 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin53765732013-02-20 17:41:57 -0800338
339 mListener = new ProCameraTestListener();
340 mCamera->setListener(mListener);
Igor Murashkin634a5152013-02-20 17:15:11 -0800341 }
342
343 virtual void TearDown() {
344 ASSERT_NE((void*)NULL, mCamera.get());
345 mCamera->disconnect();
346 }
347
348protected:
349 sp<ProCamera> mCamera;
Igor Murashkin53765732013-02-20 17:41:57 -0800350 sp<ProCameraTestListener> mListener;
351
Igor Murashkin39f79f72013-01-30 10:14:24 -0800352 static sp<Thread> mTestThread;
Igor Murashkin53765732013-02-20 17:41:57 -0800353
Igor Murashkin68506fd2013-02-20 17:57:31 -0800354 int mDisplaySecs;
Igor Murashkindcb07d52013-02-21 14:18:10 -0800355 int mDisplayFmt;
356 int mDisplayW;
357 int mDisplayH;
358
Igor Murashkin68506fd2013-02-20 17:57:31 -0800359 sp<SurfaceComposerClient> mComposerClient;
360 sp<SurfaceControl> mSurfaceControl;
361
Igor Murashkin5835cc42013-02-20 19:29:53 -0800362 sp<SurfaceComposerClient> mDepthComposerClient;
363 sp<SurfaceControl> mDepthSurfaceControl;
364
Igor Murashkin68506fd2013-02-20 17:57:31 -0800365 int getSurfaceWidth() {
366 return 512;
367 }
368 int getSurfaceHeight() {
369 return 512;
370 }
371
372 void createOnScreenSurface(sp<Surface>& surface) {
373 mComposerClient = new SurfaceComposerClient;
374 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
375
376 mSurfaceControl = mComposerClient->createSurface(
377 String8("ProCameraTest StreamingImage Surface"),
378 getSurfaceWidth(), getSurfaceHeight(),
379 PIXEL_FORMAT_RGB_888, 0);
380
Igor Murashkindcb07d52013-02-21 14:18:10 -0800381 mSurfaceControl->setPosition(0, 0);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800382
Igor Murashkin68506fd2013-02-20 17:57:31 -0800383 ASSERT_TRUE(mSurfaceControl != NULL);
384 ASSERT_TRUE(mSurfaceControl->isValid());
385
386 SurfaceComposerClient::openGlobalTransaction();
387 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
388 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
389 SurfaceComposerClient::closeGlobalTransaction();
390
391 sp<ANativeWindow> window = mSurfaceControl->getSurface();
392 surface = mSurfaceControl->getSurface();
393
394 ASSERT_NE((void*)NULL, surface.get());
395 }
396
Igor Murashkin5835cc42013-02-20 19:29:53 -0800397 void createDepthOnScreenSurface(sp<Surface>& surface) {
398 mDepthComposerClient = new SurfaceComposerClient;
399 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
400
401 mDepthSurfaceControl = mDepthComposerClient->createSurface(
402 String8("ProCameraTest StreamingImage Surface"),
403 getSurfaceWidth(), getSurfaceHeight(),
404 PIXEL_FORMAT_RGB_888, 0);
405
406 mDepthSurfaceControl->setPosition(640, 0);
407
408 ASSERT_TRUE(mDepthSurfaceControl != NULL);
409 ASSERT_TRUE(mDepthSurfaceControl->isValid());
410
411 SurfaceComposerClient::openGlobalTransaction();
412 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
413 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
414 SurfaceComposerClient::closeGlobalTransaction();
415
416 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
417 surface = mDepthSurfaceControl->getSurface();
418
419 ASSERT_NE((void*)NULL, surface.get());
420 }
421
Igor Murashkin7b33a742013-02-21 13:49:26 -0800422 template <typename T>
Igor Murashkindcb07d52013-02-21 14:18:10 -0800423 static bool ExistsItem(T needle, T* array, size_t count) {
424 if (!array) {
425 return false;
426 }
427
Igor Murashkina140a6e2013-02-21 14:45:03 -0800428 for (size_t i = 0; i < count; ++i) {
Igor Murashkin7b33a742013-02-21 13:49:26 -0800429 if (array[i] == needle) {
430 return true;
431 }
432 }
433 return false;
434 }
435
Igor Murashkindcb07d52013-02-21 14:18:10 -0800436
437 static int FormatFromString(const char* str) {
438 std::string s(str);
439
440#define CMP_STR(x, y) \
441 if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
442#define CMP_STR_SAME(x) CMP_STR(x, x)
443
444 CMP_STR_SAME( Y16);
445 CMP_STR_SAME( Y8);
446 CMP_STR_SAME( YV12);
447 CMP_STR(NV16, YCbCr_422_SP);
448 CMP_STR(NV21, YCrCb_420_SP);
449 CMP_STR(YUY2, YCbCr_422_I);
450 CMP_STR(RAW, RAW_SENSOR);
451 CMP_STR(RGBA, RGBA_8888);
452
453 std::cerr << "Unknown format string " << str << std::endl;
454 return -1;
455
456 }
457
458 /**
459 * Creating a streaming request for these output streams from a template,
460 * and submit it
461 */
Igor Murashkina140a6e2013-02-21 14:45:03 -0800462 void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800463
464 ASSERT_NE((void*)NULL, streamIds);
Igor Murashkina140a6e2013-02-21 14:45:03 -0800465 ASSERT_LT(0u, count);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800466
467 camera_metadata_t *requestTmp = NULL;
468 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
469 /*out*/&requestTmp));
470 ASSERT_NE((void*)NULL, requestTmp);
471 CameraMetadata request(requestTmp);
472
473 // set the output streams. default is empty
474
475 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
476 request.update(tag, streamIds, count);
477
478 requestTmp = request.release();
Igor Murashkina140a6e2013-02-21 14:45:03 -0800479
480 if (requestCount < 0) {
481 EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
482 } else {
483 for (int i = 0; i < requestCount; ++i) {
484 EXPECT_OK(mCamera->submitRequest(requestTmp,
485 /*streaming*/false));
486 }
487 }
Igor Murashkindcb07d52013-02-21 14:18:10 -0800488 request.acquire(requestTmp);
489 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800490};
491
Igor Murashkin39f79f72013-01-30 10:14:24 -0800492sp<Thread> ProCameraTest::mTestThread;
493
Igor Murashkin7b33a742013-02-21 13:49:26 -0800494TEST_F(ProCameraTest, AvailableFormats) {
495 if (HasFatalFailure()) {
496 return;
497 }
498
Igor Murashkindcb07d52013-02-21 14:18:10 -0800499 CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
500 ASSERT_FALSE(staticInfo.isEmpty());
Igor Murashkin7b33a742013-02-21 13:49:26 -0800501
Igor Murashkin7b33a742013-02-21 13:49:26 -0800502 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800503 EXPECT_TRUE(staticInfo.exists(tag));
504 camera_metadata_entry_t entry = staticInfo.find(tag);
Igor Murashkin7b33a742013-02-21 13:49:26 -0800505
Igor Murashkindcb07d52013-02-21 14:18:10 -0800506 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800507 entry.data.i32, entry.count));
Igor Murashkindcb07d52013-02-21 14:18:10 -0800508 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800509 entry.data.i32, entry.count));
Igor Murashkin7b33a742013-02-21 13:49:26 -0800510}
511
Igor Murashkin39f79f72013-01-30 10:14:24 -0800512// test around exclusiveTryLock (immediate locking)
Igor Murashkin53765732013-02-20 17:41:57 -0800513TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800514
515 if (HasFatalFailure()) {
516 return;
517 }
518
Igor Murashkina91537e2013-02-21 12:02:29 -0800519 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
520 ProEvent_Mask(STOLEN) |
521 ProEvent_Mask(RELEASED));
522
Igor Murashkin53765732013-02-20 17:41:57 -0800523 EXPECT_FALSE(mCamera->hasExclusiveLock());
524 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin39f79f72013-01-30 10:14:24 -0800525 // at this point we definitely have the lock
526
527 EXPECT_EQ(OK, mListener->WaitForEvent());
528 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
529
530 EXPECT_TRUE(mCamera->hasExclusiveLock());
531 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
532
533 EXPECT_EQ(OK, mListener->WaitForEvent());
534 EXPECT_EQ(RELEASED, mListener->ReadEvent());
535
536 EXPECT_FALSE(mCamera->hasExclusiveLock());
537}
538
539// test around exclusiveLock (locking at some future point in time)
540TEST_F(ProCameraTest, LockingAsynchronous) {
541
542 if (HasFatalFailure()) {
543 return;
544 }
545
Igor Murashkina91537e2013-02-21 12:02:29 -0800546
547 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
548 ProEvent_Mask(STOLEN) |
549 ProEvent_Mask(RELEASED));
550
Igor Murashkin39f79f72013-01-30 10:14:24 -0800551 // TODO: Add another procamera that has a lock here.
552 // then we can be test that the lock wont immediately be acquired
553
554 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkina91537e2013-02-21 12:02:29 -0800555 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
556 // at this point we definitely have the lock
Igor Murashkin53765732013-02-20 17:41:57 -0800557
558 EXPECT_EQ(OK, mListener->WaitForEvent());
559 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
560
561 EXPECT_TRUE(mCamera->hasExclusiveLock());
562 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
563
564 EXPECT_EQ(OK, mListener->WaitForEvent());
565 EXPECT_EQ(RELEASED, mListener->ReadEvent());
566
567 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkin634a5152013-02-20 17:15:11 -0800568}
569
Igor Murashkin68506fd2013-02-20 17:57:31 -0800570// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800571TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800572 if (HasFatalFailure()) {
573 return;
574 }
Igor Murashkin68506fd2013-02-20 17:57:31 -0800575
Igor Murashkindcb07d52013-02-21 14:18:10 -0800576 sp<Surface> surface;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800577 if (mDisplaySecs > 0) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800578 createOnScreenSurface(/*out*/surface);
579 }
580 else {
581 dout << "Skipping, will not render to screen" << std::endl;
582 return;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800583 }
Igor Murashkin5835cc42013-02-20 19:29:53 -0800584
585 int depthStreamId = -1;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800586
Igor Murashkinbfc99152013-02-27 12:55:20 -0800587 sp<ServiceListener> listener = new ServiceListener();
588 EXPECT_OK(ProCamera::addServiceListener(listener));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800589
Igor Murashkincba2c162013-03-20 15:56:31 -0700590 ServiceListener::Status currentStatus;
591
592 // when subscribing a new listener,
593 // we immediately get a callback to the current status
594 while (listener->waitForStatusChange(/*out*/currentStatus) != OK);
595 EXPECT_EQ(ServiceListener::STATUS_PRESENT, currentStatus);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800596
Igor Murashkinbfc99152013-02-27 12:55:20 -0800597 dout << "Will now stream and resume infinitely..." << std::endl;
598 while (true) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800599
Igor Murashkincba2c162013-03-20 15:56:31 -0700600 if (currentStatus == ServiceListener::STATUS_PRESENT) {
Igor Murashkinbfc99152013-02-27 12:55:20 -0800601
Igor Murashkincba2c162013-03-20 15:56:31 -0700602 ASSERT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
Igor Murashkinbfc99152013-02-27 12:55:20 -0800603 surface,
604 &depthStreamId));
605 EXPECT_NE(-1, depthStreamId);
606
607 EXPECT_OK(mCamera->exclusiveTryLock());
608
609 uint8_t streams[] = { depthStreamId };
610 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
611 streams,
612 /*count*/1));
613 }
614
615 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
616
617 // TODO: maybe check for getch every once in a while?
618 while (listener->waitForStatusChange(/*out*/stat) != OK);
619
620 if (currentStatus != stat) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700621 if (stat == ServiceListener::STATUS_PRESENT) {
Igor Murashkinbfc99152013-02-27 12:55:20 -0800622 dout << "Reconnecting to camera" << std::endl;
623 mCamera = ProCamera::connect(CAMERA_ID);
624 } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
625 dout << "Disconnecting from camera" << std::endl;
626 mCamera->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700627 } else if (stat == ServiceListener::STATUS_NOT_PRESENT) {
628 dout << "Camera unplugged" << std::endl;
629 mCamera = NULL;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800630 } else {
631 dout << "Unknown status change "
632 << std::hex << stat << std::endl;
633 }
634
635 currentStatus = stat;
636 }
637 }
638
639 EXPECT_OK(ProCamera::removeServiceListener(listener));
Igor Murashkindcb07d52013-02-21 14:18:10 -0800640 EXPECT_OK(mCamera->deleteStream(depthStreamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800641 EXPECT_OK(mCamera->exclusiveUnlock());
642}
643
Igor Murashkineb72e172013-02-21 11:43:14 -0800644// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800645TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
Igor Murashkineb72e172013-02-21 11:43:14 -0800646 if (HasFatalFailure()) {
647 return;
648 }
Igor Murashkineb72e172013-02-21 11:43:14 -0800649 sp<Surface> surface;
650 sp<Surface> depthSurface;
651 if (mDisplaySecs > 0) {
652 createOnScreenSurface(/*out*/surface);
653 createDepthOnScreenSurface(/*out*/depthSurface);
654 }
655
656 int streamId = -1;
657 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
658 TEST_FORMAT_MAIN, surface, &streamId));
659 EXPECT_NE(-1, streamId);
660
661 int depthStreamId = -1;
662 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
663 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
664 EXPECT_NE(-1, depthStreamId);
665
666 EXPECT_OK(mCamera->exclusiveTryLock());
667 /*
668 */
669 /* iterate in a loop submitting requests every frame.
670 * what kind of requests doesnt really matter, just whatever.
671 */
672
673 // it would probably be better to use CameraMetadata from camera service.
674 camera_metadata_t *request = NULL;
675 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
676 /*out*/&request));
677 EXPECT_NE((void*)NULL, request);
678
679 /*FIXME: dont need this later, at which point the above should become an
680 ASSERT_NE*/
681 if(request == NULL) request = allocate_camera_metadata(10, 100);
682
683 // set the output streams to just this stream ID
684
685 // wow what a verbose API.
686 uint8_t allStreams[] = { streamId, depthStreamId };
687 // IMPORTANT. bad things will happen if its not a uint8.
688 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
689 camera_metadata_entry_t entry;
690 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
691 int find = find_camera_metadata_entry(request, tag, &entry);
692 if (find == -ENOENT) {
693 if (add_camera_metadata_entry(request, tag, &allStreams,
694 /*data_count*/streamCount) != OK) {
695 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
696 ASSERT_OK(append_camera_metadata(tmp, request));
697 free_camera_metadata(request);
698 request = tmp;
699
700 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
701 /*data_count*/streamCount));
702 }
703 } else {
704 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
705 &allStreams, /*data_count*/streamCount, &entry));
706 }
707
708 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
709
710 dout << "will sleep now for " << mDisplaySecs << std::endl;
711 sleep(mDisplaySecs);
712
713 free_camera_metadata(request);
714
715 for (int i = 0; i < streamCount; ++i) {
716 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
717 }
718 EXPECT_OK(mCamera->exclusiveUnlock());
719}
720
721TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800722 if (HasFatalFailure()) {
723 return;
724 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800725
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800726 // FIXME: Note this test is broken because onBufferReceived was removed
Igor Murashkina91537e2013-02-21 12:02:29 -0800727 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
728
Igor Murashkin5835cc42013-02-20 19:29:53 -0800729 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800730 sp<CpuConsumer> consumer;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800731 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800732 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800733 EXPECT_NE(-1, streamId);
734
735 EXPECT_OK(mCamera->exclusiveTryLock());
736 EXPECT_EQ(OK, mListener->WaitForEvent());
737 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
738 /* iterate in a loop submitting requests every frame.
739 * what kind of requests doesnt really matter, just whatever.
740 */
741
742 // it would probably be better to use CameraMetadata from camera service.
743 camera_metadata_t *request = NULL;
744 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
745 /*out*/&request));
746 EXPECT_NE((void*)NULL, request);
747
748 /*FIXME: dont need this later, at which point the above should become an
749 ASSERT_NE*/
750 if(request == NULL) request = allocate_camera_metadata(10, 100);
751
752 // set the output streams to just this stream ID
753
754 uint8_t allStreams[] = { streamId };
755 camera_metadata_entry_t entry;
756 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
757 int find = find_camera_metadata_entry(request, tag, &entry);
758 if (find == -ENOENT) {
759 if (add_camera_metadata_entry(request, tag, &allStreams,
760 /*data_count*/1) != OK) {
761 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
762 ASSERT_OK(append_camera_metadata(tmp, request));
763 free_camera_metadata(request);
764 request = tmp;
765
766 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
767 /*data_count*/1));
768 }
769 } else {
770 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
771 &allStreams, /*data_count*/1, &entry));
772 }
773
774 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
775
776 // Consume a couple of frames
777 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
778 EXPECT_EQ(OK, mListener->WaitForEvent());
779 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
780 }
781
782 // Done: clean up
783 free_camera_metadata(request);
784 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800785 EXPECT_OK(mCamera->exclusiveUnlock());
786}
787
Igor Murashkineb72e172013-02-21 11:43:14 -0800788TEST_F(ProCameraTest, CpuConsumerDual) {
789 if (HasFatalFailure()) {
790 return;
791 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800792
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800793 // FIXME: Note this test is broken because onBufferReceived was removed
Igor Murashkina91537e2013-02-21 12:02:29 -0800794 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
795
Igor Murashkineb72e172013-02-21 11:43:14 -0800796 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800797 sp<CpuConsumer> consumer;
Igor Murashkineb72e172013-02-21 11:43:14 -0800798 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800799 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800800 EXPECT_NE(-1, streamId);
801
802 int depthStreamId = -1;
803 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800804 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800805 EXPECT_NE(-1, depthStreamId);
806
807 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkineb72e172013-02-21 11:43:14 -0800808 /*
809 */
810 /* iterate in a loop submitting requests every frame.
811 * what kind of requests doesnt really matter, just whatever.
812 */
813
814 // it would probably be better to use CameraMetadata from camera service.
815 camera_metadata_t *request = NULL;
816 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
817 /*out*/&request));
818 EXPECT_NE((void*)NULL, request);
819
820 if(request == NULL) request = allocate_camera_metadata(10, 100);
821
822 // set the output streams to just this stream ID
823
824 // wow what a verbose API.
825 uint8_t allStreams[] = { streamId, depthStreamId };
826 size_t streamCount = 2;
827 camera_metadata_entry_t entry;
828 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
829 int find = find_camera_metadata_entry(request, tag, &entry);
830 if (find == -ENOENT) {
831 if (add_camera_metadata_entry(request, tag, &allStreams,
832 /*data_count*/streamCount) != OK) {
833 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
834 ASSERT_OK(append_camera_metadata(tmp, request));
835 free_camera_metadata(request);
836 request = tmp;
837
838 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
839 /*data_count*/streamCount));
840 }
841 } else {
842 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
843 &allStreams, /*data_count*/streamCount, &entry));
844 }
845
846 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
847
848 // Consume a couple of frames
849 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
850 // stream id 1
851 EXPECT_EQ(OK, mListener->WaitForEvent());
852 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
853
854 // stream id 2
855 EXPECT_EQ(OK, mListener->WaitForEvent());
856 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
857
858 //TODO: events should be a struct with some data like the stream id
859 }
860
861 // Done: clean up
862 free_camera_metadata(request);
863 EXPECT_OK(mCamera->deleteStream(streamId));
864 EXPECT_OK(mCamera->exclusiveUnlock());
865}
866
Igor Murashkina91537e2013-02-21 12:02:29 -0800867TEST_F(ProCameraTest, ResultReceiver) {
868 if (HasFatalFailure()) {
869 return;
870 }
871
872 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
873 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
874 // need to filter out events at read time
875
876 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800877 sp<CpuConsumer> consumer;
Igor Murashkina91537e2013-02-21 12:02:29 -0800878 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800879 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkina91537e2013-02-21 12:02:29 -0800880 EXPECT_NE(-1, streamId);
881
882 EXPECT_OK(mCamera->exclusiveTryLock());
883 /*
884 */
885 /* iterate in a loop submitting requests every frame.
886 * what kind of requests doesnt really matter, just whatever.
887 */
888
889 camera_metadata_t *request = NULL;
890 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
891 /*out*/&request));
892 EXPECT_NE((void*)NULL, request);
893
894 /*FIXME*/
895 if(request == NULL) request = allocate_camera_metadata(10, 100);
896
897 // set the output streams to just this stream ID
898
899 uint8_t allStreams[] = { streamId };
900 size_t streamCount = 1;
901 camera_metadata_entry_t entry;
902 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
903 int find = find_camera_metadata_entry(request, tag, &entry);
904 if (find == -ENOENT) {
905 if (add_camera_metadata_entry(request, tag, &allStreams,
906 /*data_count*/streamCount) != OK) {
907 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
908 ASSERT_OK(append_camera_metadata(tmp, request));
909 free_camera_metadata(request);
910 request = tmp;
911
912 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
913 /*data_count*/streamCount));
914 }
915 } else {
916 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
917 &allStreams, /*data_count*/streamCount, &entry));
918 }
919
920 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
921
922 // Consume a couple of results
923 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
924 EXPECT_EQ(OK, mListener->WaitForEvent());
925 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
926 }
927
928 // Done: clean up
929 free_camera_metadata(request);
930 EXPECT_OK(mCamera->deleteStream(streamId));
931 EXPECT_OK(mCamera->exclusiveUnlock());
932}
933
Igor Murashkina140a6e2013-02-21 14:45:03 -0800934TEST_F(ProCameraTest, WaitForResult) {
935 if (HasFatalFailure()) {
936 return;
937 }
938
939 int streamId = -1;
940 sp<CpuConsumer> consumer;
941 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
942 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
943 EXPECT_NE(-1, streamId);
944
945 EXPECT_OK(mCamera->exclusiveTryLock());
946
947 uint8_t streams[] = { streamId };
948 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
949
950 // Consume a couple of results
951 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
952 EXPECT_OK(mCamera->waitForFrameMetadata());
953 CameraMetadata meta = mCamera->consumeFrameMetadata();
954 EXPECT_FALSE(meta.isEmpty());
955 }
956
957 // Done: clean up
958 consumer->abandon(); // since we didn't consume any of the buffers
959 EXPECT_OK(mCamera->deleteStream(streamId));
960 EXPECT_OK(mCamera->exclusiveUnlock());
961}
962
963TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
964 if (HasFatalFailure()) {
965 return;
966 }
967
968 int streamId = -1;
969 sp<CpuConsumer> consumer;
970 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
971 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
972 EXPECT_NE(-1, streamId);
973
974 EXPECT_OK(mCamera->exclusiveTryLock());
975
976 uint8_t streams[] = { streamId };
977 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
978 /*requests*/TEST_CPU_FRAME_COUNT));
979
980 // Consume a couple of results
981 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -0800982 EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));
Igor Murashkina140a6e2013-02-21 14:45:03 -0800983
984 CpuConsumer::LockedBuffer buf;
985 EXPECT_OK(consumer->lockNextBuffer(&buf));
986
987 dout << "Buffer synchronously received on streamId = " << streamId <<
988 ", dataPtr = " << (void*)buf.data <<
989 ", timestamp = " << buf.timestamp << std::endl;
990
991 EXPECT_OK(consumer->unlockBuffer(buf));
992 }
993
994 // Done: clean up
995 EXPECT_OK(mCamera->deleteStream(streamId));
996 EXPECT_OK(mCamera->exclusiveUnlock());
997}
998
999TEST_F(ProCameraTest, WaitForDualStreamBuffer) {
1000 if (HasFatalFailure()) {
1001 return;
1002 }
1003
1004 const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
1005
1006 // 15 fps
1007 int streamId = -1;
1008 sp<CpuConsumer> consumer;
1009 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1010 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1011 EXPECT_NE(-1, streamId);
1012
1013 // 30 fps
1014 int depthStreamId = -1;
1015 sp<CpuConsumer> depthConsumer;
1016 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
1017 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
1018 EXPECT_NE(-1, depthStreamId);
1019
1020 EXPECT_OK(mCamera->exclusiveTryLock());
1021
1022 uint8_t streams[] = { streamId, depthStreamId };
1023 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
1024 /*requests*/REQUEST_COUNT));
1025
Igor Murashkin47539182013-03-18 11:10:48 -07001026 int depthFrames = 0;
1027 int greyFrames = 0;
1028
Igor Murashkina140a6e2013-02-21 14:45:03 -08001029 // Consume two frames simultaneously. Unsynchronized by timestamps.
1030 for (int i = 0; i < REQUEST_COUNT; ++i) {
1031
1032 // Get the metadata
1033 EXPECT_OK(mCamera->waitForFrameMetadata());
1034 CameraMetadata meta = mCamera->consumeFrameMetadata();
1035 EXPECT_FALSE(meta.isEmpty());
1036
1037 // Get the buffers
1038
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001039 EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));
Igor Murashkina140a6e2013-02-21 14:45:03 -08001040
1041 /**
1042 * Guaranteed to be able to consume the depth frame,
1043 * since we waited on it.
1044 */
1045 CpuConsumer::LockedBuffer depthBuffer;
1046 EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
1047
1048 dout << "Depth Buffer synchronously received on streamId = " <<
1049 streamId <<
1050 ", dataPtr = " << (void*)depthBuffer.data <<
1051 ", timestamp = " << depthBuffer.timestamp << std::endl;
1052
1053 EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
1054
Igor Murashkin47539182013-03-18 11:10:48 -07001055 depthFrames++;
1056
Igor Murashkina140a6e2013-02-21 14:45:03 -08001057
1058 /** Consume Greyscale frames if there are any.
1059 * There may not be since it runs at half FPS */
1060 CpuConsumer::LockedBuffer greyBuffer;
1061 while (consumer->lockNextBuffer(&greyBuffer) == OK) {
1062
1063 dout << "GRAY Buffer synchronously received on streamId = " <<
1064 streamId <<
1065 ", dataPtr = " << (void*)greyBuffer.data <<
1066 ", timestamp = " << greyBuffer.timestamp << std::endl;
1067
1068 EXPECT_OK(consumer->unlockBuffer(greyBuffer));
Igor Murashkin47539182013-03-18 11:10:48 -07001069
1070 greyFrames++;
Igor Murashkina140a6e2013-02-21 14:45:03 -08001071 }
1072 }
1073
Igor Murashkin47539182013-03-18 11:10:48 -07001074 dout << "Done, summary: depth frames " << std::dec << depthFrames
1075 << ", grey frames " << std::dec << greyFrames << std::endl;
1076
Igor Murashkina140a6e2013-02-21 14:45:03 -08001077 // Done: clean up
1078 EXPECT_OK(mCamera->deleteStream(streamId));
1079 EXPECT_OK(mCamera->exclusiveUnlock());
1080}
1081
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001082TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001083 if (HasFatalFailure()) {
1084 return;
1085 }
Igor Murashkina140a6e2013-02-21 14:45:03 -08001086
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001087 const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1088
1089 int streamId = -1;
1090 sp<CpuConsumer> consumer;
1091 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001092 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1093 /*synchronousMode*/true, &consumer, &streamId));
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001094 EXPECT_NE(-1, streamId);
1095
1096 EXPECT_OK(mCamera->exclusiveTryLock());
1097
1098 uint8_t streams[] = { streamId };
1099 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1100 /*requests*/NUM_REQUESTS));
1101
1102 // Consume a couple of results
1103 for (int i = 0; i < NUM_REQUESTS; ++i) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001104 int numFrames;
1105 EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1106
1107 // Drop all but the newest framebuffer
1108 EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1109
1110 dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1111
1112 // Skip the counter ahead, don't try to consume these frames again
1113 i += numFrames-1;
1114
1115 // "Consume" the buffer
1116 CpuConsumer::LockedBuffer buf;
1117 EXPECT_OK(consumer->lockNextBuffer(&buf));
1118
1119 dout << "Buffer synchronously received on streamId = " << streamId <<
1120 ", dataPtr = " << (void*)buf.data <<
1121 ", timestamp = " << buf.timestamp << std::endl;
1122
Igor Murashkin3fa48912013-02-28 10:41:51 -08001123 // Process at 10fps, stream is at 15fps.
1124 // This means we will definitely fill up the buffer queue with
1125 // extra buffers and need to drop them.
1126 usleep(TEST_FRAME_PROCESSING_DELAY_US);
1127
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001128 EXPECT_OK(consumer->unlockBuffer(buf));
1129 }
1130
1131 // Done: clean up
1132 EXPECT_OK(mCamera->deleteStream(streamId));
1133 EXPECT_OK(mCamera->exclusiveUnlock());
1134}
Igor Murashkina140a6e2013-02-21 14:45:03 -08001135
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001136TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
1137 if (HasFatalFailure()) {
1138 return;
1139 }
1140
1141 const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1142
1143 int streamId = -1;
1144 sp<CpuConsumer> consumer;
1145 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1146 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1147 /*synchronousMode*/false, &consumer, &streamId));
1148 EXPECT_NE(-1, streamId);
1149
1150 EXPECT_OK(mCamera->exclusiveTryLock());
1151
1152 uint8_t streams[] = { streamId };
1153 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1154 /*requests*/NUM_REQUESTS));
1155
1156 // Consume a couple of results
1157 for (int i = 0; i < NUM_REQUESTS; ++i) {
1158 int numFrames;
1159 EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1160
1161 dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1162
1163 // Skip the counter ahead, don't try to consume these frames again
1164 i += numFrames-1;
1165
1166 // "Consume" the buffer
1167 CpuConsumer::LockedBuffer buf;
1168 EXPECT_OK(consumer->lockNextBuffer(&buf));
1169
1170 dout << "Buffer asynchronously received on streamId = " << streamId <<
1171 ", dataPtr = " << (void*)buf.data <<
1172 ", timestamp = " << buf.timestamp << std::endl;
1173
1174 // Process at 10fps, stream is at 15fps.
1175 // This means we will definitely fill up the buffer queue with
1176 // extra buffers and need to drop them.
1177 usleep(TEST_FRAME_PROCESSING_DELAY_US);
1178
1179 EXPECT_OK(consumer->unlockBuffer(buf));
1180 }
1181
1182 // Done: clean up
1183 EXPECT_OK(mCamera->deleteStream(streamId));
1184 EXPECT_OK(mCamera->exclusiveUnlock());
1185}
1186
Igor Murashkina140a6e2013-02-21 14:45:03 -08001187
1188
Igor Murashkinbfc99152013-02-27 12:55:20 -08001189//TODO: refactor into separate file
1190TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1191
1192 ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1193
1194 sp<ServiceListener> listener = new ServiceListener();
1195
1196 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1197 EXPECT_OK(ProCamera::addServiceListener(listener));
1198
1199 EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1200 EXPECT_OK(ProCamera::removeServiceListener(listener));
1201
1202 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1203}
1204
1205//TODO: refactor into separate file
1206TEST_F(ProCameraTest, ServiceListenersFunctional) {
1207
1208 sp<ServiceListener> listener = new ServiceListener();
1209
1210 EXPECT_OK(ProCamera::addServiceListener(listener));
1211
1212 sp<Camera> cam = Camera::connect(CAMERA_ID,
1213 /*clientPackageName*/String16(),
1214 -1);
1215 EXPECT_NE((void*)NULL, cam.get());
1216
1217 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1218 EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1219
1220 EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1221
1222 if (cam.get()) {
1223 cam->disconnect();
1224 }
1225
1226 EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
Igor Murashkincba2c162013-03-20 15:56:31 -07001227 EXPECT_EQ(ServiceListener::STATUS_PRESENT, stat);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001228
1229 EXPECT_OK(ProCamera::removeServiceListener(listener));
1230}
1231
1232
1233
Igor Murashkin634a5152013-02-20 17:15:11 -08001234}
1235}
1236}
1237}
1238