ProCameraTests.cpp revision bfc9915f482520eb9676c6d2dbf7f1ac078d937d
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18#include <iostream>
19
20#include <binder/IPCThreadState.h>
21#include <utils/Thread.h>
22
23#include "Camera.h"
24#include "ProCamera.h"
25#include <utils/Vector.h>
26#include <utils/Mutex.h>
27#include <utils/Condition.h>
28
29#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#include <camera/CameraMetadata.h>
35
36#include <camera/ICameraServiceListener.h>
37
38namespace android {
39namespace camera2 {
40namespace tests {
41namespace client {
42
43#define CAMERA_ID 0
44#define TEST_DEBUGGING 0
45
46#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
47#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
48
49#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
50#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
51
52// defaults for display "test"
53#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y8
54#define TEST_DISPLAY_WIDTH 320
55#define TEST_DISPLAY_HEIGHT 240
56
57#define TEST_CPU_FRAME_COUNT 2
58#define TEST_CPU_HEAP_COUNT 5
59
60#define TEST_FRAME_PROCESSING_DELAY_US 200000 // 200 ms
61
62#if TEST_DEBUGGING
63#define dout std::cerr
64#else
65#define dout if (0) std::cerr
66#endif
67
68#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
69#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
70
71class ProCameraTest;
72
73struct 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
119enum ProEvent {
120    UNKNOWN,
121    ACQUIRED,
122    RELEASED,
123    STOLEN,
124    BUFFER_RECEIVED,
125    RESULT_RECEIVED,
126};
127
128inline int ProEvent_Mask(ProEvent e) {
129    return (1 << static_cast<int>(e));
130}
131
132typedef Vector<ProEvent> EventList;
133
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
146        ptr->joinThreadPool();
147
148        return false;
149    }
150
151    sp<ProcessState> mProc;
152};
153
154class ProCameraTestListener : public ProCameraListener {
155
156public:
157    static const int EVENT_MASK_ALL = 0xFFFFFFFF;
158
159    ProCameraTestListener() {
160        mEventMask = EVENT_MASK_ALL;
161    }
162
163    status_t WaitForEvent() {
164        Mutex::Autolock cal(mConditionMutex);
165
166        {
167            Mutex::Autolock al(mListenerMutex);
168
169            if (mProEventList.size() > 0) {
170                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
182        for (size_t i = 0; i < mProEventList.size(); ++i) {
183            out.push(mProEventList[i]);
184        }
185
186        mProEventList.clear();
187    }
188
189    /**
190      * Dequeue 1 event from the event queue.
191      * Returns UNKNOWN if queue is empty
192      */
193    ProEvent ReadEvent() {
194        Mutex::Autolock al(mListenerMutex);
195
196        if (mProEventList.size() == 0) {
197            return UNKNOWN;
198        }
199
200        ProEvent ev = mProEventList[0];
201        mProEventList.removeAt(0);
202
203        return ev;
204    }
205
206    void SetEventMask(int eventMask) {
207        Mutex::Autolock al(mListenerMutex);
208        mEventMask = eventMask;
209    }
210
211private:
212    void QueueEvent(ProEvent ev) {
213        bool eventAdded = false;
214        {
215            Mutex::Autolock al(mListenerMutex);
216
217            if (ProEvent_Mask(ev) & mEventMask) {
218                mProEventList.push(ev);
219                eventAdded = true;
220            }
221        }
222
223        if (eventAdded) {
224            mListenerCondition.broadcast();
225        }
226    }
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
256    virtual void onBufferReceived(int streamId,
257                                  const CpuConsumer::LockedBuffer& buf) {
258
259        dout << "Buffer received on streamId = " << streamId <<
260                ", dataPtr = " << (void*)buf.data <<
261                ", timestamp = " << buf.timestamp << std::endl;
262
263        QueueEvent(BUFFER_RECEIVED);
264
265    }
266    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);
271        free_camera_metadata(request);
272    }
273
274    // TODO: remove
275
276    virtual void notify(int32_t , int32_t , int32_t ) {}
277    virtual void postData(int32_t , const sp<IMemory>& ,
278                          camera_frame_metadata_t *) {}
279    virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
280
281
282    Vector<ProEvent> mProEventList;
283    Mutex             mListenerMutex;
284    Mutex             mConditionMutex;
285    Condition         mListenerCondition;
286    int               mEventMask;
287};
288
289class ProCameraTest : public ::testing::Test {
290
291public:
292    ProCameraTest() {
293        char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
294        if (displaySecsEnv != NULL) {
295            mDisplaySecs = atoi(displaySecsEnv);
296            if (mDisplaySecs < 0) {
297                mDisplaySecs = 0;
298            }
299        } else {
300            mDisplaySecs = 0;
301        }
302
303        char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
304        if (displayFmtEnv != NULL) {
305            mDisplayFmt = FormatFromString(displayFmtEnv);
306        } else {
307            mDisplayFmt = TEST_DISPLAY_FORMAT;
308        }
309
310        char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
311        if (displayWidthEnv != NULL) {
312            mDisplayW = atoi(displayWidthEnv);
313            if (mDisplayW < 0) {
314                mDisplayW = 0;
315            }
316        } else {
317            mDisplayW = TEST_DISPLAY_WIDTH;
318        }
319
320        char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
321        if (displayHeightEnv != NULL) {
322            mDisplayH = atoi(displayHeightEnv);
323            if (mDisplayH < 0) {
324                mDisplayH = 0;
325            }
326        } else {
327            mDisplayH = TEST_DISPLAY_HEIGHT;
328        }
329    }
330
331    static void SetUpTestCase() {
332        // Binder Thread Pool Initialization
333        mTestThread = new ProCameraTestThread();
334        mTestThread->run("ProCameraTestThread");
335    }
336
337    virtual void SetUp() {
338        mCamera = ProCamera::connect(CAMERA_ID);
339        ASSERT_NE((void*)NULL, mCamera.get());
340
341        mListener = new ProCameraTestListener();
342        mCamera->setListener(mListener);
343    }
344
345    virtual void TearDown() {
346        ASSERT_NE((void*)NULL, mCamera.get());
347        mCamera->disconnect();
348    }
349
350protected:
351    sp<ProCamera> mCamera;
352    sp<ProCameraTestListener> mListener;
353
354    static sp<Thread> mTestThread;
355
356    int mDisplaySecs;
357    int mDisplayFmt;
358    int mDisplayW;
359    int mDisplayH;
360
361    sp<SurfaceComposerClient> mComposerClient;
362    sp<SurfaceControl> mSurfaceControl;
363
364    sp<SurfaceComposerClient> mDepthComposerClient;
365    sp<SurfaceControl> mDepthSurfaceControl;
366
367    int getSurfaceWidth() {
368        return 512;
369    }
370    int getSurfaceHeight() {
371        return 512;
372    }
373
374    void createOnScreenSurface(sp<Surface>& surface) {
375        mComposerClient = new SurfaceComposerClient;
376        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
377
378        mSurfaceControl = mComposerClient->createSurface(
379                String8("ProCameraTest StreamingImage Surface"),
380                getSurfaceWidth(), getSurfaceHeight(),
381                PIXEL_FORMAT_RGB_888, 0);
382
383        mSurfaceControl->setPosition(0, 0);
384
385        ASSERT_TRUE(mSurfaceControl != NULL);
386        ASSERT_TRUE(mSurfaceControl->isValid());
387
388        SurfaceComposerClient::openGlobalTransaction();
389        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
390        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
391        SurfaceComposerClient::closeGlobalTransaction();
392
393        sp<ANativeWindow> window = mSurfaceControl->getSurface();
394        surface = mSurfaceControl->getSurface();
395
396        ASSERT_NE((void*)NULL, surface.get());
397    }
398
399    void createDepthOnScreenSurface(sp<Surface>& surface) {
400        mDepthComposerClient = new SurfaceComposerClient;
401        ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
402
403        mDepthSurfaceControl = mDepthComposerClient->createSurface(
404                String8("ProCameraTest StreamingImage Surface"),
405                getSurfaceWidth(), getSurfaceHeight(),
406                PIXEL_FORMAT_RGB_888, 0);
407
408        mDepthSurfaceControl->setPosition(640, 0);
409
410        ASSERT_TRUE(mDepthSurfaceControl != NULL);
411        ASSERT_TRUE(mDepthSurfaceControl->isValid());
412
413        SurfaceComposerClient::openGlobalTransaction();
414        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
415        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
416        SurfaceComposerClient::closeGlobalTransaction();
417
418        sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
419        surface = mDepthSurfaceControl->getSurface();
420
421        ASSERT_NE((void*)NULL, surface.get());
422    }
423
424    template <typename T>
425    static bool ExistsItem(T needle, T* array, size_t count) {
426        if (!array) {
427            return false;
428        }
429
430        for (size_t i = 0; i < count; ++i) {
431            if (array[i] == needle) {
432                return true;
433            }
434        }
435        return false;
436    }
437
438
439    static int FormatFromString(const char* str) {
440        std::string s(str);
441
442#define CMP_STR(x, y)                               \
443        if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
444#define CMP_STR_SAME(x) CMP_STR(x, x)
445
446        CMP_STR_SAME( Y16);
447        CMP_STR_SAME( Y8);
448        CMP_STR_SAME( YV12);
449        CMP_STR(NV16, YCbCr_422_SP);
450        CMP_STR(NV21, YCrCb_420_SP);
451        CMP_STR(YUY2, YCbCr_422_I);
452        CMP_STR(RAW,  RAW_SENSOR);
453        CMP_STR(RGBA, RGBA_8888);
454
455        std::cerr << "Unknown format string " << str << std::endl;
456        return -1;
457
458    }
459
460    /**
461     * Creating a streaming request for these output streams from a template,
462     *  and submit it
463     */
464    void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
465
466        ASSERT_NE((void*)NULL, streamIds);
467        ASSERT_LT(0u, count);
468
469        camera_metadata_t *requestTmp = NULL;
470        EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
471                                                /*out*/&requestTmp));
472        ASSERT_NE((void*)NULL, requestTmp);
473        CameraMetadata request(requestTmp);
474
475        // set the output streams. default is empty
476
477        uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
478        request.update(tag, streamIds, count);
479
480        requestTmp = request.release();
481
482        if (requestCount < 0) {
483            EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
484        } else {
485            for (int i = 0; i < requestCount; ++i) {
486                EXPECT_OK(mCamera->submitRequest(requestTmp,
487                                                 /*streaming*/false));
488            }
489        }
490        request.acquire(requestTmp);
491    }
492};
493
494sp<Thread> ProCameraTest::mTestThread;
495
496TEST_F(ProCameraTest, AvailableFormats) {
497    if (HasFatalFailure()) {
498        return;
499    }
500
501    CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
502    ASSERT_FALSE(staticInfo.isEmpty());
503
504    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
505    EXPECT_TRUE(staticInfo.exists(tag));
506    camera_metadata_entry_t entry = staticInfo.find(tag);
507
508    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
509                                                  entry.data.i32, entry.count));
510    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
511                                                  entry.data.i32, entry.count));
512}
513
514// test around exclusiveTryLock (immediate locking)
515TEST_F(ProCameraTest, LockingImmediate) {
516
517    if (HasFatalFailure()) {
518        return;
519    }
520
521    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
522                            ProEvent_Mask(STOLEN)   |
523                            ProEvent_Mask(RELEASED));
524
525    EXPECT_FALSE(mCamera->hasExclusiveLock());
526    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
527    // at this point we definitely have the lock
528
529    EXPECT_EQ(OK, mListener->WaitForEvent());
530    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
531
532    EXPECT_TRUE(mCamera->hasExclusiveLock());
533    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
534
535    EXPECT_EQ(OK, mListener->WaitForEvent());
536    EXPECT_EQ(RELEASED, mListener->ReadEvent());
537
538    EXPECT_FALSE(mCamera->hasExclusiveLock());
539}
540
541// test around exclusiveLock (locking at some future point in time)
542TEST_F(ProCameraTest, LockingAsynchronous) {
543
544    if (HasFatalFailure()) {
545        return;
546    }
547
548
549    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
550                            ProEvent_Mask(STOLEN)   |
551                            ProEvent_Mask(RELEASED));
552
553    // TODO: Add another procamera that has a lock here.
554    // then we can be test that the lock wont immediately be acquired
555
556    EXPECT_FALSE(mCamera->hasExclusiveLock());
557    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
558    // at this point we definitely have the lock
559
560    EXPECT_EQ(OK, mListener->WaitForEvent());
561    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
562
563    EXPECT_TRUE(mCamera->hasExclusiveLock());
564    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
565
566    EXPECT_EQ(OK, mListener->WaitForEvent());
567    EXPECT_EQ(RELEASED, mListener->ReadEvent());
568
569    EXPECT_FALSE(mCamera->hasExclusiveLock());
570}
571
572// Stream directly to the screen.
573TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
574    if (HasFatalFailure()) {
575        return;
576    }
577
578    sp<Surface> surface;
579    if (mDisplaySecs > 0) {
580        createOnScreenSurface(/*out*/surface);
581    }
582    else {
583        dout << "Skipping, will not render to screen" << std::endl;
584        return;
585    }
586
587    int depthStreamId = -1;
588
589    sp<ServiceListener> listener = new ServiceListener();
590    EXPECT_OK(ProCamera::addServiceListener(listener));
591
592    ServiceListener::Status currentStatus = ServiceListener::STATUS_AVAILABLE;
593
594    dout << "Will now stream and resume infinitely..." << std::endl;
595    while (true) {
596
597        if (currentStatus == ServiceListener::STATUS_AVAILABLE) {
598
599            EXPECT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
600                                            surface,
601                                            &depthStreamId));
602            EXPECT_NE(-1, depthStreamId);
603
604            EXPECT_OK(mCamera->exclusiveTryLock());
605
606            uint8_t streams[] = { depthStreamId };
607            ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
608                                                 streams,
609                                                 /*count*/1));
610        }
611
612        ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
613
614        // TODO: maybe check for getch every once in a while?
615        while (listener->waitForStatusChange(/*out*/stat) != OK);
616
617        if (currentStatus != stat) {
618            if (stat == ServiceListener::STATUS_AVAILABLE) {
619                dout << "Reconnecting to camera" << std::endl;
620                mCamera = ProCamera::connect(CAMERA_ID);
621            } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
622                dout << "Disconnecting from camera" << std::endl;
623                mCamera->disconnect();
624            } else {
625                dout << "Unknown status change "
626                     << std::hex << stat << std::endl;
627            }
628
629            currentStatus = stat;
630        }
631    }
632
633    EXPECT_OK(ProCamera::removeServiceListener(listener));
634    EXPECT_OK(mCamera->deleteStream(depthStreamId));
635    EXPECT_OK(mCamera->exclusiveUnlock());
636}
637
638// Stream directly to the screen.
639TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
640    if (HasFatalFailure()) {
641        return;
642    }
643    sp<Surface> surface;
644    sp<Surface> depthSurface;
645    if (mDisplaySecs > 0) {
646        createOnScreenSurface(/*out*/surface);
647        createDepthOnScreenSurface(/*out*/depthSurface);
648    }
649
650    int streamId = -1;
651    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
652              TEST_FORMAT_MAIN, surface, &streamId));
653    EXPECT_NE(-1, streamId);
654
655    int depthStreamId = -1;
656    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
657              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
658    EXPECT_NE(-1, depthStreamId);
659
660    EXPECT_OK(mCamera->exclusiveTryLock());
661    /*
662    */
663    /* iterate in a loop submitting requests every frame.
664     *  what kind of requests doesnt really matter, just whatever.
665     */
666
667    // it would probably be better to use CameraMetadata from camera service.
668    camera_metadata_t *request = NULL;
669    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
670              /*out*/&request));
671    EXPECT_NE((void*)NULL, request);
672
673    /*FIXME: dont need this later, at which point the above should become an
674             ASSERT_NE*/
675    if(request == NULL) request = allocate_camera_metadata(10, 100);
676
677    // set the output streams to just this stream ID
678
679    // wow what a verbose API.
680    uint8_t allStreams[] = { streamId, depthStreamId };
681    // IMPORTANT. bad things will happen if its not a uint8.
682    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
683    camera_metadata_entry_t entry;
684    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
685    int find = find_camera_metadata_entry(request, tag, &entry);
686    if (find == -ENOENT) {
687        if (add_camera_metadata_entry(request, tag, &allStreams,
688                                      /*data_count*/streamCount) != OK) {
689            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
690            ASSERT_OK(append_camera_metadata(tmp, request));
691            free_camera_metadata(request);
692            request = tmp;
693
694            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
695                                                /*data_count*/streamCount));
696        }
697    } else {
698        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
699                  &allStreams, /*data_count*/streamCount, &entry));
700    }
701
702    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
703
704    dout << "will sleep now for " << mDisplaySecs << std::endl;
705    sleep(mDisplaySecs);
706
707    free_camera_metadata(request);
708
709    for (int i = 0; i < streamCount; ++i) {
710        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
711    }
712    EXPECT_OK(mCamera->exclusiveUnlock());
713}
714
715TEST_F(ProCameraTest, CpuConsumerSingle) {
716    if (HasFatalFailure()) {
717        return;
718    }
719
720    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
721
722    int streamId = -1;
723    sp<CpuConsumer> consumer;
724    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
725                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
726    EXPECT_NE(-1, streamId);
727
728    EXPECT_OK(mCamera->exclusiveTryLock());
729    EXPECT_EQ(OK, mListener->WaitForEvent());
730    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
731    /* iterate in a loop submitting requests every frame.
732     *  what kind of requests doesnt really matter, just whatever.
733     */
734
735    // it would probably be better to use CameraMetadata from camera service.
736    camera_metadata_t *request = NULL;
737    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
738        /*out*/&request));
739    EXPECT_NE((void*)NULL, request);
740
741    /*FIXME: dont need this later, at which point the above should become an
742      ASSERT_NE*/
743    if(request == NULL) request = allocate_camera_metadata(10, 100);
744
745    // set the output streams to just this stream ID
746
747    uint8_t allStreams[] = { streamId };
748    camera_metadata_entry_t entry;
749    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
750    int find = find_camera_metadata_entry(request, tag, &entry);
751    if (find == -ENOENT) {
752        if (add_camera_metadata_entry(request, tag, &allStreams,
753                /*data_count*/1) != OK) {
754            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
755            ASSERT_OK(append_camera_metadata(tmp, request));
756            free_camera_metadata(request);
757            request = tmp;
758
759            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
760                /*data_count*/1));
761        }
762    } else {
763        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
764            &allStreams, /*data_count*/1, &entry));
765    }
766
767    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
768
769    // Consume a couple of frames
770    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
771        EXPECT_EQ(OK, mListener->WaitForEvent());
772        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
773    }
774
775    // Done: clean up
776    free_camera_metadata(request);
777    EXPECT_OK(mCamera->deleteStream(streamId));
778    EXPECT_OK(mCamera->exclusiveUnlock());
779}
780
781TEST_F(ProCameraTest, CpuConsumerDual) {
782    if (HasFatalFailure()) {
783        return;
784    }
785
786    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
787
788    int streamId = -1;
789    sp<CpuConsumer> consumer;
790    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
791                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
792    EXPECT_NE(-1, streamId);
793
794    int depthStreamId = -1;
795    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
796            TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
797    EXPECT_NE(-1, depthStreamId);
798
799    EXPECT_OK(mCamera->exclusiveTryLock());
800    /*
801    */
802    /* iterate in a loop submitting requests every frame.
803     *  what kind of requests doesnt really matter, just whatever.
804     */
805
806    // it would probably be better to use CameraMetadata from camera service.
807    camera_metadata_t *request = NULL;
808    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
809                                            /*out*/&request));
810    EXPECT_NE((void*)NULL, request);
811
812    if(request == NULL) request = allocate_camera_metadata(10, 100);
813
814    // set the output streams to just this stream ID
815
816    // wow what a verbose API.
817    uint8_t allStreams[] = { streamId, depthStreamId };
818    size_t streamCount = 2;
819    camera_metadata_entry_t entry;
820    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
821    int find = find_camera_metadata_entry(request, tag, &entry);
822    if (find == -ENOENT) {
823        if (add_camera_metadata_entry(request, tag, &allStreams,
824                                      /*data_count*/streamCount) != OK) {
825            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
826            ASSERT_OK(append_camera_metadata(tmp, request));
827            free_camera_metadata(request);
828            request = tmp;
829
830            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
831                                                   /*data_count*/streamCount));
832        }
833    } else {
834        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
835                              &allStreams, /*data_count*/streamCount, &entry));
836    }
837
838    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
839
840    // Consume a couple of frames
841    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
842        // stream id 1
843        EXPECT_EQ(OK, mListener->WaitForEvent());
844        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
845
846        // stream id 2
847        EXPECT_EQ(OK, mListener->WaitForEvent());
848        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
849
850        //TODO: events should be a struct with some data like the stream id
851    }
852
853    // Done: clean up
854    free_camera_metadata(request);
855    EXPECT_OK(mCamera->deleteStream(streamId));
856    EXPECT_OK(mCamera->exclusiveUnlock());
857}
858
859TEST_F(ProCameraTest, ResultReceiver) {
860    if (HasFatalFailure()) {
861        return;
862    }
863
864    mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
865    //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
866    // need to filter out events at read time
867
868    int streamId = -1;
869    sp<CpuConsumer> consumer;
870    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
871                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
872    EXPECT_NE(-1, streamId);
873
874    EXPECT_OK(mCamera->exclusiveTryLock());
875    /*
876    */
877    /* iterate in a loop submitting requests every frame.
878     *  what kind of requests doesnt really matter, just whatever.
879     */
880
881    camera_metadata_t *request = NULL;
882    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
883                                            /*out*/&request));
884    EXPECT_NE((void*)NULL, request);
885
886    /*FIXME*/
887    if(request == NULL) request = allocate_camera_metadata(10, 100);
888
889    // set the output streams to just this stream ID
890
891    uint8_t allStreams[] = { streamId };
892    size_t streamCount = 1;
893    camera_metadata_entry_t entry;
894    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
895    int find = find_camera_metadata_entry(request, tag, &entry);
896    if (find == -ENOENT) {
897        if (add_camera_metadata_entry(request, tag, &allStreams,
898                                      /*data_count*/streamCount) != OK) {
899            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
900            ASSERT_OK(append_camera_metadata(tmp, request));
901            free_camera_metadata(request);
902            request = tmp;
903
904            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
905                                                /*data_count*/streamCount));
906        }
907    } else {
908        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
909                               &allStreams, /*data_count*/streamCount, &entry));
910    }
911
912    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
913
914    // Consume a couple of results
915    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
916        EXPECT_EQ(OK, mListener->WaitForEvent());
917        EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
918    }
919
920    // Done: clean up
921    free_camera_metadata(request);
922    EXPECT_OK(mCamera->deleteStream(streamId));
923    EXPECT_OK(mCamera->exclusiveUnlock());
924}
925
926TEST_F(ProCameraTest, WaitForResult) {
927    if (HasFatalFailure()) {
928        return;
929    }
930
931    int streamId = -1;
932    sp<CpuConsumer> consumer;
933    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
934                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
935    EXPECT_NE(-1, streamId);
936
937    EXPECT_OK(mCamera->exclusiveTryLock());
938
939    uint8_t streams[] = { streamId };
940    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
941
942    // Consume a couple of results
943    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
944        EXPECT_OK(mCamera->waitForFrameMetadata());
945        CameraMetadata meta = mCamera->consumeFrameMetadata();
946        EXPECT_FALSE(meta.isEmpty());
947    }
948
949    // Done: clean up
950    consumer->abandon(); // since we didn't consume any of the buffers
951    EXPECT_OK(mCamera->deleteStream(streamId));
952    EXPECT_OK(mCamera->exclusiveUnlock());
953}
954
955TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
956    if (HasFatalFailure()) {
957        return;
958    }
959
960    int streamId = -1;
961    sp<CpuConsumer> consumer;
962    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
963                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
964    EXPECT_NE(-1, streamId);
965
966    EXPECT_OK(mCamera->exclusiveTryLock());
967
968    uint8_t streams[] = { streamId };
969    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
970                                            /*requests*/TEST_CPU_FRAME_COUNT));
971
972    // Consume a couple of results
973    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
974        EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));
975
976        CpuConsumer::LockedBuffer buf;
977        EXPECT_OK(consumer->lockNextBuffer(&buf));
978
979        dout << "Buffer synchronously received on streamId = " << streamId <<
980                ", dataPtr = " << (void*)buf.data <<
981                ", timestamp = " << buf.timestamp << std::endl;
982
983        EXPECT_OK(consumer->unlockBuffer(buf));
984    }
985
986    // Done: clean up
987    EXPECT_OK(mCamera->deleteStream(streamId));
988    EXPECT_OK(mCamera->exclusiveUnlock());
989}
990
991TEST_F(ProCameraTest, WaitForDualStreamBuffer) {
992    if (HasFatalFailure()) {
993        return;
994    }
995
996    const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
997
998    // 15 fps
999    int streamId = -1;
1000    sp<CpuConsumer> consumer;
1001    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1002                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1003    EXPECT_NE(-1, streamId);
1004
1005    // 30 fps
1006    int depthStreamId = -1;
1007    sp<CpuConsumer> depthConsumer;
1008    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
1009       TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
1010    EXPECT_NE(-1, depthStreamId);
1011
1012    EXPECT_OK(mCamera->exclusiveTryLock());
1013
1014    uint8_t streams[] = { streamId, depthStreamId };
1015    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
1016                                                    /*requests*/REQUEST_COUNT));
1017
1018    // Consume two frames simultaneously. Unsynchronized by timestamps.
1019    for (int i = 0; i < REQUEST_COUNT; ++i) {
1020
1021        // Get the metadata
1022        EXPECT_OK(mCamera->waitForFrameMetadata());
1023        CameraMetadata meta = mCamera->consumeFrameMetadata();
1024        EXPECT_FALSE(meta.isEmpty());
1025
1026        // Get the buffers
1027
1028        EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));
1029
1030        /**
1031          * Guaranteed to be able to consume the depth frame,
1032          * since we waited on it.
1033          */
1034        CpuConsumer::LockedBuffer depthBuffer;
1035        EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
1036
1037        dout << "Depth Buffer synchronously received on streamId = " <<
1038                streamId <<
1039                ", dataPtr = " << (void*)depthBuffer.data <<
1040                ", timestamp = " << depthBuffer.timestamp << std::endl;
1041
1042        EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
1043
1044
1045        /** Consume Greyscale frames if there are any.
1046          * There may not be since it runs at half FPS */
1047        CpuConsumer::LockedBuffer greyBuffer;
1048        while (consumer->lockNextBuffer(&greyBuffer) == OK) {
1049
1050            dout << "GRAY Buffer synchronously received on streamId = " <<
1051                streamId <<
1052                ", dataPtr = " << (void*)greyBuffer.data <<
1053                ", timestamp = " << greyBuffer.timestamp << std::endl;
1054
1055            EXPECT_OK(consumer->unlockBuffer(greyBuffer));
1056        }
1057    }
1058
1059    // Done: clean up
1060    EXPECT_OK(mCamera->deleteStream(streamId));
1061    EXPECT_OK(mCamera->exclusiveUnlock());
1062}
1063
1064TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) {
1065    if (HasFatalFailure()) {
1066        return;
1067    }
1068
1069    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1070
1071    int streamId = -1;
1072    sp<CpuConsumer> consumer;
1073    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1074                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1075    EXPECT_NE(-1, streamId);
1076
1077    EXPECT_OK(mCamera->exclusiveTryLock());
1078
1079    uint8_t streams[] = { streamId };
1080    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1081                                                     /*requests*/NUM_REQUESTS));
1082
1083    // Consume a couple of results
1084    for (int i = 0; i < NUM_REQUESTS; ++i) {
1085        int numFrames;
1086        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1087
1088        // Drop all but the newest framebuffer
1089        EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1090
1091        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1092
1093        // Skip the counter ahead, don't try to consume these frames again
1094        i += numFrames-1;
1095
1096        // "Consume" the buffer
1097        CpuConsumer::LockedBuffer buf;
1098        EXPECT_OK(consumer->lockNextBuffer(&buf));
1099
1100        dout << "Buffer synchronously received on streamId = " << streamId <<
1101                ", dataPtr = " << (void*)buf.data <<
1102                ", timestamp = " << buf.timestamp << std::endl;
1103
1104        // Process at 10fps, stream is at 15fps.
1105        // This means we will definitely fill up the buffer queue with
1106        // extra buffers and need to drop them.
1107        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1108
1109        EXPECT_OK(consumer->unlockBuffer(buf));
1110    }
1111
1112    // Done: clean up
1113    EXPECT_OK(mCamera->deleteStream(streamId));
1114    EXPECT_OK(mCamera->exclusiveUnlock());
1115}
1116
1117
1118
1119//TODO: refactor into separate file
1120TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1121
1122    ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1123
1124    sp<ServiceListener> listener = new ServiceListener();
1125
1126    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1127    EXPECT_OK(ProCamera::addServiceListener(listener));
1128
1129    EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1130    EXPECT_OK(ProCamera::removeServiceListener(listener));
1131
1132    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1133}
1134
1135//TODO: refactor into separate file
1136TEST_F(ProCameraTest, ServiceListenersFunctional) {
1137
1138    sp<ServiceListener> listener = new ServiceListener();
1139
1140    EXPECT_OK(ProCamera::addServiceListener(listener));
1141
1142    sp<Camera> cam = Camera::connect(CAMERA_ID,
1143                                     /*clientPackageName*/String16(),
1144                                     -1);
1145    EXPECT_NE((void*)NULL, cam.get());
1146
1147    ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1148    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1149
1150    EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1151
1152    if (cam.get()) {
1153        cam->disconnect();
1154    }
1155
1156    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1157    EXPECT_EQ(ServiceListener::STATUS_AVAILABLE, stat);
1158
1159    EXPECT_OK(ProCamera::removeServiceListener(listener));
1160}
1161
1162
1163
1164}
1165}
1166}
1167}
1168
1169