blob: 6212678f195ff15bec709c19ad32d9c7f25113d7 [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
Igor Murashkinc6deb682013-04-18 11:53:35 -070083 << (unsigned int) status << " cameraId " << cameraId
Igor Murashkinbfc99152013-02-27 12:55:20 -080084 << std::endl;
85
86 Mutex::Autolock al(mMutex);
87
88 mLatestStatus = status;
89 mCondition.broadcast();
90 }
91
Chien-Yu Chen3068d732015-02-09 13:29:57 -080092 void onTorchStatusChanged(TorchStatus status, const String16& cameraId) {
93 dout << "On torch status changed: 0x" << std::hex
94 << (unsigned int) status << " cameraId " << cameraId.string()
95 << std::endl;
96 }
97
Igor Murashkinbfc99152013-02-27 12:55:20 -080098 status_t waitForStatusChange(Status& newStatus) {
99 Mutex::Autolock al(mMutex);
100
101 if (mLatestStatus != mPrevStatus) {
102 newStatus = mLatestStatus;
103 mPrevStatus = mLatestStatus;
104 return OK;
105 }
106
107 status_t stat = mCondition.waitRelative(mMutex,
108 TEST_LISTENER_TIMEOUT);
109
110 if (stat == OK) {
111 newStatus = mLatestStatus;
112 mPrevStatus = mLatestStatus;
113 }
114
115 return stat;
116 }
117
118 Condition mCondition;
119 Mutex mMutex;
120
121 Status mLatestStatus;
122 Status mPrevStatus;
123};
124
Igor Murashkin5835cc42013-02-20 19:29:53 -0800125enum ProEvent {
Igor Murashkin53765732013-02-20 17:41:57 -0800126 UNKNOWN,
127 ACQUIRED,
128 RELEASED,
Igor Murashkin5835cc42013-02-20 19:29:53 -0800129 STOLEN,
Igor Murashkinc6deb682013-04-18 11:53:35 -0700130 FRAME_RECEIVED,
Igor Murashkina91537e2013-02-21 12:02:29 -0800131 RESULT_RECEIVED,
Igor Murashkin53765732013-02-20 17:41:57 -0800132};
133
Igor Murashkina91537e2013-02-21 12:02:29 -0800134inline int ProEvent_Mask(ProEvent e) {
135 return (1 << static_cast<int>(e));
136}
137
Igor Murashkin5835cc42013-02-20 19:29:53 -0800138typedef Vector<ProEvent> EventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800139
140class ProCameraTestThread : public Thread
141{
142public:
143 ProCameraTestThread() {
144 }
145
146 virtual bool threadLoop() {
147 mProc = ProcessState::self();
148 mProc->startThreadPool();
149
150 IPCThreadState *ptr = IPCThreadState::self();
151
Igor Murashkin53765732013-02-20 17:41:57 -0800152 ptr->joinThreadPool();
Igor Murashkin53765732013-02-20 17:41:57 -0800153
154 return false;
155 }
156
157 sp<ProcessState> mProc;
158};
159
160class ProCameraTestListener : public ProCameraListener {
161
162public:
Igor Murashkina91537e2013-02-21 12:02:29 -0800163 static const int EVENT_MASK_ALL = 0xFFFFFFFF;
164
165 ProCameraTestListener() {
166 mEventMask = EVENT_MASK_ALL;
Igor Murashkinc6deb682013-04-18 11:53:35 -0700167 mDropFrames = false;
Igor Murashkina91537e2013-02-21 12:02:29 -0800168 }
169
Igor Murashkin53765732013-02-20 17:41:57 -0800170 status_t WaitForEvent() {
171 Mutex::Autolock cal(mConditionMutex);
172
173 {
174 Mutex::Autolock al(mListenerMutex);
175
Igor Murashkin5835cc42013-02-20 19:29:53 -0800176 if (mProEventList.size() > 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800177 return OK;
178 }
179 }
180
181 return mListenerCondition.waitRelative(mConditionMutex,
182 TEST_LISTENER_TIMEOUT);
183 }
184
185 /* Read events into out. Existing queue is flushed */
186 void ReadEvents(EventList& out) {
187 Mutex::Autolock al(mListenerMutex);
188
Igor Murashkin5835cc42013-02-20 19:29:53 -0800189 for (size_t i = 0; i < mProEventList.size(); ++i) {
190 out.push(mProEventList[i]);
Igor Murashkin53765732013-02-20 17:41:57 -0800191 }
192
Igor Murashkin5835cc42013-02-20 19:29:53 -0800193 mProEventList.clear();
Igor Murashkin53765732013-02-20 17:41:57 -0800194 }
195
196 /**
197 * Dequeue 1 event from the event queue.
198 * Returns UNKNOWN if queue is empty
199 */
Igor Murashkin5835cc42013-02-20 19:29:53 -0800200 ProEvent ReadEvent() {
Igor Murashkin53765732013-02-20 17:41:57 -0800201 Mutex::Autolock al(mListenerMutex);
202
Igor Murashkin5835cc42013-02-20 19:29:53 -0800203 if (mProEventList.size() == 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800204 return UNKNOWN;
205 }
206
Igor Murashkin5835cc42013-02-20 19:29:53 -0800207 ProEvent ev = mProEventList[0];
208 mProEventList.removeAt(0);
Igor Murashkin53765732013-02-20 17:41:57 -0800209
210 return ev;
211 }
212
Igor Murashkina91537e2013-02-21 12:02:29 -0800213 void SetEventMask(int eventMask) {
214 Mutex::Autolock al(mListenerMutex);
215 mEventMask = eventMask;
216 }
217
Igor Murashkinc6deb682013-04-18 11:53:35 -0700218 // Automatically acquire/release frames as they are available
219 void SetDropFrames(bool dropFrames) {
220 Mutex::Autolock al(mListenerMutex);
221 mDropFrames = dropFrames;
222 }
223
Igor Murashkin53765732013-02-20 17:41:57 -0800224private:
Igor Murashkin5835cc42013-02-20 19:29:53 -0800225 void QueueEvent(ProEvent ev) {
Igor Murashkina91537e2013-02-21 12:02:29 -0800226 bool eventAdded = false;
Igor Murashkin53765732013-02-20 17:41:57 -0800227 {
228 Mutex::Autolock al(mListenerMutex);
Igor Murashkina91537e2013-02-21 12:02:29 -0800229
Igor Murashkinc6deb682013-04-18 11:53:35 -0700230 // Drop events not part of mask
Igor Murashkina91537e2013-02-21 12:02:29 -0800231 if (ProEvent_Mask(ev) & mEventMask) {
232 mProEventList.push(ev);
233 eventAdded = true;
234 }
Igor Murashkin53765732013-02-20 17:41:57 -0800235 }
236
Igor Murashkina91537e2013-02-21 12:02:29 -0800237 if (eventAdded) {
238 mListenerCondition.broadcast();
239 }
Igor Murashkin53765732013-02-20 17:41:57 -0800240 }
241
242protected:
243
244 //////////////////////////////////////////////////
245 ///////// ProCameraListener //////////////////////
246 //////////////////////////////////////////////////
247
248
249 // Lock has been acquired. Write operations now available.
250 virtual void onLockAcquired() {
251 QueueEvent(ACQUIRED);
252 }
253 // Lock has been released with exclusiveUnlock
254 virtual void onLockReleased() {
255 QueueEvent(RELEASED);
256 }
257
258 // Lock has been stolen by another client.
259 virtual void onLockStolen() {
260 QueueEvent(STOLEN);
261 }
262
263 // Lock free.
264 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
265
266 dout << "Trigger notify: " << ext1 << " " << ext2
267 << " " << ext3 << std::endl;
268 }
269
Igor Murashkinc6deb682013-04-18 11:53:35 -0700270 virtual void onFrameAvailable(int streamId,
271 const sp<CpuConsumer>& consumer) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800272
Igor Murashkinc6deb682013-04-18 11:53:35 -0700273 QueueEvent(FRAME_RECEIVED);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800274
Igor Murashkinc6deb682013-04-18 11:53:35 -0700275 Mutex::Autolock al(mListenerMutex);
276 if (mDropFrames) {
277 CpuConsumer::LockedBuffer buf;
278 status_t ret;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800279
Igor Murashkinc6deb682013-04-18 11:53:35 -0700280 if (OK == (ret = consumer->lockNextBuffer(&buf))) {
281
282 dout << "Frame received on streamId = " << streamId <<
283 ", dataPtr = " << (void*)buf.data <<
284 ", timestamp = " << buf.timestamp << std::endl;
285
286 EXPECT_OK(consumer->unlockBuffer(buf));
287 }
288 } else {
289 dout << "Frame received on streamId = " << streamId << std::endl;
290 }
Igor Murashkin5835cc42013-02-20 19:29:53 -0800291 }
Igor Murashkinc6deb682013-04-18 11:53:35 -0700292
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700293 virtual void onResultReceived(int32_t requestId,
Igor Murashkina91537e2013-02-21 12:02:29 -0800294 camera_metadata* request) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700295 dout << "Result received requestId = " << requestId
Igor Murashkina91537e2013-02-21 12:02:29 -0800296 << ", requestPtr = " << (void*)request << std::endl;
297 QueueEvent(RESULT_RECEIVED);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800298 free_camera_metadata(request);
299 }
300
Igor Murashkinfa4cf9d2013-03-04 16:14:23 -0800301 virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
302 dout << "Notify received: msg " << std::hex << msg
303 << ", ext1: " << std::hex << ext1 << ", ext2: " << std::hex << ext2
304 << std::endl;
305 }
Igor Murashkin53765732013-02-20 17:41:57 -0800306
Igor Murashkin5835cc42013-02-20 19:29:53 -0800307 Vector<ProEvent> mProEventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800308 Mutex mListenerMutex;
309 Mutex mConditionMutex;
310 Condition mListenerCondition;
Igor Murashkina91537e2013-02-21 12:02:29 -0800311 int mEventMask;
Igor Murashkinc6deb682013-04-18 11:53:35 -0700312 bool mDropFrames;
Igor Murashkin53765732013-02-20 17:41:57 -0800313};
314
Igor Murashkin634a5152013-02-20 17:15:11 -0800315class ProCameraTest : public ::testing::Test {
316
Igor Murashkin53765732013-02-20 17:41:57 -0800317public:
318 ProCameraTest() {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800319 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
320 if (displaySecsEnv != NULL) {
321 mDisplaySecs = atoi(displaySecsEnv);
322 if (mDisplaySecs < 0) {
323 mDisplaySecs = 0;
324 }
325 } else {
326 mDisplaySecs = 0;
327 }
328
329 char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
330 if (displayFmtEnv != NULL) {
331 mDisplayFmt = FormatFromString(displayFmtEnv);
332 } else {
333 mDisplayFmt = TEST_DISPLAY_FORMAT;
334 }
335
336 char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
337 if (displayWidthEnv != NULL) {
338 mDisplayW = atoi(displayWidthEnv);
339 if (mDisplayW < 0) {
340 mDisplayW = 0;
341 }
342 } else {
343 mDisplayW = TEST_DISPLAY_WIDTH;
344 }
345
346 char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
347 if (displayHeightEnv != NULL) {
348 mDisplayH = atoi(displayHeightEnv);
349 if (mDisplayH < 0) {
350 mDisplayH = 0;
351 }
352 } else {
353 mDisplayH = TEST_DISPLAY_HEIGHT;
354 }
Igor Murashkin53765732013-02-20 17:41:57 -0800355 }
356
Igor Murashkin39f79f72013-01-30 10:14:24 -0800357 static void SetUpTestCase() {
358 // Binder Thread Pool Initialization
Igor Murashkin53765732013-02-20 17:41:57 -0800359 mTestThread = new ProCameraTestThread();
360 mTestThread->run("ProCameraTestThread");
Igor Murashkin39f79f72013-01-30 10:14:24 -0800361 }
Igor Murashkin53765732013-02-20 17:41:57 -0800362
Igor Murashkin39f79f72013-01-30 10:14:24 -0800363 virtual void SetUp() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800364 mCamera = ProCamera::connect(CAMERA_ID);
365 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin53765732013-02-20 17:41:57 -0800366
367 mListener = new ProCameraTestListener();
368 mCamera->setListener(mListener);
Igor Murashkin634a5152013-02-20 17:15:11 -0800369 }
370
371 virtual void TearDown() {
372 ASSERT_NE((void*)NULL, mCamera.get());
373 mCamera->disconnect();
374 }
375
376protected:
377 sp<ProCamera> mCamera;
Igor Murashkin53765732013-02-20 17:41:57 -0800378 sp<ProCameraTestListener> mListener;
379
Igor Murashkin39f79f72013-01-30 10:14:24 -0800380 static sp<Thread> mTestThread;
Igor Murashkin53765732013-02-20 17:41:57 -0800381
Igor Murashkin68506fd2013-02-20 17:57:31 -0800382 int mDisplaySecs;
Igor Murashkindcb07d52013-02-21 14:18:10 -0800383 int mDisplayFmt;
384 int mDisplayW;
385 int mDisplayH;
386
Igor Murashkin68506fd2013-02-20 17:57:31 -0800387 sp<SurfaceComposerClient> mComposerClient;
388 sp<SurfaceControl> mSurfaceControl;
389
Igor Murashkin5835cc42013-02-20 19:29:53 -0800390 sp<SurfaceComposerClient> mDepthComposerClient;
391 sp<SurfaceControl> mDepthSurfaceControl;
392
Igor Murashkin68506fd2013-02-20 17:57:31 -0800393 int getSurfaceWidth() {
394 return 512;
395 }
396 int getSurfaceHeight() {
397 return 512;
398 }
399
400 void createOnScreenSurface(sp<Surface>& surface) {
401 mComposerClient = new SurfaceComposerClient;
402 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
403
404 mSurfaceControl = mComposerClient->createSurface(
405 String8("ProCameraTest StreamingImage Surface"),
406 getSurfaceWidth(), getSurfaceHeight(),
407 PIXEL_FORMAT_RGB_888, 0);
408
Igor Murashkindcb07d52013-02-21 14:18:10 -0800409 mSurfaceControl->setPosition(0, 0);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800410
Igor Murashkin68506fd2013-02-20 17:57:31 -0800411 ASSERT_TRUE(mSurfaceControl != NULL);
412 ASSERT_TRUE(mSurfaceControl->isValid());
413
414 SurfaceComposerClient::openGlobalTransaction();
415 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
416 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
417 SurfaceComposerClient::closeGlobalTransaction();
418
419 sp<ANativeWindow> window = mSurfaceControl->getSurface();
420 surface = mSurfaceControl->getSurface();
421
422 ASSERT_NE((void*)NULL, surface.get());
423 }
424
Igor Murashkin5835cc42013-02-20 19:29:53 -0800425 void createDepthOnScreenSurface(sp<Surface>& surface) {
426 mDepthComposerClient = new SurfaceComposerClient;
427 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
428
429 mDepthSurfaceControl = mDepthComposerClient->createSurface(
430 String8("ProCameraTest StreamingImage Surface"),
431 getSurfaceWidth(), getSurfaceHeight(),
432 PIXEL_FORMAT_RGB_888, 0);
433
434 mDepthSurfaceControl->setPosition(640, 0);
435
436 ASSERT_TRUE(mDepthSurfaceControl != NULL);
437 ASSERT_TRUE(mDepthSurfaceControl->isValid());
438
439 SurfaceComposerClient::openGlobalTransaction();
440 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
441 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
442 SurfaceComposerClient::closeGlobalTransaction();
443
444 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
445 surface = mDepthSurfaceControl->getSurface();
446
447 ASSERT_NE((void*)NULL, surface.get());
448 }
449
Igor Murashkin7b33a742013-02-21 13:49:26 -0800450 template <typename T>
Igor Murashkindcb07d52013-02-21 14:18:10 -0800451 static bool ExistsItem(T needle, T* array, size_t count) {
452 if (!array) {
453 return false;
454 }
455
Igor Murashkina140a6e2013-02-21 14:45:03 -0800456 for (size_t i = 0; i < count; ++i) {
Igor Murashkin7b33a742013-02-21 13:49:26 -0800457 if (array[i] == needle) {
458 return true;
459 }
460 }
461 return false;
462 }
463
Igor Murashkindcb07d52013-02-21 14:18:10 -0800464
465 static int FormatFromString(const char* str) {
466 std::string s(str);
467
468#define CMP_STR(x, y) \
469 if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
470#define CMP_STR_SAME(x) CMP_STR(x, x)
471
472 CMP_STR_SAME( Y16);
473 CMP_STR_SAME( Y8);
474 CMP_STR_SAME( YV12);
475 CMP_STR(NV16, YCbCr_422_SP);
476 CMP_STR(NV21, YCrCb_420_SP);
477 CMP_STR(YUY2, YCbCr_422_I);
478 CMP_STR(RAW, RAW_SENSOR);
479 CMP_STR(RGBA, RGBA_8888);
480
481 std::cerr << "Unknown format string " << str << std::endl;
482 return -1;
483
484 }
485
486 /**
487 * Creating a streaming request for these output streams from a template,
488 * and submit it
489 */
Zhijun Hed1d64672013-09-06 15:00:01 -0700490 void createSubmitRequestForStreams(int32_t* streamIds, size_t count, int requestCount=-1) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800491
492 ASSERT_NE((void*)NULL, streamIds);
Igor Murashkina140a6e2013-02-21 14:45:03 -0800493 ASSERT_LT(0u, count);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800494
495 camera_metadata_t *requestTmp = NULL;
496 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
497 /*out*/&requestTmp));
498 ASSERT_NE((void*)NULL, requestTmp);
499 CameraMetadata request(requestTmp);
500
501 // set the output streams. default is empty
502
503 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
504 request.update(tag, streamIds, count);
505
506 requestTmp = request.release();
Igor Murashkina140a6e2013-02-21 14:45:03 -0800507
508 if (requestCount < 0) {
509 EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
510 } else {
511 for (int i = 0; i < requestCount; ++i) {
512 EXPECT_OK(mCamera->submitRequest(requestTmp,
513 /*streaming*/false));
514 }
515 }
Igor Murashkindcb07d52013-02-21 14:18:10 -0800516 request.acquire(requestTmp);
517 }
Igor Murashkin634a5152013-02-20 17:15:11 -0800518};
519
Igor Murashkin39f79f72013-01-30 10:14:24 -0800520sp<Thread> ProCameraTest::mTestThread;
521
Igor Murashkin7b33a742013-02-21 13:49:26 -0800522TEST_F(ProCameraTest, AvailableFormats) {
523 if (HasFatalFailure()) {
524 return;
525 }
526
Igor Murashkindcb07d52013-02-21 14:18:10 -0800527 CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
528 ASSERT_FALSE(staticInfo.isEmpty());
Igor Murashkin7b33a742013-02-21 13:49:26 -0800529
Igor Murashkin7b33a742013-02-21 13:49:26 -0800530 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800531 EXPECT_TRUE(staticInfo.exists(tag));
532 camera_metadata_entry_t entry = staticInfo.find(tag);
Igor Murashkin7b33a742013-02-21 13:49:26 -0800533
Igor Murashkindcb07d52013-02-21 14:18:10 -0800534 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800535 entry.data.i32, entry.count));
Igor Murashkindcb07d52013-02-21 14:18:10 -0800536 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800537 entry.data.i32, entry.count));
Igor Murashkin7b33a742013-02-21 13:49:26 -0800538}
539
Igor Murashkin39f79f72013-01-30 10:14:24 -0800540// test around exclusiveTryLock (immediate locking)
Igor Murashkin53765732013-02-20 17:41:57 -0800541TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800542
543 if (HasFatalFailure()) {
544 return;
545 }
546
Igor Murashkina91537e2013-02-21 12:02:29 -0800547 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
548 ProEvent_Mask(STOLEN) |
549 ProEvent_Mask(RELEASED));
550
Igor Murashkin53765732013-02-20 17:41:57 -0800551 EXPECT_FALSE(mCamera->hasExclusiveLock());
552 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin39f79f72013-01-30 10:14:24 -0800553 // at this point we definitely have the lock
554
555 EXPECT_EQ(OK, mListener->WaitForEvent());
556 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
557
558 EXPECT_TRUE(mCamera->hasExclusiveLock());
559 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
560
561 EXPECT_EQ(OK, mListener->WaitForEvent());
562 EXPECT_EQ(RELEASED, mListener->ReadEvent());
563
564 EXPECT_FALSE(mCamera->hasExclusiveLock());
565}
566
567// test around exclusiveLock (locking at some future point in time)
568TEST_F(ProCameraTest, LockingAsynchronous) {
569
570 if (HasFatalFailure()) {
571 return;
572 }
573
Igor Murashkina91537e2013-02-21 12:02:29 -0800574
575 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
576 ProEvent_Mask(STOLEN) |
577 ProEvent_Mask(RELEASED));
578
Igor Murashkin39f79f72013-01-30 10:14:24 -0800579 // TODO: Add another procamera that has a lock here.
580 // then we can be test that the lock wont immediately be acquired
581
582 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkina91537e2013-02-21 12:02:29 -0800583 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
584 // at this point we definitely have the lock
Igor Murashkin53765732013-02-20 17:41:57 -0800585
586 EXPECT_EQ(OK, mListener->WaitForEvent());
587 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
588
589 EXPECT_TRUE(mCamera->hasExclusiveLock());
590 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
591
592 EXPECT_EQ(OK, mListener->WaitForEvent());
593 EXPECT_EQ(RELEASED, mListener->ReadEvent());
594
595 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkin634a5152013-02-20 17:15:11 -0800596}
597
Igor Murashkin68506fd2013-02-20 17:57:31 -0800598// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800599TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800600 if (HasFatalFailure()) {
601 return;
602 }
Igor Murashkin68506fd2013-02-20 17:57:31 -0800603
Igor Murashkindcb07d52013-02-21 14:18:10 -0800604 sp<Surface> surface;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800605 if (mDisplaySecs > 0) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800606 createOnScreenSurface(/*out*/surface);
607 }
608 else {
609 dout << "Skipping, will not render to screen" << std::endl;
610 return;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800611 }
Igor Murashkin5835cc42013-02-20 19:29:53 -0800612
613 int depthStreamId = -1;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800614
Igor Murashkinbfc99152013-02-27 12:55:20 -0800615 sp<ServiceListener> listener = new ServiceListener();
616 EXPECT_OK(ProCamera::addServiceListener(listener));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800617
Igor Murashkincba2c162013-03-20 15:56:31 -0700618 ServiceListener::Status currentStatus;
619
620 // when subscribing a new listener,
621 // we immediately get a callback to the current status
622 while (listener->waitForStatusChange(/*out*/currentStatus) != OK);
623 EXPECT_EQ(ServiceListener::STATUS_PRESENT, currentStatus);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800624
Igor Murashkinbfc99152013-02-27 12:55:20 -0800625 dout << "Will now stream and resume infinitely..." << std::endl;
626 while (true) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800627
Igor Murashkincba2c162013-03-20 15:56:31 -0700628 if (currentStatus == ServiceListener::STATUS_PRESENT) {
Igor Murashkinbfc99152013-02-27 12:55:20 -0800629
Igor Murashkincba2c162013-03-20 15:56:31 -0700630 ASSERT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
Igor Murashkinbfc99152013-02-27 12:55:20 -0800631 surface,
632 &depthStreamId));
633 EXPECT_NE(-1, depthStreamId);
634
635 EXPECT_OK(mCamera->exclusiveTryLock());
636
Zhijun Hed1d64672013-09-06 15:00:01 -0700637 int32_t streams[] = { depthStreamId };
Igor Murashkinbfc99152013-02-27 12:55:20 -0800638 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
639 streams,
640 /*count*/1));
641 }
642
643 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
644
645 // TODO: maybe check for getch every once in a while?
646 while (listener->waitForStatusChange(/*out*/stat) != OK);
647
648 if (currentStatus != stat) {
Igor Murashkincba2c162013-03-20 15:56:31 -0700649 if (stat == ServiceListener::STATUS_PRESENT) {
Igor Murashkinbfc99152013-02-27 12:55:20 -0800650 dout << "Reconnecting to camera" << std::endl;
651 mCamera = ProCamera::connect(CAMERA_ID);
652 } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
653 dout << "Disconnecting from camera" << std::endl;
654 mCamera->disconnect();
Igor Murashkincba2c162013-03-20 15:56:31 -0700655 } else if (stat == ServiceListener::STATUS_NOT_PRESENT) {
656 dout << "Camera unplugged" << std::endl;
657 mCamera = NULL;
Igor Murashkinbfc99152013-02-27 12:55:20 -0800658 } else {
659 dout << "Unknown status change "
660 << std::hex << stat << std::endl;
661 }
662
663 currentStatus = stat;
664 }
665 }
666
667 EXPECT_OK(ProCamera::removeServiceListener(listener));
Igor Murashkindcb07d52013-02-21 14:18:10 -0800668 EXPECT_OK(mCamera->deleteStream(depthStreamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800669 EXPECT_OK(mCamera->exclusiveUnlock());
670}
671
Igor Murashkineb72e172013-02-21 11:43:14 -0800672// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800673TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
Igor Murashkineb72e172013-02-21 11:43:14 -0800674 if (HasFatalFailure()) {
675 return;
676 }
Igor Murashkineb72e172013-02-21 11:43:14 -0800677 sp<Surface> surface;
678 sp<Surface> depthSurface;
679 if (mDisplaySecs > 0) {
680 createOnScreenSurface(/*out*/surface);
681 createDepthOnScreenSurface(/*out*/depthSurface);
682 }
683
684 int streamId = -1;
685 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
686 TEST_FORMAT_MAIN, surface, &streamId));
687 EXPECT_NE(-1, streamId);
688
689 int depthStreamId = -1;
690 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
691 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
692 EXPECT_NE(-1, depthStreamId);
693
694 EXPECT_OK(mCamera->exclusiveTryLock());
695 /*
696 */
697 /* iterate in a loop submitting requests every frame.
698 * what kind of requests doesnt really matter, just whatever.
699 */
700
701 // it would probably be better to use CameraMetadata from camera service.
702 camera_metadata_t *request = NULL;
703 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
704 /*out*/&request));
705 EXPECT_NE((void*)NULL, request);
706
707 /*FIXME: dont need this later, at which point the above should become an
708 ASSERT_NE*/
709 if(request == NULL) request = allocate_camera_metadata(10, 100);
710
711 // set the output streams to just this stream ID
712
713 // wow what a verbose API.
Zhijun Hed1d64672013-09-06 15:00:01 -0700714 int32_t allStreams[] = { streamId, depthStreamId };
Igor Murashkineb72e172013-02-21 11:43:14 -0800715 // IMPORTANT. bad things will happen if its not a uint8.
716 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
717 camera_metadata_entry_t entry;
718 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
719 int find = find_camera_metadata_entry(request, tag, &entry);
720 if (find == -ENOENT) {
721 if (add_camera_metadata_entry(request, tag, &allStreams,
722 /*data_count*/streamCount) != OK) {
723 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
724 ASSERT_OK(append_camera_metadata(tmp, request));
725 free_camera_metadata(request);
726 request = tmp;
727
728 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
729 /*data_count*/streamCount));
730 }
731 } else {
732 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
733 &allStreams, /*data_count*/streamCount, &entry));
734 }
735
736 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
737
738 dout << "will sleep now for " << mDisplaySecs << std::endl;
739 sleep(mDisplaySecs);
740
741 free_camera_metadata(request);
742
Zhijun Hed1d64672013-09-06 15:00:01 -0700743 for (size_t i = 0; i < streamCount; ++i) {
Igor Murashkineb72e172013-02-21 11:43:14 -0800744 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
745 }
746 EXPECT_OK(mCamera->exclusiveUnlock());
747}
748
749TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800750 if (HasFatalFailure()) {
751 return;
752 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800753
Igor Murashkinc6deb682013-04-18 11:53:35 -0700754 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
755 ProEvent_Mask(STOLEN) |
756 ProEvent_Mask(RELEASED) |
757 ProEvent_Mask(FRAME_RECEIVED));
758 mListener->SetDropFrames(true);
Igor Murashkina91537e2013-02-21 12:02:29 -0800759
Igor Murashkin5835cc42013-02-20 19:29:53 -0800760 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800761 sp<CpuConsumer> consumer;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800762 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800763 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800764 EXPECT_NE(-1, streamId);
765
766 EXPECT_OK(mCamera->exclusiveTryLock());
767 EXPECT_EQ(OK, mListener->WaitForEvent());
768 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
769 /* iterate in a loop submitting requests every frame.
770 * what kind of requests doesnt really matter, just whatever.
771 */
772
773 // it would probably be better to use CameraMetadata from camera service.
774 camera_metadata_t *request = NULL;
775 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
776 /*out*/&request));
777 EXPECT_NE((void*)NULL, request);
778
779 /*FIXME: dont need this later, at which point the above should become an
780 ASSERT_NE*/
781 if(request == NULL) request = allocate_camera_metadata(10, 100);
782
783 // set the output streams to just this stream ID
784
Zhijun Hed1d64672013-09-06 15:00:01 -0700785 int32_t allStreams[] = { streamId };
Igor Murashkin5835cc42013-02-20 19:29:53 -0800786 camera_metadata_entry_t entry;
787 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
788 int find = find_camera_metadata_entry(request, tag, &entry);
789 if (find == -ENOENT) {
790 if (add_camera_metadata_entry(request, tag, &allStreams,
791 /*data_count*/1) != OK) {
792 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
793 ASSERT_OK(append_camera_metadata(tmp, request));
794 free_camera_metadata(request);
795 request = tmp;
796
797 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
798 /*data_count*/1));
799 }
800 } else {
801 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
802 &allStreams, /*data_count*/1, &entry));
803 }
804
805 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
806
807 // Consume a couple of frames
808 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
809 EXPECT_EQ(OK, mListener->WaitForEvent());
Igor Murashkinc6deb682013-04-18 11:53:35 -0700810 EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
Igor Murashkin5835cc42013-02-20 19:29:53 -0800811 }
812
813 // Done: clean up
814 free_camera_metadata(request);
815 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800816 EXPECT_OK(mCamera->exclusiveUnlock());
817}
818
Igor Murashkineb72e172013-02-21 11:43:14 -0800819TEST_F(ProCameraTest, CpuConsumerDual) {
820 if (HasFatalFailure()) {
821 return;
822 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800823
Igor Murashkinc6deb682013-04-18 11:53:35 -0700824 mListener->SetEventMask(ProEvent_Mask(FRAME_RECEIVED));
825 mListener->SetDropFrames(true);
Igor Murashkina91537e2013-02-21 12:02:29 -0800826
Igor Murashkineb72e172013-02-21 11:43:14 -0800827 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800828 sp<CpuConsumer> consumer;
Igor Murashkineb72e172013-02-21 11:43:14 -0800829 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800830 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800831 EXPECT_NE(-1, streamId);
832
833 int depthStreamId = -1;
834 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800835 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800836 EXPECT_NE(-1, depthStreamId);
837
838 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkineb72e172013-02-21 11:43:14 -0800839 /*
840 */
841 /* iterate in a loop submitting requests every frame.
842 * what kind of requests doesnt really matter, just whatever.
843 */
844
845 // it would probably be better to use CameraMetadata from camera service.
846 camera_metadata_t *request = NULL;
847 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
848 /*out*/&request));
849 EXPECT_NE((void*)NULL, request);
850
851 if(request == NULL) request = allocate_camera_metadata(10, 100);
852
853 // set the output streams to just this stream ID
854
855 // wow what a verbose API.
Zhijun Hed1d64672013-09-06 15:00:01 -0700856 int32_t allStreams[] = { streamId, depthStreamId };
Igor Murashkineb72e172013-02-21 11:43:14 -0800857 size_t streamCount = 2;
858 camera_metadata_entry_t entry;
859 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
860 int find = find_camera_metadata_entry(request, tag, &entry);
861 if (find == -ENOENT) {
862 if (add_camera_metadata_entry(request, tag, &allStreams,
863 /*data_count*/streamCount) != OK) {
864 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
865 ASSERT_OK(append_camera_metadata(tmp, request));
866 free_camera_metadata(request);
867 request = tmp;
868
869 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
870 /*data_count*/streamCount));
871 }
872 } else {
873 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
874 &allStreams, /*data_count*/streamCount, &entry));
875 }
876
877 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
878
879 // Consume a couple of frames
880 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
881 // stream id 1
882 EXPECT_EQ(OK, mListener->WaitForEvent());
Igor Murashkinc6deb682013-04-18 11:53:35 -0700883 EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
Igor Murashkineb72e172013-02-21 11:43:14 -0800884
885 // stream id 2
886 EXPECT_EQ(OK, mListener->WaitForEvent());
Igor Murashkinc6deb682013-04-18 11:53:35 -0700887 EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
Igor Murashkineb72e172013-02-21 11:43:14 -0800888
889 //TODO: events should be a struct with some data like the stream id
890 }
891
892 // Done: clean up
893 free_camera_metadata(request);
894 EXPECT_OK(mCamera->deleteStream(streamId));
895 EXPECT_OK(mCamera->exclusiveUnlock());
896}
897
Igor Murashkina91537e2013-02-21 12:02:29 -0800898TEST_F(ProCameraTest, ResultReceiver) {
899 if (HasFatalFailure()) {
900 return;
901 }
902
903 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
Igor Murashkinc6deb682013-04-18 11:53:35 -0700904 mListener->SetDropFrames(true);
905 //FIXME: if this is run right after the previous test we get FRAME_RECEIVED
Igor Murashkina91537e2013-02-21 12:02:29 -0800906 // need to filter out events at read time
907
908 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800909 sp<CpuConsumer> consumer;
Igor Murashkina91537e2013-02-21 12:02:29 -0800910 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800911 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkina91537e2013-02-21 12:02:29 -0800912 EXPECT_NE(-1, streamId);
913
914 EXPECT_OK(mCamera->exclusiveTryLock());
915 /*
916 */
917 /* iterate in a loop submitting requests every frame.
918 * what kind of requests doesnt really matter, just whatever.
919 */
920
921 camera_metadata_t *request = NULL;
922 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
923 /*out*/&request));
924 EXPECT_NE((void*)NULL, request);
925
926 /*FIXME*/
927 if(request == NULL) request = allocate_camera_metadata(10, 100);
928
929 // set the output streams to just this stream ID
930
Zhijun Hed1d64672013-09-06 15:00:01 -0700931 int32_t allStreams[] = { streamId };
Igor Murashkina91537e2013-02-21 12:02:29 -0800932 size_t streamCount = 1;
933 camera_metadata_entry_t entry;
934 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
935 int find = find_camera_metadata_entry(request, tag, &entry);
936 if (find == -ENOENT) {
937 if (add_camera_metadata_entry(request, tag, &allStreams,
938 /*data_count*/streamCount) != OK) {
939 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
940 ASSERT_OK(append_camera_metadata(tmp, request));
941 free_camera_metadata(request);
942 request = tmp;
943
944 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
945 /*data_count*/streamCount));
946 }
947 } else {
948 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
949 &allStreams, /*data_count*/streamCount, &entry));
950 }
951
952 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
953
954 // Consume a couple of results
955 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
956 EXPECT_EQ(OK, mListener->WaitForEvent());
957 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
958 }
959
960 // Done: clean up
961 free_camera_metadata(request);
962 EXPECT_OK(mCamera->deleteStream(streamId));
963 EXPECT_OK(mCamera->exclusiveUnlock());
964}
965
Igor Murashkinc6deb682013-04-18 11:53:35 -0700966// FIXME: This is racy and sometimes fails on waitForFrameMetadata
967TEST_F(ProCameraTest, DISABLED_WaitForResult) {
Igor Murashkina140a6e2013-02-21 14:45:03 -0800968 if (HasFatalFailure()) {
969 return;
970 }
971
Igor Murashkinc6deb682013-04-18 11:53:35 -0700972 mListener->SetDropFrames(true);
973
Igor Murashkina140a6e2013-02-21 14:45:03 -0800974 int streamId = -1;
975 sp<CpuConsumer> consumer;
976 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
977 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
978 EXPECT_NE(-1, streamId);
979
980 EXPECT_OK(mCamera->exclusiveTryLock());
981
Zhijun Hed1d64672013-09-06 15:00:01 -0700982 int32_t streams[] = { streamId };
Igor Murashkina140a6e2013-02-21 14:45:03 -0800983 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
984
985 // Consume a couple of results
986 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
987 EXPECT_OK(mCamera->waitForFrameMetadata());
988 CameraMetadata meta = mCamera->consumeFrameMetadata();
989 EXPECT_FALSE(meta.isEmpty());
990 }
991
992 // Done: clean up
Igor Murashkina140a6e2013-02-21 14:45:03 -0800993 EXPECT_OK(mCamera->deleteStream(streamId));
994 EXPECT_OK(mCamera->exclusiveUnlock());
995}
996
997TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
998 if (HasFatalFailure()) {
999 return;
1000 }
1001
1002 int streamId = -1;
1003 sp<CpuConsumer> consumer;
1004 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1005 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1006 EXPECT_NE(-1, streamId);
1007
1008 EXPECT_OK(mCamera->exclusiveTryLock());
1009
Zhijun Hed1d64672013-09-06 15:00:01 -07001010 int32_t streams[] = { streamId };
Igor Murashkina140a6e2013-02-21 14:45:03 -08001011 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1012 /*requests*/TEST_CPU_FRAME_COUNT));
1013
1014 // Consume a couple of results
1015 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001016 EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));
Igor Murashkina140a6e2013-02-21 14:45:03 -08001017
1018 CpuConsumer::LockedBuffer buf;
1019 EXPECT_OK(consumer->lockNextBuffer(&buf));
1020
1021 dout << "Buffer synchronously received on streamId = " << streamId <<
1022 ", dataPtr = " << (void*)buf.data <<
1023 ", timestamp = " << buf.timestamp << std::endl;
1024
1025 EXPECT_OK(consumer->unlockBuffer(buf));
1026 }
1027
1028 // Done: clean up
1029 EXPECT_OK(mCamera->deleteStream(streamId));
1030 EXPECT_OK(mCamera->exclusiveUnlock());
1031}
1032
Igor Murashkinc6deb682013-04-18 11:53:35 -07001033// FIXME: This is racy and sometimes fails on waitForFrameMetadata
1034TEST_F(ProCameraTest, DISABLED_WaitForDualStreamBuffer) {
Igor Murashkina140a6e2013-02-21 14:45:03 -08001035 if (HasFatalFailure()) {
1036 return;
1037 }
1038
1039 const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
1040
1041 // 15 fps
1042 int streamId = -1;
1043 sp<CpuConsumer> consumer;
1044 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1045 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1046 EXPECT_NE(-1, streamId);
1047
1048 // 30 fps
1049 int depthStreamId = -1;
1050 sp<CpuConsumer> depthConsumer;
1051 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
1052 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
1053 EXPECT_NE(-1, depthStreamId);
1054
1055 EXPECT_OK(mCamera->exclusiveTryLock());
1056
Zhijun Hed1d64672013-09-06 15:00:01 -07001057 int32_t streams[] = { streamId, depthStreamId };
Igor Murashkina140a6e2013-02-21 14:45:03 -08001058 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
1059 /*requests*/REQUEST_COUNT));
1060
Igor Murashkin47539182013-03-18 11:10:48 -07001061 int depthFrames = 0;
1062 int greyFrames = 0;
1063
Igor Murashkina140a6e2013-02-21 14:45:03 -08001064 // Consume two frames simultaneously. Unsynchronized by timestamps.
1065 for (int i = 0; i < REQUEST_COUNT; ++i) {
1066
Igor Murashkin65d79862013-03-27 11:07:06 -07001067 // Exhaust event queue so it doesn't keep growing
1068 while (mListener->ReadEvent() != UNKNOWN);
1069
Igor Murashkina140a6e2013-02-21 14:45:03 -08001070 // Get the metadata
1071 EXPECT_OK(mCamera->waitForFrameMetadata());
1072 CameraMetadata meta = mCamera->consumeFrameMetadata();
1073 EXPECT_FALSE(meta.isEmpty());
1074
1075 // Get the buffers
1076
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001077 EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));
Igor Murashkina140a6e2013-02-21 14:45:03 -08001078
1079 /**
1080 * Guaranteed to be able to consume the depth frame,
1081 * since we waited on it.
1082 */
1083 CpuConsumer::LockedBuffer depthBuffer;
1084 EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
1085
1086 dout << "Depth Buffer synchronously received on streamId = " <<
1087 streamId <<
1088 ", dataPtr = " << (void*)depthBuffer.data <<
1089 ", timestamp = " << depthBuffer.timestamp << std::endl;
1090
1091 EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
1092
Igor Murashkin47539182013-03-18 11:10:48 -07001093 depthFrames++;
1094
Igor Murashkina140a6e2013-02-21 14:45:03 -08001095
1096 /** Consume Greyscale frames if there are any.
1097 * There may not be since it runs at half FPS */
1098 CpuConsumer::LockedBuffer greyBuffer;
1099 while (consumer->lockNextBuffer(&greyBuffer) == OK) {
1100
1101 dout << "GRAY Buffer synchronously received on streamId = " <<
1102 streamId <<
1103 ", dataPtr = " << (void*)greyBuffer.data <<
1104 ", timestamp = " << greyBuffer.timestamp << std::endl;
1105
1106 EXPECT_OK(consumer->unlockBuffer(greyBuffer));
Igor Murashkin47539182013-03-18 11:10:48 -07001107
1108 greyFrames++;
Igor Murashkina140a6e2013-02-21 14:45:03 -08001109 }
1110 }
1111
Igor Murashkin47539182013-03-18 11:10:48 -07001112 dout << "Done, summary: depth frames " << std::dec << depthFrames
1113 << ", grey frames " << std::dec << greyFrames << std::endl;
1114
Igor Murashkina140a6e2013-02-21 14:45:03 -08001115 // Done: clean up
1116 EXPECT_OK(mCamera->deleteStream(streamId));
1117 EXPECT_OK(mCamera->exclusiveUnlock());
1118}
1119
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001120TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001121 if (HasFatalFailure()) {
1122 return;
1123 }
Igor Murashkina140a6e2013-02-21 14:45:03 -08001124
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001125 const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1126
1127 int streamId = -1;
1128 sp<CpuConsumer> consumer;
1129 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001130 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1131 /*synchronousMode*/true, &consumer, &streamId));
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001132 EXPECT_NE(-1, streamId);
1133
1134 EXPECT_OK(mCamera->exclusiveTryLock());
1135
Zhijun Hed1d64672013-09-06 15:00:01 -07001136 int32_t streams[] = { streamId };
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001137 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1138 /*requests*/NUM_REQUESTS));
1139
1140 // Consume a couple of results
1141 for (int i = 0; i < NUM_REQUESTS; ++i) {
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001142 int numFrames;
1143 EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1144
1145 // Drop all but the newest framebuffer
1146 EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1147
1148 dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1149
1150 // Skip the counter ahead, don't try to consume these frames again
1151 i += numFrames-1;
1152
1153 // "Consume" the buffer
1154 CpuConsumer::LockedBuffer buf;
1155 EXPECT_OK(consumer->lockNextBuffer(&buf));
1156
1157 dout << "Buffer synchronously received on streamId = " << streamId <<
1158 ", dataPtr = " << (void*)buf.data <<
1159 ", timestamp = " << buf.timestamp << std::endl;
1160
Igor Murashkin3fa48912013-02-28 10:41:51 -08001161 // Process at 10fps, stream is at 15fps.
1162 // This means we will definitely fill up the buffer queue with
1163 // extra buffers and need to drop them.
1164 usleep(TEST_FRAME_PROCESSING_DELAY_US);
1165
Igor Murashkin4bc4a382013-02-20 13:36:17 -08001166 EXPECT_OK(consumer->unlockBuffer(buf));
1167 }
1168
1169 // Done: clean up
1170 EXPECT_OK(mCamera->deleteStream(streamId));
1171 EXPECT_OK(mCamera->exclusiveUnlock());
1172}
Igor Murashkina140a6e2013-02-21 14:45:03 -08001173
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001174TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
1175 if (HasFatalFailure()) {
1176 return;
1177 }
1178
1179 const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1180
1181 int streamId = -1;
1182 sp<CpuConsumer> consumer;
1183 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1184 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1185 /*synchronousMode*/false, &consumer, &streamId));
1186 EXPECT_NE(-1, streamId);
1187
1188 EXPECT_OK(mCamera->exclusiveTryLock());
1189
Zhijun Hed1d64672013-09-06 15:00:01 -07001190 int32_t streams[] = { streamId };
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001191 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1192 /*requests*/NUM_REQUESTS));
1193
Igor Murashkinc6deb682013-04-18 11:53:35 -07001194 uint64_t lastFrameNumber = 0;
1195 int numFrames;
1196
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001197 // Consume a couple of results
Igor Murashkinc6deb682013-04-18 11:53:35 -07001198 int i;
1199 for (i = 0; i < NUM_REQUESTS && lastFrameNumber < NUM_REQUESTS; ++i) {
1200 EXPECT_LT(0, (numFrames = mCamera->waitForFrameBuffer(streamId)));
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001201
1202 dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1203
1204 // Skip the counter ahead, don't try to consume these frames again
1205 i += numFrames-1;
1206
1207 // "Consume" the buffer
1208 CpuConsumer::LockedBuffer buf;
Igor Murashkinc6deb682013-04-18 11:53:35 -07001209
1210 EXPECT_EQ(OK, consumer->lockNextBuffer(&buf));
1211
1212 lastFrameNumber = buf.frameNumber;
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001213
1214 dout << "Buffer asynchronously received on streamId = " << streamId <<
1215 ", dataPtr = " << (void*)buf.data <<
Igor Murashkinc6deb682013-04-18 11:53:35 -07001216 ", timestamp = " << buf.timestamp <<
1217 ", framenumber = " << buf.frameNumber << std::endl;
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001218
1219 // Process at 10fps, stream is at 15fps.
1220 // This means we will definitely fill up the buffer queue with
1221 // extra buffers and need to drop them.
1222 usleep(TEST_FRAME_PROCESSING_DELAY_US);
1223
1224 EXPECT_OK(consumer->unlockBuffer(buf));
1225 }
1226
Igor Murashkinc6deb682013-04-18 11:53:35 -07001227 dout << "Done after " << i << " iterations " << std::endl;
1228
Igor Murashkinba5ca4e2013-02-28 11:21:00 -08001229 // Done: clean up
1230 EXPECT_OK(mCamera->deleteStream(streamId));
1231 EXPECT_OK(mCamera->exclusiveUnlock());
1232}
1233
Igor Murashkina140a6e2013-02-21 14:45:03 -08001234
1235
Igor Murashkinbfc99152013-02-27 12:55:20 -08001236//TODO: refactor into separate file
1237TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1238
1239 ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1240
1241 sp<ServiceListener> listener = new ServiceListener();
1242
1243 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1244 EXPECT_OK(ProCamera::addServiceListener(listener));
1245
1246 EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1247 EXPECT_OK(ProCamera::removeServiceListener(listener));
1248
1249 EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1250}
1251
1252//TODO: refactor into separate file
1253TEST_F(ProCameraTest, ServiceListenersFunctional) {
1254
1255 sp<ServiceListener> listener = new ServiceListener();
1256
1257 EXPECT_OK(ProCamera::addServiceListener(listener));
1258
1259 sp<Camera> cam = Camera::connect(CAMERA_ID,
1260 /*clientPackageName*/String16(),
1261 -1);
1262 EXPECT_NE((void*)NULL, cam.get());
1263
1264 ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1265 EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1266
1267 EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1268
1269 if (cam.get()) {
1270 cam->disconnect();
1271 }
1272
1273 EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
Igor Murashkincba2c162013-03-20 15:56:31 -07001274 EXPECT_EQ(ServiceListener::STATUS_PRESENT, stat);
Igor Murashkinbfc99152013-02-27 12:55:20 -08001275
1276 EXPECT_OK(ProCamera::removeServiceListener(listener));
1277}
1278
1279
1280
Igor Murashkin634a5152013-02-20 17:15:11 -08001281}
1282}
1283}
1284}