blob: 69b7f3c147241cea6c2c16ef7208502bcdd69eba [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
34
Igor Murashkin634a5152013-02-20 17:15:11 -080035namespace android {
36namespace camera2 {
37namespace tests {
38namespace client {
39
40#define CAMERA_ID 0
41#define TEST_DEBUGGING 0
42
Igor Murashkin68506fd2013-02-20 17:57:31 -080043#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
Igor Murashkin5835cc42013-02-20 19:29:53 -080044#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
45
Igor Murashkineb72e172013-02-21 11:43:14 -080046#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
Igor Murashkin5835cc42013-02-20 19:29:53 -080047#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
48
49#define TEST_CPU_FRAME_COUNT 2
50#define TEST_CPU_HEAP_COUNT 5
Igor Murashkin53765732013-02-20 17:41:57 -080051
Igor Murashkin634a5152013-02-20 17:15:11 -080052#if TEST_DEBUGGING
53#define dout std::cerr
54#else
55#define dout if (0) std::cerr
56#endif
57
Igor Murashkin39f79f72013-01-30 10:14:24 -080058#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
59#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
60
61class ProCameraTest;
62
Igor Murashkin5835cc42013-02-20 19:29:53 -080063enum ProEvent {
Igor Murashkin53765732013-02-20 17:41:57 -080064 UNKNOWN,
65 ACQUIRED,
66 RELEASED,
Igor Murashkin5835cc42013-02-20 19:29:53 -080067 STOLEN,
68 BUFFER_RECEIVED,
Igor Murashkina91537e2013-02-21 12:02:29 -080069 RESULT_RECEIVED,
Igor Murashkin53765732013-02-20 17:41:57 -080070};
71
Igor Murashkina91537e2013-02-21 12:02:29 -080072inline int ProEvent_Mask(ProEvent e) {
73 return (1 << static_cast<int>(e));
74}
75
Igor Murashkin5835cc42013-02-20 19:29:53 -080076typedef Vector<ProEvent> EventList;
Igor Murashkin53765732013-02-20 17:41:57 -080077
78class ProCameraTestThread : public Thread
79{
80public:
81 ProCameraTestThread() {
82 }
83
84 virtual bool threadLoop() {
85 mProc = ProcessState::self();
86 mProc->startThreadPool();
87
88 IPCThreadState *ptr = IPCThreadState::self();
89
Igor Murashkin53765732013-02-20 17:41:57 -080090 ptr->joinThreadPool();
Igor Murashkin53765732013-02-20 17:41:57 -080091
92 return false;
93 }
94
95 sp<ProcessState> mProc;
96};
97
98class ProCameraTestListener : public ProCameraListener {
99
100public:
Igor Murashkina91537e2013-02-21 12:02:29 -0800101 static const int EVENT_MASK_ALL = 0xFFFFFFFF;
102
103 ProCameraTestListener() {
104 mEventMask = EVENT_MASK_ALL;
105 }
106
Igor Murashkin53765732013-02-20 17:41:57 -0800107 status_t WaitForEvent() {
108 Mutex::Autolock cal(mConditionMutex);
109
110 {
111 Mutex::Autolock al(mListenerMutex);
112
Igor Murashkin5835cc42013-02-20 19:29:53 -0800113 if (mProEventList.size() > 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800114 return OK;
115 }
116 }
117
118 return mListenerCondition.waitRelative(mConditionMutex,
119 TEST_LISTENER_TIMEOUT);
120 }
121
122 /* Read events into out. Existing queue is flushed */
123 void ReadEvents(EventList& out) {
124 Mutex::Autolock al(mListenerMutex);
125
Igor Murashkin5835cc42013-02-20 19:29:53 -0800126 for (size_t i = 0; i < mProEventList.size(); ++i) {
127 out.push(mProEventList[i]);
Igor Murashkin53765732013-02-20 17:41:57 -0800128 }
129
Igor Murashkin5835cc42013-02-20 19:29:53 -0800130 mProEventList.clear();
Igor Murashkin53765732013-02-20 17:41:57 -0800131 }
132
133 /**
134 * Dequeue 1 event from the event queue.
135 * Returns UNKNOWN if queue is empty
136 */
Igor Murashkin5835cc42013-02-20 19:29:53 -0800137 ProEvent ReadEvent() {
Igor Murashkin53765732013-02-20 17:41:57 -0800138 Mutex::Autolock al(mListenerMutex);
139
Igor Murashkin5835cc42013-02-20 19:29:53 -0800140 if (mProEventList.size() == 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800141 return UNKNOWN;
142 }
143
Igor Murashkin5835cc42013-02-20 19:29:53 -0800144 ProEvent ev = mProEventList[0];
145 mProEventList.removeAt(0);
Igor Murashkin53765732013-02-20 17:41:57 -0800146
147 return ev;
148 }
149
Igor Murashkina91537e2013-02-21 12:02:29 -0800150 void SetEventMask(int eventMask) {
151 Mutex::Autolock al(mListenerMutex);
152 mEventMask = eventMask;
153 }
154
Igor Murashkin53765732013-02-20 17:41:57 -0800155private:
Igor Murashkin5835cc42013-02-20 19:29:53 -0800156 void QueueEvent(ProEvent ev) {
Igor Murashkina91537e2013-02-21 12:02:29 -0800157 bool eventAdded = false;
Igor Murashkin53765732013-02-20 17:41:57 -0800158 {
159 Mutex::Autolock al(mListenerMutex);
Igor Murashkina91537e2013-02-21 12:02:29 -0800160
161 if (ProEvent_Mask(ev) & mEventMask) {
162 mProEventList.push(ev);
163 eventAdded = true;
164 }
Igor Murashkin53765732013-02-20 17:41:57 -0800165 }
166
Igor Murashkina91537e2013-02-21 12:02:29 -0800167 if (eventAdded) {
168 mListenerCondition.broadcast();
169 }
Igor Murashkin53765732013-02-20 17:41:57 -0800170 }
171
172protected:
173
174 //////////////////////////////////////////////////
175 ///////// ProCameraListener //////////////////////
176 //////////////////////////////////////////////////
177
178
179 // Lock has been acquired. Write operations now available.
180 virtual void onLockAcquired() {
181 QueueEvent(ACQUIRED);
182 }
183 // Lock has been released with exclusiveUnlock
184 virtual void onLockReleased() {
185 QueueEvent(RELEASED);
186 }
187
188 // Lock has been stolen by another client.
189 virtual void onLockStolen() {
190 QueueEvent(STOLEN);
191 }
192
193 // Lock free.
194 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
195
196 dout << "Trigger notify: " << ext1 << " " << ext2
197 << " " << ext3 << std::endl;
198 }
199
Igor Murashkin5835cc42013-02-20 19:29:53 -0800200 virtual void onBufferReceived(int streamId,
201 const CpuConsumer::LockedBuffer& buf) {
202
203 dout << "Buffer received on streamId = " << streamId <<
204 ", dataPtr = " << (void*)buf.data << std::endl;
205
206 QueueEvent(BUFFER_RECEIVED);
207
208 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800209 virtual void onResultReceived(int32_t frameId,
210 camera_metadata* request) {
211 dout << "Result received frameId = " << frameId
212 << ", requestPtr = " << (void*)request << std::endl;
213 QueueEvent(RESULT_RECEIVED);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800214 free_camera_metadata(request);
215 }
216
Igor Murashkin53765732013-02-20 17:41:57 -0800217 // TODO: remove
218
219 virtual void notify(int32_t , int32_t , int32_t ) {}
220 virtual void postData(int32_t , const sp<IMemory>& ,
221 camera_frame_metadata_t *) {}
222 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
223
224
Igor Murashkin5835cc42013-02-20 19:29:53 -0800225 Vector<ProEvent> mProEventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800226 Mutex mListenerMutex;
227 Mutex mConditionMutex;
228 Condition mListenerCondition;
Igor Murashkina91537e2013-02-21 12:02:29 -0800229 int mEventMask;
Igor Murashkin53765732013-02-20 17:41:57 -0800230};
231
Igor Murashkin634a5152013-02-20 17:15:11 -0800232class ProCameraTest : public ::testing::Test {
233
Igor Murashkin53765732013-02-20 17:41:57 -0800234public:
235 ProCameraTest() {
236 }
237
Igor Murashkin39f79f72013-01-30 10:14:24 -0800238 static void SetUpTestCase() {
239 // Binder Thread Pool Initialization
Igor Murashkin53765732013-02-20 17:41:57 -0800240 mTestThread = new ProCameraTestThread();
241 mTestThread->run("ProCameraTestThread");
Igor Murashkin39f79f72013-01-30 10:14:24 -0800242 }
Igor Murashkin53765732013-02-20 17:41:57 -0800243
Igor Murashkin39f79f72013-01-30 10:14:24 -0800244 virtual void SetUp() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800245 mCamera = ProCamera::connect(CAMERA_ID);
246 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin53765732013-02-20 17:41:57 -0800247
248 mListener = new ProCameraTestListener();
249 mCamera->setListener(mListener);
Igor Murashkin634a5152013-02-20 17:15:11 -0800250 }
251
252 virtual void TearDown() {
253 ASSERT_NE((void*)NULL, mCamera.get());
254 mCamera->disconnect();
255 }
256
257protected:
258 sp<ProCamera> mCamera;
Igor Murashkin53765732013-02-20 17:41:57 -0800259 sp<ProCameraTestListener> mListener;
260
Igor Murashkin39f79f72013-01-30 10:14:24 -0800261 static sp<Thread> mTestThread;
Igor Murashkin53765732013-02-20 17:41:57 -0800262
Igor Murashkin68506fd2013-02-20 17:57:31 -0800263 int mDisplaySecs;
264 sp<SurfaceComposerClient> mComposerClient;
265 sp<SurfaceControl> mSurfaceControl;
266
Igor Murashkin5835cc42013-02-20 19:29:53 -0800267 sp<SurfaceComposerClient> mDepthComposerClient;
268 sp<SurfaceControl> mDepthSurfaceControl;
269
Igor Murashkin68506fd2013-02-20 17:57:31 -0800270 int getSurfaceWidth() {
271 return 512;
272 }
273 int getSurfaceHeight() {
274 return 512;
275 }
276
277 void createOnScreenSurface(sp<Surface>& surface) {
278 mComposerClient = new SurfaceComposerClient;
279 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
280
281 mSurfaceControl = mComposerClient->createSurface(
282 String8("ProCameraTest StreamingImage Surface"),
283 getSurfaceWidth(), getSurfaceHeight(),
284 PIXEL_FORMAT_RGB_888, 0);
285
Igor Murashkin5835cc42013-02-20 19:29:53 -0800286 mSurfaceControl->setPosition(640, 0);
287
Igor Murashkin68506fd2013-02-20 17:57:31 -0800288 ASSERT_TRUE(mSurfaceControl != NULL);
289 ASSERT_TRUE(mSurfaceControl->isValid());
290
291 SurfaceComposerClient::openGlobalTransaction();
292 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
293 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
294 SurfaceComposerClient::closeGlobalTransaction();
295
296 sp<ANativeWindow> window = mSurfaceControl->getSurface();
297 surface = mSurfaceControl->getSurface();
298
299 ASSERT_NE((void*)NULL, surface.get());
300 }
301
Igor Murashkin5835cc42013-02-20 19:29:53 -0800302 void createDepthOnScreenSurface(sp<Surface>& surface) {
303 mDepthComposerClient = new SurfaceComposerClient;
304 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
305
306 mDepthSurfaceControl = mDepthComposerClient->createSurface(
307 String8("ProCameraTest StreamingImage Surface"),
308 getSurfaceWidth(), getSurfaceHeight(),
309 PIXEL_FORMAT_RGB_888, 0);
310
311 mDepthSurfaceControl->setPosition(640, 0);
312
313 ASSERT_TRUE(mDepthSurfaceControl != NULL);
314 ASSERT_TRUE(mDepthSurfaceControl->isValid());
315
316 SurfaceComposerClient::openGlobalTransaction();
317 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
318 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
319 SurfaceComposerClient::closeGlobalTransaction();
320
321 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
322 surface = mDepthSurfaceControl->getSurface();
323
324 ASSERT_NE((void*)NULL, surface.get());
325 }
326
Igor Murashkin7b33a742013-02-21 13:49:26 -0800327 template <typename T>
328 static bool FindItem(T needle, T* array, size_t count) {
329 for (int i = 0; i < count; ++i) {
330 if (array[i] == needle) {
331 return true;
332 }
333 }
334 return false;
335 }
336
Igor Murashkin634a5152013-02-20 17:15:11 -0800337};
338
Igor Murashkin39f79f72013-01-30 10:14:24 -0800339sp<Thread> ProCameraTest::mTestThread;
340
Igor Murashkin7b33a742013-02-21 13:49:26 -0800341TEST_F(ProCameraTest, AvailableFormats) {
342 if (HasFatalFailure()) {
343 return;
344 }
345
346 camera_metadata_t* info = mCamera->getCameraInfo(CAMERA_ID);
347 ASSERT_NE((void*)NULL, info);
348
349 camera_metadata_entry_t entry;
350 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
351 EXPECT_EQ(OK, find_camera_metadata_entry(info, tag, &entry));
352
353 EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
354 entry.data.i32, entry.count));
355 EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
356 entry.data.i32, entry.count));
357
358 free_camera_metadata(info);
359}
360
Igor Murashkin39f79f72013-01-30 10:14:24 -0800361// test around exclusiveTryLock (immediate locking)
Igor Murashkin53765732013-02-20 17:41:57 -0800362TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800363
364 if (HasFatalFailure()) {
365 return;
366 }
367
Igor Murashkina91537e2013-02-21 12:02:29 -0800368 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
369 ProEvent_Mask(STOLEN) |
370 ProEvent_Mask(RELEASED));
371
Igor Murashkin53765732013-02-20 17:41:57 -0800372 EXPECT_FALSE(mCamera->hasExclusiveLock());
373 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin39f79f72013-01-30 10:14:24 -0800374 // at this point we definitely have the lock
375
376 EXPECT_EQ(OK, mListener->WaitForEvent());
377 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
378
379 EXPECT_TRUE(mCamera->hasExclusiveLock());
380 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
381
382 EXPECT_EQ(OK, mListener->WaitForEvent());
383 EXPECT_EQ(RELEASED, mListener->ReadEvent());
384
385 EXPECT_FALSE(mCamera->hasExclusiveLock());
386}
387
388// test around exclusiveLock (locking at some future point in time)
389TEST_F(ProCameraTest, LockingAsynchronous) {
390
391 if (HasFatalFailure()) {
392 return;
393 }
394
Igor Murashkina91537e2013-02-21 12:02:29 -0800395
396 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
397 ProEvent_Mask(STOLEN) |
398 ProEvent_Mask(RELEASED));
399
Igor Murashkin39f79f72013-01-30 10:14:24 -0800400 // TODO: Add another procamera that has a lock here.
401 // then we can be test that the lock wont immediately be acquired
402
403 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkina91537e2013-02-21 12:02:29 -0800404 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
405 // at this point we definitely have the lock
Igor Murashkin53765732013-02-20 17:41:57 -0800406
407 EXPECT_EQ(OK, mListener->WaitForEvent());
408 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
409
410 EXPECT_TRUE(mCamera->hasExclusiveLock());
411 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
412
413 EXPECT_EQ(OK, mListener->WaitForEvent());
414 EXPECT_EQ(RELEASED, mListener->ReadEvent());
415
416 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkin634a5152013-02-20 17:15:11 -0800417}
418
Igor Murashkin68506fd2013-02-20 17:57:31 -0800419// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800420TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800421 if (HasFatalFailure()) {
422 return;
423 }
424 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
425 if (displaySecsEnv != NULL) {
426 mDisplaySecs = atoi(displaySecsEnv);
427 if (mDisplaySecs < 0) {
428 mDisplaySecs = 0;
429 }
430 } else {
431 mDisplaySecs = 0;
432 }
433
Igor Murashkin5835cc42013-02-20 19:29:53 -0800434 sp<Surface> depthSurface;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800435 if (mDisplaySecs > 0) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800436 createDepthOnScreenSurface(/*out*/depthSurface);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800437 }
Igor Murashkin5835cc42013-02-20 19:29:53 -0800438
439 int depthStreamId = -1;
440 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
441 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
442 EXPECT_NE(-1, depthStreamId);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800443
444 EXPECT_OK(mCamera->exclusiveTryLock());
445 /* iterate in a loop submitting requests every frame.
446 * what kind of requests doesnt really matter, just whatever.
447 */
448
449 // it would probably be better to use CameraMetadata from camera service.
450 camera_metadata_t *request = NULL;
451 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
452 /*out*/&request));
453 EXPECT_NE((void*)NULL, request);
454
455 /* FIXME: dont need this later, at which point the above should become an
456 ASSERT_NE*/
457 if(request == NULL) request = allocate_camera_metadata(10, 100);
458
459 // set the output streams to just this stream ID
460
461 // wow what a verbose API.
462 // i would give a loaf of bread for
463 // metadata->updateOrInsert(keys.request.output.streams, streamId);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800464 uint8_t allStreams[] = { depthStreamId };
465 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
466
Igor Murashkin68506fd2013-02-20 17:57:31 -0800467 camera_metadata_entry_t entry;
468 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
469 int find = find_camera_metadata_entry(request, tag, &entry);
470 if (find == -ENOENT) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800471 if (add_camera_metadata_entry(request, tag, &allStreams,
472 /*data_count*/streamCount) != OK) {
Igor Murashkin985fd302013-02-20 18:24:43 -0800473 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
474 ASSERT_OK(append_camera_metadata(tmp, request));
475 free_camera_metadata(request);
476 request = tmp;
477
Igor Murashkin5835cc42013-02-20 19:29:53 -0800478 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
479 /*data_count*/streamCount));
Igor Murashkin985fd302013-02-20 18:24:43 -0800480 }
Igor Murashkin68506fd2013-02-20 17:57:31 -0800481 } else {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800482 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
483 &allStreams, /*data_count*/streamCount, &entry));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800484 }
485
486 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
487
Igor Murashkin985fd302013-02-20 18:24:43 -0800488 dout << "will sleep now for " << mDisplaySecs << std::endl;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800489 sleep(mDisplaySecs);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800490
491 free_camera_metadata(request);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800492
493 for (int i = 0; i < streamCount; ++i) {
494 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
495 }
496 EXPECT_OK(mCamera->exclusiveUnlock());
497}
498
Igor Murashkineb72e172013-02-21 11:43:14 -0800499// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800500TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
Igor Murashkineb72e172013-02-21 11:43:14 -0800501 if (HasFatalFailure()) {
502 return;
503 }
504 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
505 if (displaySecsEnv != NULL) {
506 mDisplaySecs = atoi(displaySecsEnv);
507 if (mDisplaySecs < 0) {
508 mDisplaySecs = 0;
509 }
510 } else {
511 mDisplaySecs = 0;
512 }
513
514 sp<Surface> surface;
515 sp<Surface> depthSurface;
516 if (mDisplaySecs > 0) {
517 createOnScreenSurface(/*out*/surface);
518 createDepthOnScreenSurface(/*out*/depthSurface);
519 }
520
521 int streamId = -1;
522 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
523 TEST_FORMAT_MAIN, surface, &streamId));
524 EXPECT_NE(-1, streamId);
525
526 int depthStreamId = -1;
527 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
528 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
529 EXPECT_NE(-1, depthStreamId);
530
531 EXPECT_OK(mCamera->exclusiveTryLock());
532 /*
533 */
534 /* iterate in a loop submitting requests every frame.
535 * what kind of requests doesnt really matter, just whatever.
536 */
537
538 // it would probably be better to use CameraMetadata from camera service.
539 camera_metadata_t *request = NULL;
540 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
541 /*out*/&request));
542 EXPECT_NE((void*)NULL, request);
543
544 /*FIXME: dont need this later, at which point the above should become an
545 ASSERT_NE*/
546 if(request == NULL) request = allocate_camera_metadata(10, 100);
547
548 // set the output streams to just this stream ID
549
550 // wow what a verbose API.
551 uint8_t allStreams[] = { streamId, depthStreamId };
552 // IMPORTANT. bad things will happen if its not a uint8.
553 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
554 camera_metadata_entry_t entry;
555 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
556 int find = find_camera_metadata_entry(request, tag, &entry);
557 if (find == -ENOENT) {
558 if (add_camera_metadata_entry(request, tag, &allStreams,
559 /*data_count*/streamCount) != OK) {
560 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
561 ASSERT_OK(append_camera_metadata(tmp, request));
562 free_camera_metadata(request);
563 request = tmp;
564
565 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
566 /*data_count*/streamCount));
567 }
568 } else {
569 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
570 &allStreams, /*data_count*/streamCount, &entry));
571 }
572
573 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
574
575 dout << "will sleep now for " << mDisplaySecs << std::endl;
576 sleep(mDisplaySecs);
577
578 free_camera_metadata(request);
579
580 for (int i = 0; i < streamCount; ++i) {
581 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
582 }
583 EXPECT_OK(mCamera->exclusiveUnlock());
584}
585
586TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800587 if (HasFatalFailure()) {
588 return;
589 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800590
591 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
592
Igor Murashkin5835cc42013-02-20 19:29:53 -0800593 int streamId = -1;
594 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
595 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &streamId));
596 EXPECT_NE(-1, streamId);
597
598 EXPECT_OK(mCamera->exclusiveTryLock());
599 EXPECT_EQ(OK, mListener->WaitForEvent());
600 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
601 /* iterate in a loop submitting requests every frame.
602 * what kind of requests doesnt really matter, just whatever.
603 */
604
605 // it would probably be better to use CameraMetadata from camera service.
606 camera_metadata_t *request = NULL;
607 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
608 /*out*/&request));
609 EXPECT_NE((void*)NULL, request);
610
611 /*FIXME: dont need this later, at which point the above should become an
612 ASSERT_NE*/
613 if(request == NULL) request = allocate_camera_metadata(10, 100);
614
615 // set the output streams to just this stream ID
616
617 uint8_t allStreams[] = { streamId };
618 camera_metadata_entry_t entry;
619 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
620 int find = find_camera_metadata_entry(request, tag, &entry);
621 if (find == -ENOENT) {
622 if (add_camera_metadata_entry(request, tag, &allStreams,
623 /*data_count*/1) != OK) {
624 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
625 ASSERT_OK(append_camera_metadata(tmp, request));
626 free_camera_metadata(request);
627 request = tmp;
628
629 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
630 /*data_count*/1));
631 }
632 } else {
633 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
634 &allStreams, /*data_count*/1, &entry));
635 }
636
637 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
638
639 // Consume a couple of frames
640 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
641 EXPECT_EQ(OK, mListener->WaitForEvent());
642 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
643 }
644
645 // Done: clean up
646 free_camera_metadata(request);
647 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800648 EXPECT_OK(mCamera->exclusiveUnlock());
649}
650
Igor Murashkineb72e172013-02-21 11:43:14 -0800651TEST_F(ProCameraTest, CpuConsumerDual) {
652 if (HasFatalFailure()) {
653 return;
654 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800655
656 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
657
Igor Murashkineb72e172013-02-21 11:43:14 -0800658 int streamId = -1;
659 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
660 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId));
661 EXPECT_NE(-1, streamId);
662
663 int depthStreamId = -1;
664 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
665 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthStreamId));
666 EXPECT_NE(-1, depthStreamId);
667
668 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkineb72e172013-02-21 11:43:14 -0800669 /*
670 */
671 /* iterate in a loop submitting requests every frame.
672 * what kind of requests doesnt really matter, just whatever.
673 */
674
675 // it would probably be better to use CameraMetadata from camera service.
676 camera_metadata_t *request = NULL;
677 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
678 /*out*/&request));
679 EXPECT_NE((void*)NULL, request);
680
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 size_t streamCount = 2;
688 camera_metadata_entry_t entry;
689 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
690 int find = find_camera_metadata_entry(request, tag, &entry);
691 if (find == -ENOENT) {
692 if (add_camera_metadata_entry(request, tag, &allStreams,
693 /*data_count*/streamCount) != OK) {
694 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
695 ASSERT_OK(append_camera_metadata(tmp, request));
696 free_camera_metadata(request);
697 request = tmp;
698
699 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
700 /*data_count*/streamCount));
701 }
702 } else {
703 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
704 &allStreams, /*data_count*/streamCount, &entry));
705 }
706
707 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
708
709 // Consume a couple of frames
710 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
711 // stream id 1
712 EXPECT_EQ(OK, mListener->WaitForEvent());
713 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
714
715 // stream id 2
716 EXPECT_EQ(OK, mListener->WaitForEvent());
717 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
718
719 //TODO: events should be a struct with some data like the stream id
720 }
721
722 // Done: clean up
723 free_camera_metadata(request);
724 EXPECT_OK(mCamera->deleteStream(streamId));
725 EXPECT_OK(mCamera->exclusiveUnlock());
726}
727
Igor Murashkina91537e2013-02-21 12:02:29 -0800728TEST_F(ProCameraTest, ResultReceiver) {
729 if (HasFatalFailure()) {
730 return;
731 }
732
733 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
734 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
735 // need to filter out events at read time
736
737 int streamId = -1;
738 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
739 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId));
740 EXPECT_NE(-1, streamId);
741
742 EXPECT_OK(mCamera->exclusiveTryLock());
743 /*
744 */
745 /* iterate in a loop submitting requests every frame.
746 * what kind of requests doesnt really matter, just whatever.
747 */
748
749 camera_metadata_t *request = NULL;
750 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
751 /*out*/&request));
752 EXPECT_NE((void*)NULL, request);
753
754 /*FIXME*/
755 if(request == NULL) request = allocate_camera_metadata(10, 100);
756
757 // set the output streams to just this stream ID
758
759 uint8_t allStreams[] = { streamId };
760 size_t streamCount = 1;
761 camera_metadata_entry_t entry;
762 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
763 int find = find_camera_metadata_entry(request, tag, &entry);
764 if (find == -ENOENT) {
765 if (add_camera_metadata_entry(request, tag, &allStreams,
766 /*data_count*/streamCount) != OK) {
767 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
768 ASSERT_OK(append_camera_metadata(tmp, request));
769 free_camera_metadata(request);
770 request = tmp;
771
772 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
773 /*data_count*/streamCount));
774 }
775 } else {
776 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
777 &allStreams, /*data_count*/streamCount, &entry));
778 }
779
780 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
781
782 // Consume a couple of results
783 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
784 EXPECT_EQ(OK, mListener->WaitForEvent());
785 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
786 }
787
788 // Done: clean up
789 free_camera_metadata(request);
790 EXPECT_OK(mCamera->deleteStream(streamId));
791 EXPECT_OK(mCamera->exclusiveUnlock());
792}
793
Igor Murashkin634a5152013-02-20 17:15:11 -0800794}
795}
796}
797}
798