ProCameraTests.cpp revision 7cf9a7e7d19579565e0f9dba8be9c107f2dbf548
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    virtual void notify(int32_t msg, int32_t ext1, int32_t ext2) {
275        dout << "Notify received: msg " << std::hex << msg
276             << ", ext1: " << std::hex << ext1 << ", ext2: " << std::hex << ext2
277             << std::endl;
278    }
279
280    Vector<ProEvent> mProEventList;
281    Mutex             mListenerMutex;
282    Mutex             mConditionMutex;
283    Condition         mListenerCondition;
284    int               mEventMask;
285};
286
287class ProCameraTest : public ::testing::Test {
288
289public:
290    ProCameraTest() {
291        char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
292        if (displaySecsEnv != NULL) {
293            mDisplaySecs = atoi(displaySecsEnv);
294            if (mDisplaySecs < 0) {
295                mDisplaySecs = 0;
296            }
297        } else {
298            mDisplaySecs = 0;
299        }
300
301        char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
302        if (displayFmtEnv != NULL) {
303            mDisplayFmt = FormatFromString(displayFmtEnv);
304        } else {
305            mDisplayFmt = TEST_DISPLAY_FORMAT;
306        }
307
308        char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
309        if (displayWidthEnv != NULL) {
310            mDisplayW = atoi(displayWidthEnv);
311            if (mDisplayW < 0) {
312                mDisplayW = 0;
313            }
314        } else {
315            mDisplayW = TEST_DISPLAY_WIDTH;
316        }
317
318        char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
319        if (displayHeightEnv != NULL) {
320            mDisplayH = atoi(displayHeightEnv);
321            if (mDisplayH < 0) {
322                mDisplayH = 0;
323            }
324        } else {
325            mDisplayH = TEST_DISPLAY_HEIGHT;
326        }
327    }
328
329    static void SetUpTestCase() {
330        // Binder Thread Pool Initialization
331        mTestThread = new ProCameraTestThread();
332        mTestThread->run("ProCameraTestThread");
333    }
334
335    virtual void SetUp() {
336        mCamera = ProCamera::connect(CAMERA_ID);
337        ASSERT_NE((void*)NULL, mCamera.get());
338
339        mListener = new ProCameraTestListener();
340        mCamera->setListener(mListener);
341    }
342
343    virtual void TearDown() {
344        ASSERT_NE((void*)NULL, mCamera.get());
345        mCamera->disconnect();
346    }
347
348protected:
349    sp<ProCamera> mCamera;
350    sp<ProCameraTestListener> mListener;
351
352    static sp<Thread> mTestThread;
353
354    int mDisplaySecs;
355    int mDisplayFmt;
356    int mDisplayW;
357    int mDisplayH;
358
359    sp<SurfaceComposerClient> mComposerClient;
360    sp<SurfaceControl> mSurfaceControl;
361
362    sp<SurfaceComposerClient> mDepthComposerClient;
363    sp<SurfaceControl> mDepthSurfaceControl;
364
365    int getSurfaceWidth() {
366        return 512;
367    }
368    int getSurfaceHeight() {
369        return 512;
370    }
371
372    void createOnScreenSurface(sp<Surface>& surface) {
373        mComposerClient = new SurfaceComposerClient;
374        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
375
376        mSurfaceControl = mComposerClient->createSurface(
377                String8("ProCameraTest StreamingImage Surface"),
378                getSurfaceWidth(), getSurfaceHeight(),
379                PIXEL_FORMAT_RGB_888, 0);
380
381        mSurfaceControl->setPosition(0, 0);
382
383        ASSERT_TRUE(mSurfaceControl != NULL);
384        ASSERT_TRUE(mSurfaceControl->isValid());
385
386        SurfaceComposerClient::openGlobalTransaction();
387        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
388        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
389        SurfaceComposerClient::closeGlobalTransaction();
390
391        sp<ANativeWindow> window = mSurfaceControl->getSurface();
392        surface = mSurfaceControl->getSurface();
393
394        ASSERT_NE((void*)NULL, surface.get());
395    }
396
397    void createDepthOnScreenSurface(sp<Surface>& surface) {
398        mDepthComposerClient = new SurfaceComposerClient;
399        ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
400
401        mDepthSurfaceControl = mDepthComposerClient->createSurface(
402                String8("ProCameraTest StreamingImage Surface"),
403                getSurfaceWidth(), getSurfaceHeight(),
404                PIXEL_FORMAT_RGB_888, 0);
405
406        mDepthSurfaceControl->setPosition(640, 0);
407
408        ASSERT_TRUE(mDepthSurfaceControl != NULL);
409        ASSERT_TRUE(mDepthSurfaceControl->isValid());
410
411        SurfaceComposerClient::openGlobalTransaction();
412        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
413        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
414        SurfaceComposerClient::closeGlobalTransaction();
415
416        sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
417        surface = mDepthSurfaceControl->getSurface();
418
419        ASSERT_NE((void*)NULL, surface.get());
420    }
421
422    template <typename T>
423    static bool ExistsItem(T needle, T* array, size_t count) {
424        if (!array) {
425            return false;
426        }
427
428        for (size_t i = 0; i < count; ++i) {
429            if (array[i] == needle) {
430                return true;
431            }
432        }
433        return false;
434    }
435
436
437    static int FormatFromString(const char* str) {
438        std::string s(str);
439
440#define CMP_STR(x, y)                               \
441        if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
442#define CMP_STR_SAME(x) CMP_STR(x, x)
443
444        CMP_STR_SAME( Y16);
445        CMP_STR_SAME( Y8);
446        CMP_STR_SAME( YV12);
447        CMP_STR(NV16, YCbCr_422_SP);
448        CMP_STR(NV21, YCrCb_420_SP);
449        CMP_STR(YUY2, YCbCr_422_I);
450        CMP_STR(RAW,  RAW_SENSOR);
451        CMP_STR(RGBA, RGBA_8888);
452
453        std::cerr << "Unknown format string " << str << std::endl;
454        return -1;
455
456    }
457
458    /**
459     * Creating a streaming request for these output streams from a template,
460     *  and submit it
461     */
462    void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
463
464        ASSERT_NE((void*)NULL, streamIds);
465        ASSERT_LT(0u, count);
466
467        camera_metadata_t *requestTmp = NULL;
468        EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
469                                                /*out*/&requestTmp));
470        ASSERT_NE((void*)NULL, requestTmp);
471        CameraMetadata request(requestTmp);
472
473        // set the output streams. default is empty
474
475        uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
476        request.update(tag, streamIds, count);
477
478        requestTmp = request.release();
479
480        if (requestCount < 0) {
481            EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
482        } else {
483            for (int i = 0; i < requestCount; ++i) {
484                EXPECT_OK(mCamera->submitRequest(requestTmp,
485                                                 /*streaming*/false));
486            }
487        }
488        request.acquire(requestTmp);
489    }
490};
491
492sp<Thread> ProCameraTest::mTestThread;
493
494TEST_F(ProCameraTest, AvailableFormats) {
495    if (HasFatalFailure()) {
496        return;
497    }
498
499    CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
500    ASSERT_FALSE(staticInfo.isEmpty());
501
502    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
503    EXPECT_TRUE(staticInfo.exists(tag));
504    camera_metadata_entry_t entry = staticInfo.find(tag);
505
506    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
507                                                  entry.data.i32, entry.count));
508    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
509                                                  entry.data.i32, entry.count));
510}
511
512// test around exclusiveTryLock (immediate locking)
513TEST_F(ProCameraTest, LockingImmediate) {
514
515    if (HasFatalFailure()) {
516        return;
517    }
518
519    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
520                            ProEvent_Mask(STOLEN)   |
521                            ProEvent_Mask(RELEASED));
522
523    EXPECT_FALSE(mCamera->hasExclusiveLock());
524    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
525    // at this point we definitely have the lock
526
527    EXPECT_EQ(OK, mListener->WaitForEvent());
528    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
529
530    EXPECT_TRUE(mCamera->hasExclusiveLock());
531    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
532
533    EXPECT_EQ(OK, mListener->WaitForEvent());
534    EXPECT_EQ(RELEASED, mListener->ReadEvent());
535
536    EXPECT_FALSE(mCamera->hasExclusiveLock());
537}
538
539// test around exclusiveLock (locking at some future point in time)
540TEST_F(ProCameraTest, LockingAsynchronous) {
541
542    if (HasFatalFailure()) {
543        return;
544    }
545
546
547    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
548                            ProEvent_Mask(STOLEN)   |
549                            ProEvent_Mask(RELEASED));
550
551    // TODO: Add another procamera that has a lock here.
552    // then we can be test that the lock wont immediately be acquired
553
554    EXPECT_FALSE(mCamera->hasExclusiveLock());
555    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
556    // at this point we definitely have the lock
557
558    EXPECT_EQ(OK, mListener->WaitForEvent());
559    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
560
561    EXPECT_TRUE(mCamera->hasExclusiveLock());
562    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
563
564    EXPECT_EQ(OK, mListener->WaitForEvent());
565    EXPECT_EQ(RELEASED, mListener->ReadEvent());
566
567    EXPECT_FALSE(mCamera->hasExclusiveLock());
568}
569
570// Stream directly to the screen.
571TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
572    if (HasFatalFailure()) {
573        return;
574    }
575
576    sp<Surface> surface;
577    if (mDisplaySecs > 0) {
578        createOnScreenSurface(/*out*/surface);
579    }
580    else {
581        dout << "Skipping, will not render to screen" << std::endl;
582        return;
583    }
584
585    int depthStreamId = -1;
586
587    sp<ServiceListener> listener = new ServiceListener();
588    EXPECT_OK(ProCamera::addServiceListener(listener));
589
590    ServiceListener::Status currentStatus = ServiceListener::STATUS_AVAILABLE;
591
592    dout << "Will now stream and resume infinitely..." << std::endl;
593    while (true) {
594
595        if (currentStatus == ServiceListener::STATUS_AVAILABLE) {
596
597            EXPECT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
598                                            surface,
599                                            &depthStreamId));
600            EXPECT_NE(-1, depthStreamId);
601
602            EXPECT_OK(mCamera->exclusiveTryLock());
603
604            uint8_t streams[] = { depthStreamId };
605            ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
606                                                 streams,
607                                                 /*count*/1));
608        }
609
610        ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
611
612        // TODO: maybe check for getch every once in a while?
613        while (listener->waitForStatusChange(/*out*/stat) != OK);
614
615        if (currentStatus != stat) {
616            if (stat == ServiceListener::STATUS_AVAILABLE) {
617                dout << "Reconnecting to camera" << std::endl;
618                mCamera = ProCamera::connect(CAMERA_ID);
619            } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
620                dout << "Disconnecting from camera" << std::endl;
621                mCamera->disconnect();
622            } else {
623                dout << "Unknown status change "
624                     << std::hex << stat << std::endl;
625            }
626
627            currentStatus = stat;
628        }
629    }
630
631    EXPECT_OK(ProCamera::removeServiceListener(listener));
632    EXPECT_OK(mCamera->deleteStream(depthStreamId));
633    EXPECT_OK(mCamera->exclusiveUnlock());
634}
635
636// Stream directly to the screen.
637TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
638    if (HasFatalFailure()) {
639        return;
640    }
641    sp<Surface> surface;
642    sp<Surface> depthSurface;
643    if (mDisplaySecs > 0) {
644        createOnScreenSurface(/*out*/surface);
645        createDepthOnScreenSurface(/*out*/depthSurface);
646    }
647
648    int streamId = -1;
649    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
650              TEST_FORMAT_MAIN, surface, &streamId));
651    EXPECT_NE(-1, streamId);
652
653    int depthStreamId = -1;
654    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
655              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
656    EXPECT_NE(-1, depthStreamId);
657
658    EXPECT_OK(mCamera->exclusiveTryLock());
659    /*
660    */
661    /* iterate in a loop submitting requests every frame.
662     *  what kind of requests doesnt really matter, just whatever.
663     */
664
665    // it would probably be better to use CameraMetadata from camera service.
666    camera_metadata_t *request = NULL;
667    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
668              /*out*/&request));
669    EXPECT_NE((void*)NULL, request);
670
671    /*FIXME: dont need this later, at which point the above should become an
672             ASSERT_NE*/
673    if(request == NULL) request = allocate_camera_metadata(10, 100);
674
675    // set the output streams to just this stream ID
676
677    // wow what a verbose API.
678    uint8_t allStreams[] = { streamId, depthStreamId };
679    // IMPORTANT. bad things will happen if its not a uint8.
680    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
681    camera_metadata_entry_t entry;
682    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
683    int find = find_camera_metadata_entry(request, tag, &entry);
684    if (find == -ENOENT) {
685        if (add_camera_metadata_entry(request, tag, &allStreams,
686                                      /*data_count*/streamCount) != OK) {
687            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
688            ASSERT_OK(append_camera_metadata(tmp, request));
689            free_camera_metadata(request);
690            request = tmp;
691
692            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
693                                                /*data_count*/streamCount));
694        }
695    } else {
696        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
697                  &allStreams, /*data_count*/streamCount, &entry));
698    }
699
700    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
701
702    dout << "will sleep now for " << mDisplaySecs << std::endl;
703    sleep(mDisplaySecs);
704
705    free_camera_metadata(request);
706
707    for (int i = 0; i < streamCount; ++i) {
708        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
709    }
710    EXPECT_OK(mCamera->exclusiveUnlock());
711}
712
713TEST_F(ProCameraTest, CpuConsumerSingle) {
714    if (HasFatalFailure()) {
715        return;
716    }
717
718    // FIXME: Note this test is broken because onBufferReceived was removed
719    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
720
721    int streamId = -1;
722    sp<CpuConsumer> consumer;
723    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
724                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
725    EXPECT_NE(-1, streamId);
726
727    EXPECT_OK(mCamera->exclusiveTryLock());
728    EXPECT_EQ(OK, mListener->WaitForEvent());
729    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
730    /* iterate in a loop submitting requests every frame.
731     *  what kind of requests doesnt really matter, just whatever.
732     */
733
734    // it would probably be better to use CameraMetadata from camera service.
735    camera_metadata_t *request = NULL;
736    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
737        /*out*/&request));
738    EXPECT_NE((void*)NULL, request);
739
740    /*FIXME: dont need this later, at which point the above should become an
741      ASSERT_NE*/
742    if(request == NULL) request = allocate_camera_metadata(10, 100);
743
744    // set the output streams to just this stream ID
745
746    uint8_t allStreams[] = { streamId };
747    camera_metadata_entry_t entry;
748    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
749    int find = find_camera_metadata_entry(request, tag, &entry);
750    if (find == -ENOENT) {
751        if (add_camera_metadata_entry(request, tag, &allStreams,
752                /*data_count*/1) != OK) {
753            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
754            ASSERT_OK(append_camera_metadata(tmp, request));
755            free_camera_metadata(request);
756            request = tmp;
757
758            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
759                /*data_count*/1));
760        }
761    } else {
762        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
763            &allStreams, /*data_count*/1, &entry));
764    }
765
766    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
767
768    // Consume a couple of frames
769    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
770        EXPECT_EQ(OK, mListener->WaitForEvent());
771        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
772    }
773
774    // Done: clean up
775    free_camera_metadata(request);
776    EXPECT_OK(mCamera->deleteStream(streamId));
777    EXPECT_OK(mCamera->exclusiveUnlock());
778}
779
780TEST_F(ProCameraTest, CpuConsumerDual) {
781    if (HasFatalFailure()) {
782        return;
783    }
784
785    // FIXME: Note this test is broken because onBufferReceived was removed
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, WaitForSingleStreamBufferAndDropFramesSync) {
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,
1075                  /*synchronousMode*/true, &consumer, &streamId));
1076    EXPECT_NE(-1, streamId);
1077
1078    EXPECT_OK(mCamera->exclusiveTryLock());
1079
1080    uint8_t streams[] = { streamId };
1081    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1082                                                     /*requests*/NUM_REQUESTS));
1083
1084    // Consume a couple of results
1085    for (int i = 0; i < NUM_REQUESTS; ++i) {
1086        int numFrames;
1087        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1088
1089        // Drop all but the newest framebuffer
1090        EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1091
1092        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1093
1094        // Skip the counter ahead, don't try to consume these frames again
1095        i += numFrames-1;
1096
1097        // "Consume" the buffer
1098        CpuConsumer::LockedBuffer buf;
1099        EXPECT_OK(consumer->lockNextBuffer(&buf));
1100
1101        dout << "Buffer synchronously received on streamId = " << streamId <<
1102                ", dataPtr = " << (void*)buf.data <<
1103                ", timestamp = " << buf.timestamp << std::endl;
1104
1105        // Process at 10fps, stream is at 15fps.
1106        // This means we will definitely fill up the buffer queue with
1107        // extra buffers and need to drop them.
1108        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1109
1110        EXPECT_OK(consumer->unlockBuffer(buf));
1111    }
1112
1113    // Done: clean up
1114    EXPECT_OK(mCamera->deleteStream(streamId));
1115    EXPECT_OK(mCamera->exclusiveUnlock());
1116}
1117
1118TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
1119    if (HasFatalFailure()) {
1120        return;
1121    }
1122
1123    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1124
1125    int streamId = -1;
1126    sp<CpuConsumer> consumer;
1127    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1128                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1129                  /*synchronousMode*/false, &consumer, &streamId));
1130    EXPECT_NE(-1, streamId);
1131
1132    EXPECT_OK(mCamera->exclusiveTryLock());
1133
1134    uint8_t streams[] = { streamId };
1135    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1136                                                     /*requests*/NUM_REQUESTS));
1137
1138    // Consume a couple of results
1139    for (int i = 0; i < NUM_REQUESTS; ++i) {
1140        int numFrames;
1141        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
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 asynchronously 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
1169
1170
1171//TODO: refactor into separate file
1172TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1173
1174    ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1175
1176    sp<ServiceListener> listener = new ServiceListener();
1177
1178    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1179    EXPECT_OK(ProCamera::addServiceListener(listener));
1180
1181    EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1182    EXPECT_OK(ProCamera::removeServiceListener(listener));
1183
1184    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1185}
1186
1187//TODO: refactor into separate file
1188TEST_F(ProCameraTest, ServiceListenersFunctional) {
1189
1190    sp<ServiceListener> listener = new ServiceListener();
1191
1192    EXPECT_OK(ProCamera::addServiceListener(listener));
1193
1194    sp<Camera> cam = Camera::connect(CAMERA_ID,
1195                                     /*clientPackageName*/String16(),
1196                                     -1);
1197    EXPECT_NE((void*)NULL, cam.get());
1198
1199    ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1200    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1201
1202    EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1203
1204    if (cam.get()) {
1205        cam->disconnect();
1206    }
1207
1208    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1209    EXPECT_EQ(ServiceListener::STATUS_AVAILABLE, stat);
1210
1211    EXPECT_OK(ProCamera::removeServiceListener(listener));
1212}
1213
1214
1215
1216}
1217}
1218}
1219}
1220
1221