ProCameraTests.cpp revision c8e19c1dadedf53710eab211e14daf723ec66705
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             << (unsigned int) 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    FRAME_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        mDropFrames = false;
162    }
163
164    status_t WaitForEvent() {
165        Mutex::Autolock cal(mConditionMutex);
166
167        {
168            Mutex::Autolock al(mListenerMutex);
169
170            if (mProEventList.size() > 0) {
171                return OK;
172            }
173        }
174
175        return mListenerCondition.waitRelative(mConditionMutex,
176                                               TEST_LISTENER_TIMEOUT);
177    }
178
179    /* Read events into out. Existing queue is flushed */
180    void ReadEvents(EventList& out) {
181        Mutex::Autolock al(mListenerMutex);
182
183        for (size_t i = 0; i < mProEventList.size(); ++i) {
184            out.push(mProEventList[i]);
185        }
186
187        mProEventList.clear();
188    }
189
190    /**
191      * Dequeue 1 event from the event queue.
192      * Returns UNKNOWN if queue is empty
193      */
194    ProEvent ReadEvent() {
195        Mutex::Autolock al(mListenerMutex);
196
197        if (mProEventList.size() == 0) {
198            return UNKNOWN;
199        }
200
201        ProEvent ev = mProEventList[0];
202        mProEventList.removeAt(0);
203
204        return ev;
205    }
206
207    void SetEventMask(int eventMask) {
208        Mutex::Autolock al(mListenerMutex);
209        mEventMask = eventMask;
210    }
211
212    // Automatically acquire/release frames as they are available
213    void SetDropFrames(bool dropFrames) {
214        Mutex::Autolock al(mListenerMutex);
215        mDropFrames = dropFrames;
216    }
217
218private:
219    void QueueEvent(ProEvent ev) {
220        bool eventAdded = false;
221        {
222            Mutex::Autolock al(mListenerMutex);
223
224            // Drop events not part of mask
225            if (ProEvent_Mask(ev) & mEventMask) {
226                mProEventList.push(ev);
227                eventAdded = true;
228            }
229        }
230
231        if (eventAdded) {
232            mListenerCondition.broadcast();
233        }
234    }
235
236protected:
237
238    //////////////////////////////////////////////////
239    ///////// ProCameraListener //////////////////////
240    //////////////////////////////////////////////////
241
242
243    // Lock has been acquired. Write operations now available.
244    virtual void onLockAcquired() {
245        QueueEvent(ACQUIRED);
246    }
247    // Lock has been released with exclusiveUnlock
248    virtual void onLockReleased() {
249        QueueEvent(RELEASED);
250    }
251
252    // Lock has been stolen by another client.
253    virtual void onLockStolen() {
254        QueueEvent(STOLEN);
255    }
256
257    // Lock free.
258    virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
259
260        dout << "Trigger notify: " << ext1 << " " << ext2
261             << " " << ext3 << std::endl;
262    }
263
264    virtual void onFrameAvailable(int streamId,
265                                  const sp<CpuConsumer>& consumer) {
266
267        QueueEvent(FRAME_RECEIVED);
268
269        Mutex::Autolock al(mListenerMutex);
270        if (mDropFrames) {
271            CpuConsumer::LockedBuffer buf;
272            status_t ret;
273
274            EXPECT_OK(ret);
275            if (OK == (ret = consumer->lockNextBuffer(&buf))) {
276
277                dout << "Frame received on streamId = " << streamId <<
278                        ", dataPtr = " << (void*)buf.data <<
279                        ", timestamp = " << buf.timestamp << std::endl;
280
281                EXPECT_OK(consumer->unlockBuffer(buf));
282            }
283        } else {
284            dout << "Frame received on streamId = " << streamId << std::endl;
285        }
286    }
287
288    virtual void onResultReceived(int32_t frameId,
289                                  camera_metadata* request) {
290        dout << "Result received frameId = " << frameId
291             << ", requestPtr = " << (void*)request << std::endl;
292        QueueEvent(RESULT_RECEIVED);
293        free_camera_metadata(request);
294    }
295
296    virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
297        dout << "Notify received: msg " << std::hex << msg
298             << ", ext1: " << std::hex << ext1 << ", ext2: " << std::hex << ext2
299             << std::endl;
300    }
301
302    Vector<ProEvent> mProEventList;
303    Mutex             mListenerMutex;
304    Mutex             mConditionMutex;
305    Condition         mListenerCondition;
306    int               mEventMask;
307    bool              mDropFrames;
308};
309
310class ProCameraTest : public ::testing::Test {
311
312public:
313    ProCameraTest() {
314        char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
315        if (displaySecsEnv != NULL) {
316            mDisplaySecs = atoi(displaySecsEnv);
317            if (mDisplaySecs < 0) {
318                mDisplaySecs = 0;
319            }
320        } else {
321            mDisplaySecs = 0;
322        }
323
324        char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
325        if (displayFmtEnv != NULL) {
326            mDisplayFmt = FormatFromString(displayFmtEnv);
327        } else {
328            mDisplayFmt = TEST_DISPLAY_FORMAT;
329        }
330
331        char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
332        if (displayWidthEnv != NULL) {
333            mDisplayW = atoi(displayWidthEnv);
334            if (mDisplayW < 0) {
335                mDisplayW = 0;
336            }
337        } else {
338            mDisplayW = TEST_DISPLAY_WIDTH;
339        }
340
341        char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
342        if (displayHeightEnv != NULL) {
343            mDisplayH = atoi(displayHeightEnv);
344            if (mDisplayH < 0) {
345                mDisplayH = 0;
346            }
347        } else {
348            mDisplayH = TEST_DISPLAY_HEIGHT;
349        }
350    }
351
352    static void SetUpTestCase() {
353        // Binder Thread Pool Initialization
354        mTestThread = new ProCameraTestThread();
355        mTestThread->run("ProCameraTestThread");
356    }
357
358    virtual void SetUp() {
359        mCamera = ProCamera::connect(CAMERA_ID);
360        ASSERT_NE((void*)NULL, mCamera.get());
361
362        mListener = new ProCameraTestListener();
363        mCamera->setListener(mListener);
364    }
365
366    virtual void TearDown() {
367        ASSERT_NE((void*)NULL, mCamera.get());
368        mCamera->disconnect();
369    }
370
371protected:
372    sp<ProCamera> mCamera;
373    sp<ProCameraTestListener> mListener;
374
375    static sp<Thread> mTestThread;
376
377    int mDisplaySecs;
378    int mDisplayFmt;
379    int mDisplayW;
380    int mDisplayH;
381
382    sp<SurfaceComposerClient> mComposerClient;
383    sp<SurfaceControl> mSurfaceControl;
384
385    sp<SurfaceComposerClient> mDepthComposerClient;
386    sp<SurfaceControl> mDepthSurfaceControl;
387
388    int getSurfaceWidth() {
389        return 512;
390    }
391    int getSurfaceHeight() {
392        return 512;
393    }
394
395    void createOnScreenSurface(sp<Surface>& surface) {
396        mComposerClient = new SurfaceComposerClient;
397        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
398
399        mSurfaceControl = mComposerClient->createSurface(
400                String8("ProCameraTest StreamingImage Surface"),
401                getSurfaceWidth(), getSurfaceHeight(),
402                PIXEL_FORMAT_RGB_888, 0);
403
404        mSurfaceControl->setPosition(0, 0);
405
406        ASSERT_TRUE(mSurfaceControl != NULL);
407        ASSERT_TRUE(mSurfaceControl->isValid());
408
409        SurfaceComposerClient::openGlobalTransaction();
410        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
411        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
412        SurfaceComposerClient::closeGlobalTransaction();
413
414        sp<ANativeWindow> window = mSurfaceControl->getSurface();
415        surface = mSurfaceControl->getSurface();
416
417        ASSERT_NE((void*)NULL, surface.get());
418    }
419
420    void createDepthOnScreenSurface(sp<Surface>& surface) {
421        mDepthComposerClient = new SurfaceComposerClient;
422        ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
423
424        mDepthSurfaceControl = mDepthComposerClient->createSurface(
425                String8("ProCameraTest StreamingImage Surface"),
426                getSurfaceWidth(), getSurfaceHeight(),
427                PIXEL_FORMAT_RGB_888, 0);
428
429        mDepthSurfaceControl->setPosition(640, 0);
430
431        ASSERT_TRUE(mDepthSurfaceControl != NULL);
432        ASSERT_TRUE(mDepthSurfaceControl->isValid());
433
434        SurfaceComposerClient::openGlobalTransaction();
435        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
436        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
437        SurfaceComposerClient::closeGlobalTransaction();
438
439        sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
440        surface = mDepthSurfaceControl->getSurface();
441
442        ASSERT_NE((void*)NULL, surface.get());
443    }
444
445    template <typename T>
446    static bool ExistsItem(T needle, T* array, size_t count) {
447        if (!array) {
448            return false;
449        }
450
451        for (size_t i = 0; i < count; ++i) {
452            if (array[i] == needle) {
453                return true;
454            }
455        }
456        return false;
457    }
458
459
460    static int FormatFromString(const char* str) {
461        std::string s(str);
462
463#define CMP_STR(x, y)                               \
464        if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
465#define CMP_STR_SAME(x) CMP_STR(x, x)
466
467        CMP_STR_SAME( Y16);
468        CMP_STR_SAME( Y8);
469        CMP_STR_SAME( YV12);
470        CMP_STR(NV16, YCbCr_422_SP);
471        CMP_STR(NV21, YCrCb_420_SP);
472        CMP_STR(YUY2, YCbCr_422_I);
473        CMP_STR(RAW,  RAW_SENSOR);
474        CMP_STR(RGBA, RGBA_8888);
475
476        std::cerr << "Unknown format string " << str << std::endl;
477        return -1;
478
479    }
480
481    /**
482     * Creating a streaming request for these output streams from a template,
483     *  and submit it
484     */
485    void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
486
487        ASSERT_NE((void*)NULL, streamIds);
488        ASSERT_LT(0u, count);
489
490        camera_metadata_t *requestTmp = NULL;
491        EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
492                                                /*out*/&requestTmp));
493        ASSERT_NE((void*)NULL, requestTmp);
494        CameraMetadata request(requestTmp);
495
496        // set the output streams. default is empty
497
498        uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
499        request.update(tag, streamIds, count);
500
501        requestTmp = request.release();
502
503        if (requestCount < 0) {
504            EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
505        } else {
506            for (int i = 0; i < requestCount; ++i) {
507                EXPECT_OK(mCamera->submitRequest(requestTmp,
508                                                 /*streaming*/false));
509            }
510        }
511        request.acquire(requestTmp);
512    }
513};
514
515sp<Thread> ProCameraTest::mTestThread;
516
517TEST_F(ProCameraTest, AvailableFormats) {
518    if (HasFatalFailure()) {
519        return;
520    }
521
522    CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
523    ASSERT_FALSE(staticInfo.isEmpty());
524
525    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
526    EXPECT_TRUE(staticInfo.exists(tag));
527    camera_metadata_entry_t entry = staticInfo.find(tag);
528
529    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
530                                                  entry.data.i32, entry.count));
531    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
532                                                  entry.data.i32, entry.count));
533}
534
535// test around exclusiveTryLock (immediate locking)
536TEST_F(ProCameraTest, LockingImmediate) {
537
538    if (HasFatalFailure()) {
539        return;
540    }
541
542    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
543                            ProEvent_Mask(STOLEN)   |
544                            ProEvent_Mask(RELEASED));
545
546    EXPECT_FALSE(mCamera->hasExclusiveLock());
547    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
548    // at this point we definitely have the lock
549
550    EXPECT_EQ(OK, mListener->WaitForEvent());
551    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
552
553    EXPECT_TRUE(mCamera->hasExclusiveLock());
554    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
555
556    EXPECT_EQ(OK, mListener->WaitForEvent());
557    EXPECT_EQ(RELEASED, mListener->ReadEvent());
558
559    EXPECT_FALSE(mCamera->hasExclusiveLock());
560}
561
562// test around exclusiveLock (locking at some future point in time)
563TEST_F(ProCameraTest, LockingAsynchronous) {
564
565    if (HasFatalFailure()) {
566        return;
567    }
568
569
570    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
571                            ProEvent_Mask(STOLEN)   |
572                            ProEvent_Mask(RELEASED));
573
574    // TODO: Add another procamera that has a lock here.
575    // then we can be test that the lock wont immediately be acquired
576
577    EXPECT_FALSE(mCamera->hasExclusiveLock());
578    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
579    // at this point we definitely have the lock
580
581    EXPECT_EQ(OK, mListener->WaitForEvent());
582    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
583
584    EXPECT_TRUE(mCamera->hasExclusiveLock());
585    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
586
587    EXPECT_EQ(OK, mListener->WaitForEvent());
588    EXPECT_EQ(RELEASED, mListener->ReadEvent());
589
590    EXPECT_FALSE(mCamera->hasExclusiveLock());
591}
592
593// Stream directly to the screen.
594TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
595    if (HasFatalFailure()) {
596        return;
597    }
598
599    sp<Surface> surface;
600    if (mDisplaySecs > 0) {
601        createOnScreenSurface(/*out*/surface);
602    }
603    else {
604        dout << "Skipping, will not render to screen" << std::endl;
605        return;
606    }
607
608    int depthStreamId = -1;
609
610    sp<ServiceListener> listener = new ServiceListener();
611    EXPECT_OK(ProCamera::addServiceListener(listener));
612
613    ServiceListener::Status currentStatus;
614
615    // when subscribing a new listener,
616    // we immediately get a callback to the current status
617    while (listener->waitForStatusChange(/*out*/currentStatus) != OK);
618    EXPECT_EQ(ServiceListener::STATUS_PRESENT, currentStatus);
619
620    dout << "Will now stream and resume infinitely..." << std::endl;
621    while (true) {
622
623        if (currentStatus == ServiceListener::STATUS_PRESENT) {
624
625            ASSERT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
626                                            surface,
627                                            &depthStreamId));
628            EXPECT_NE(-1, depthStreamId);
629
630            EXPECT_OK(mCamera->exclusiveTryLock());
631
632            uint8_t streams[] = { depthStreamId };
633            ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
634                                                 streams,
635                                                 /*count*/1));
636        }
637
638        ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
639
640        // TODO: maybe check for getch every once in a while?
641        while (listener->waitForStatusChange(/*out*/stat) != OK);
642
643        if (currentStatus != stat) {
644            if (stat == ServiceListener::STATUS_PRESENT) {
645                dout << "Reconnecting to camera" << std::endl;
646                mCamera = ProCamera::connect(CAMERA_ID);
647            } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
648                dout << "Disconnecting from camera" << std::endl;
649                mCamera->disconnect();
650            } else if (stat == ServiceListener::STATUS_NOT_PRESENT) {
651                dout << "Camera unplugged" << std::endl;
652                mCamera = NULL;
653            } else {
654                dout << "Unknown status change "
655                     << std::hex << stat << std::endl;
656            }
657
658            currentStatus = stat;
659        }
660    }
661
662    EXPECT_OK(ProCamera::removeServiceListener(listener));
663    EXPECT_OK(mCamera->deleteStream(depthStreamId));
664    EXPECT_OK(mCamera->exclusiveUnlock());
665}
666
667// Stream directly to the screen.
668TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
669    if (HasFatalFailure()) {
670        return;
671    }
672    sp<Surface> surface;
673    sp<Surface> depthSurface;
674    if (mDisplaySecs > 0) {
675        createOnScreenSurface(/*out*/surface);
676        createDepthOnScreenSurface(/*out*/depthSurface);
677    }
678
679    int streamId = -1;
680    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
681              TEST_FORMAT_MAIN, surface, &streamId));
682    EXPECT_NE(-1, streamId);
683
684    int depthStreamId = -1;
685    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
686              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
687    EXPECT_NE(-1, depthStreamId);
688
689    EXPECT_OK(mCamera->exclusiveTryLock());
690    /*
691    */
692    /* iterate in a loop submitting requests every frame.
693     *  what kind of requests doesnt really matter, just whatever.
694     */
695
696    // it would probably be better to use CameraMetadata from camera service.
697    camera_metadata_t *request = NULL;
698    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
699              /*out*/&request));
700    EXPECT_NE((void*)NULL, request);
701
702    /*FIXME: dont need this later, at which point the above should become an
703             ASSERT_NE*/
704    if(request == NULL) request = allocate_camera_metadata(10, 100);
705
706    // set the output streams to just this stream ID
707
708    // wow what a verbose API.
709    uint8_t allStreams[] = { streamId, depthStreamId };
710    // IMPORTANT. bad things will happen if its not a uint8.
711    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
712    camera_metadata_entry_t entry;
713    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
714    int find = find_camera_metadata_entry(request, tag, &entry);
715    if (find == -ENOENT) {
716        if (add_camera_metadata_entry(request, tag, &allStreams,
717                                      /*data_count*/streamCount) != OK) {
718            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
719            ASSERT_OK(append_camera_metadata(tmp, request));
720            free_camera_metadata(request);
721            request = tmp;
722
723            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
724                                                /*data_count*/streamCount));
725        }
726    } else {
727        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
728                  &allStreams, /*data_count*/streamCount, &entry));
729    }
730
731    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
732
733    dout << "will sleep now for " << mDisplaySecs << std::endl;
734    sleep(mDisplaySecs);
735
736    free_camera_metadata(request);
737
738    for (int i = 0; i < streamCount; ++i) {
739        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
740    }
741    EXPECT_OK(mCamera->exclusiveUnlock());
742}
743
744TEST_F(ProCameraTest, CpuConsumerSingle) {
745    if (HasFatalFailure()) {
746        return;
747    }
748
749    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
750                            ProEvent_Mask(STOLEN)   |
751                            ProEvent_Mask(RELEASED) |
752                            ProEvent_Mask(FRAME_RECEIVED));
753    mListener->SetDropFrames(true);
754
755    int streamId = -1;
756    sp<CpuConsumer> consumer;
757    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
758                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
759    EXPECT_NE(-1, streamId);
760
761    EXPECT_OK(mCamera->exclusiveTryLock());
762    EXPECT_EQ(OK, mListener->WaitForEvent());
763    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
764    /* iterate in a loop submitting requests every frame.
765     *  what kind of requests doesnt really matter, just whatever.
766     */
767
768    // it would probably be better to use CameraMetadata from camera service.
769    camera_metadata_t *request = NULL;
770    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
771        /*out*/&request));
772    EXPECT_NE((void*)NULL, request);
773
774    /*FIXME: dont need this later, at which point the above should become an
775      ASSERT_NE*/
776    if(request == NULL) request = allocate_camera_metadata(10, 100);
777
778    // set the output streams to just this stream ID
779
780    uint8_t allStreams[] = { streamId };
781    camera_metadata_entry_t entry;
782    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
783    int find = find_camera_metadata_entry(request, tag, &entry);
784    if (find == -ENOENT) {
785        if (add_camera_metadata_entry(request, tag, &allStreams,
786                /*data_count*/1) != OK) {
787            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
788            ASSERT_OK(append_camera_metadata(tmp, request));
789            free_camera_metadata(request);
790            request = tmp;
791
792            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
793                /*data_count*/1));
794        }
795    } else {
796        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
797            &allStreams, /*data_count*/1, &entry));
798    }
799
800    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
801
802    // Consume a couple of frames
803    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
804        EXPECT_EQ(OK, mListener->WaitForEvent());
805        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
806    }
807
808    // Done: clean up
809    free_camera_metadata(request);
810    EXPECT_OK(mCamera->deleteStream(streamId));
811    EXPECT_OK(mCamera->exclusiveUnlock());
812}
813
814TEST_F(ProCameraTest, CpuConsumerDual) {
815    if (HasFatalFailure()) {
816        return;
817    }
818
819    mListener->SetEventMask(ProEvent_Mask(FRAME_RECEIVED));
820    mListener->SetDropFrames(true);
821
822    int streamId = -1;
823    sp<CpuConsumer> consumer;
824    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
825                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
826    EXPECT_NE(-1, streamId);
827
828    int depthStreamId = -1;
829    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
830            TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
831    EXPECT_NE(-1, depthStreamId);
832
833    EXPECT_OK(mCamera->exclusiveTryLock());
834    /*
835    */
836    /* iterate in a loop submitting requests every frame.
837     *  what kind of requests doesnt really matter, just whatever.
838     */
839
840    // it would probably be better to use CameraMetadata from camera service.
841    camera_metadata_t *request = NULL;
842    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
843                                            /*out*/&request));
844    EXPECT_NE((void*)NULL, request);
845
846    if(request == NULL) request = allocate_camera_metadata(10, 100);
847
848    // set the output streams to just this stream ID
849
850    // wow what a verbose API.
851    uint8_t allStreams[] = { streamId, depthStreamId };
852    size_t streamCount = 2;
853    camera_metadata_entry_t entry;
854    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
855    int find = find_camera_metadata_entry(request, tag, &entry);
856    if (find == -ENOENT) {
857        if (add_camera_metadata_entry(request, tag, &allStreams,
858                                      /*data_count*/streamCount) != OK) {
859            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
860            ASSERT_OK(append_camera_metadata(tmp, request));
861            free_camera_metadata(request);
862            request = tmp;
863
864            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
865                                                   /*data_count*/streamCount));
866        }
867    } else {
868        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
869                              &allStreams, /*data_count*/streamCount, &entry));
870    }
871
872    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
873
874    // Consume a couple of frames
875    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
876        // stream id 1
877        EXPECT_EQ(OK, mListener->WaitForEvent());
878        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
879
880        // stream id 2
881        EXPECT_EQ(OK, mListener->WaitForEvent());
882        EXPECT_EQ(FRAME_RECEIVED, mListener->ReadEvent());
883
884        //TODO: events should be a struct with some data like the stream id
885    }
886
887    // Done: clean up
888    free_camera_metadata(request);
889    EXPECT_OK(mCamera->deleteStream(streamId));
890    EXPECT_OK(mCamera->exclusiveUnlock());
891}
892
893TEST_F(ProCameraTest, ResultReceiver) {
894    if (HasFatalFailure()) {
895        return;
896    }
897
898    mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
899    mListener->SetDropFrames(true);
900    //FIXME: if this is run right after the previous test we get FRAME_RECEIVED
901    // need to filter out events at read time
902
903    int streamId = -1;
904    sp<CpuConsumer> consumer;
905    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
906                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
907    EXPECT_NE(-1, streamId);
908
909    EXPECT_OK(mCamera->exclusiveTryLock());
910    /*
911    */
912    /* iterate in a loop submitting requests every frame.
913     *  what kind of requests doesnt really matter, just whatever.
914     */
915
916    camera_metadata_t *request = NULL;
917    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
918                                            /*out*/&request));
919    EXPECT_NE((void*)NULL, request);
920
921    /*FIXME*/
922    if(request == NULL) request = allocate_camera_metadata(10, 100);
923
924    // set the output streams to just this stream ID
925
926    uint8_t allStreams[] = { streamId };
927    size_t streamCount = 1;
928    camera_metadata_entry_t entry;
929    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
930    int find = find_camera_metadata_entry(request, tag, &entry);
931    if (find == -ENOENT) {
932        if (add_camera_metadata_entry(request, tag, &allStreams,
933                                      /*data_count*/streamCount) != OK) {
934            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
935            ASSERT_OK(append_camera_metadata(tmp, request));
936            free_camera_metadata(request);
937            request = tmp;
938
939            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
940                                                /*data_count*/streamCount));
941        }
942    } else {
943        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
944                               &allStreams, /*data_count*/streamCount, &entry));
945    }
946
947    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
948
949    // Consume a couple of results
950    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
951        EXPECT_EQ(OK, mListener->WaitForEvent());
952        EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
953    }
954
955    // Done: clean up
956    free_camera_metadata(request);
957    EXPECT_OK(mCamera->deleteStream(streamId));
958    EXPECT_OK(mCamera->exclusiveUnlock());
959}
960
961// FIXME: This is racy and sometimes fails on waitForFrameMetadata
962TEST_F(ProCameraTest, DISABLED_WaitForResult) {
963    if (HasFatalFailure()) {
964        return;
965    }
966
967    mListener->SetDropFrames(true);
968
969    int streamId = -1;
970    sp<CpuConsumer> consumer;
971    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
972                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
973    EXPECT_NE(-1, streamId);
974
975    EXPECT_OK(mCamera->exclusiveTryLock());
976
977    uint8_t streams[] = { streamId };
978    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
979
980    // Consume a couple of results
981    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
982        EXPECT_OK(mCamera->waitForFrameMetadata());
983        CameraMetadata meta = mCamera->consumeFrameMetadata();
984        EXPECT_FALSE(meta.isEmpty());
985    }
986
987    // Done: clean up
988    EXPECT_OK(mCamera->deleteStream(streamId));
989    EXPECT_OK(mCamera->exclusiveUnlock());
990}
991
992TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
993    if (HasFatalFailure()) {
994        return;
995    }
996
997    int streamId = -1;
998    sp<CpuConsumer> consumer;
999    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1000                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1001    EXPECT_NE(-1, streamId);
1002
1003    EXPECT_OK(mCamera->exclusiveTryLock());
1004
1005    uint8_t streams[] = { streamId };
1006    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1007                                            /*requests*/TEST_CPU_FRAME_COUNT));
1008
1009    // Consume a couple of results
1010    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
1011        EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));
1012
1013        CpuConsumer::LockedBuffer buf;
1014        EXPECT_OK(consumer->lockNextBuffer(&buf));
1015
1016        dout << "Buffer synchronously received on streamId = " << streamId <<
1017                ", dataPtr = " << (void*)buf.data <<
1018                ", timestamp = " << buf.timestamp << std::endl;
1019
1020        EXPECT_OK(consumer->unlockBuffer(buf));
1021    }
1022
1023    // Done: clean up
1024    EXPECT_OK(mCamera->deleteStream(streamId));
1025    EXPECT_OK(mCamera->exclusiveUnlock());
1026}
1027
1028// FIXME: This is racy and sometimes fails on waitForFrameMetadata
1029TEST_F(ProCameraTest, DISABLED_WaitForDualStreamBuffer) {
1030    if (HasFatalFailure()) {
1031        return;
1032    }
1033
1034    const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
1035
1036    // 15 fps
1037    int streamId = -1;
1038    sp<CpuConsumer> consumer;
1039    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1040                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1041    EXPECT_NE(-1, streamId);
1042
1043    // 30 fps
1044    int depthStreamId = -1;
1045    sp<CpuConsumer> depthConsumer;
1046    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
1047       TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
1048    EXPECT_NE(-1, depthStreamId);
1049
1050    EXPECT_OK(mCamera->exclusiveTryLock());
1051
1052    uint8_t streams[] = { streamId, depthStreamId };
1053    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
1054                                                    /*requests*/REQUEST_COUNT));
1055
1056    int depthFrames = 0;
1057    int greyFrames = 0;
1058
1059    // Consume two frames simultaneously. Unsynchronized by timestamps.
1060    for (int i = 0; i < REQUEST_COUNT; ++i) {
1061
1062        // Exhaust event queue so it doesn't keep growing
1063        while (mListener->ReadEvent() != UNKNOWN);
1064
1065        // Get the metadata
1066        EXPECT_OK(mCamera->waitForFrameMetadata());
1067        CameraMetadata meta = mCamera->consumeFrameMetadata();
1068        EXPECT_FALSE(meta.isEmpty());
1069
1070        // Get the buffers
1071
1072        EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));
1073
1074        /**
1075          * Guaranteed to be able to consume the depth frame,
1076          * since we waited on it.
1077          */
1078        CpuConsumer::LockedBuffer depthBuffer;
1079        EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
1080
1081        dout << "Depth Buffer synchronously received on streamId = " <<
1082                streamId <<
1083                ", dataPtr = " << (void*)depthBuffer.data <<
1084                ", timestamp = " << depthBuffer.timestamp << std::endl;
1085
1086        EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
1087
1088        depthFrames++;
1089
1090
1091        /** Consume Greyscale frames if there are any.
1092          * There may not be since it runs at half FPS */
1093        CpuConsumer::LockedBuffer greyBuffer;
1094        while (consumer->lockNextBuffer(&greyBuffer) == OK) {
1095
1096            dout << "GRAY Buffer synchronously received on streamId = " <<
1097                streamId <<
1098                ", dataPtr = " << (void*)greyBuffer.data <<
1099                ", timestamp = " << greyBuffer.timestamp << std::endl;
1100
1101            EXPECT_OK(consumer->unlockBuffer(greyBuffer));
1102
1103            greyFrames++;
1104        }
1105    }
1106
1107    dout << "Done, summary: depth frames " << std::dec << depthFrames
1108         << ", grey frames " << std::dec << greyFrames << std::endl;
1109
1110    // Done: clean up
1111    EXPECT_OK(mCamera->deleteStream(streamId));
1112    EXPECT_OK(mCamera->exclusiveUnlock());
1113}
1114
1115TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) {
1116    if (HasFatalFailure()) {
1117        return;
1118    }
1119
1120    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1121
1122    int streamId = -1;
1123    sp<CpuConsumer> consumer;
1124    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1125                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1126                  /*synchronousMode*/true, &consumer, &streamId));
1127    EXPECT_NE(-1, streamId);
1128
1129    EXPECT_OK(mCamera->exclusiveTryLock());
1130
1131    uint8_t streams[] = { streamId };
1132    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1133                                                     /*requests*/NUM_REQUESTS));
1134
1135    // Consume a couple of results
1136    for (int i = 0; i < NUM_REQUESTS; ++i) {
1137        int numFrames;
1138        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1139
1140        // Drop all but the newest framebuffer
1141        EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1142
1143        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1144
1145        // Skip the counter ahead, don't try to consume these frames again
1146        i += numFrames-1;
1147
1148        // "Consume" the buffer
1149        CpuConsumer::LockedBuffer buf;
1150        EXPECT_OK(consumer->lockNextBuffer(&buf));
1151
1152        dout << "Buffer synchronously received on streamId = " << streamId <<
1153                ", dataPtr = " << (void*)buf.data <<
1154                ", timestamp = " << buf.timestamp << std::endl;
1155
1156        // Process at 10fps, stream is at 15fps.
1157        // This means we will definitely fill up the buffer queue with
1158        // extra buffers and need to drop them.
1159        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1160
1161        EXPECT_OK(consumer->unlockBuffer(buf));
1162    }
1163
1164    // Done: clean up
1165    EXPECT_OK(mCamera->deleteStream(streamId));
1166    EXPECT_OK(mCamera->exclusiveUnlock());
1167}
1168
1169TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
1170    if (HasFatalFailure()) {
1171        return;
1172    }
1173
1174    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1175    const int CONSECUTIVE_FAILS_ASSUME_TIME_OUT = 5;
1176
1177    int streamId = -1;
1178    sp<CpuConsumer> consumer;
1179    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1180                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1181                  /*synchronousMode*/false, &consumer, &streamId));
1182    EXPECT_NE(-1, streamId);
1183
1184    EXPECT_OK(mCamera->exclusiveTryLock());
1185
1186    uint8_t streams[] = { streamId };
1187    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1188                                                     /*requests*/NUM_REQUESTS));
1189
1190    uint64_t lastFrameNumber = 0;
1191    int numFrames;
1192
1193    // Consume a couple of results
1194    int i;
1195    for (i = 0; i < NUM_REQUESTS && lastFrameNumber < NUM_REQUESTS; ++i) {
1196        EXPECT_LT(0, (numFrames = mCamera->waitForFrameBuffer(streamId)));
1197
1198        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1199
1200        // Skip the counter ahead, don't try to consume these frames again
1201        i += numFrames-1;
1202
1203        // "Consume" the buffer
1204        CpuConsumer::LockedBuffer buf;
1205
1206        EXPECT_EQ(OK, consumer->lockNextBuffer(&buf));
1207
1208        lastFrameNumber = buf.frameNumber;
1209
1210        dout << "Buffer asynchronously received on streamId = " << streamId <<
1211                ", dataPtr = " << (void*)buf.data <<
1212                ", timestamp = " << buf.timestamp <<
1213                ", framenumber = " << buf.frameNumber << std::endl;
1214
1215        // Process at 10fps, stream is at 15fps.
1216        // This means we will definitely fill up the buffer queue with
1217        // extra buffers and need to drop them.
1218        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1219
1220        EXPECT_OK(consumer->unlockBuffer(buf));
1221    }
1222
1223    dout << "Done after " << i << " iterations " << std::endl;
1224
1225    // Done: clean up
1226    EXPECT_OK(mCamera->deleteStream(streamId));
1227    EXPECT_OK(mCamera->exclusiveUnlock());
1228}
1229
1230
1231
1232//TODO: refactor into separate file
1233TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1234
1235    ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1236
1237    sp<ServiceListener> listener = new ServiceListener();
1238
1239    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1240    EXPECT_OK(ProCamera::addServiceListener(listener));
1241
1242    EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1243    EXPECT_OK(ProCamera::removeServiceListener(listener));
1244
1245    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1246}
1247
1248//TODO: refactor into separate file
1249TEST_F(ProCameraTest, ServiceListenersFunctional) {
1250
1251    sp<ServiceListener> listener = new ServiceListener();
1252
1253    EXPECT_OK(ProCamera::addServiceListener(listener));
1254
1255    sp<Camera> cam = Camera::connect(CAMERA_ID,
1256                                     /*clientPackageName*/String16(),
1257                                     -1);
1258    EXPECT_NE((void*)NULL, cam.get());
1259
1260    ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1261    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1262
1263    EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1264
1265    if (cam.get()) {
1266        cam->disconnect();
1267    }
1268
1269    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1270    EXPECT_EQ(ServiceListener::STATUS_PRESENT, stat);
1271
1272    EXPECT_OK(ProCamera::removeServiceListener(listener));
1273}
1274
1275
1276
1277}
1278}
1279}
1280}
1281
1282