ProCameraTests.cpp revision a36381479c5c546a01188390f1e0d2e280a3dbd8
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;
591
592    // when subscribing a new listener,
593    // we immediately get a callback to the current status
594    while (listener->waitForStatusChange(/*out*/currentStatus) != OK);
595    EXPECT_EQ(ServiceListener::STATUS_PRESENT, currentStatus);
596
597    dout << "Will now stream and resume infinitely..." << std::endl;
598    while (true) {
599
600        if (currentStatus == ServiceListener::STATUS_PRESENT) {
601
602            ASSERT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt,
603                                            surface,
604                                            &depthStreamId));
605            EXPECT_NE(-1, depthStreamId);
606
607            EXPECT_OK(mCamera->exclusiveTryLock());
608
609            uint8_t streams[] = { depthStreamId };
610            ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(
611                                                 streams,
612                                                 /*count*/1));
613        }
614
615        ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
616
617        // TODO: maybe check for getch every once in a while?
618        while (listener->waitForStatusChange(/*out*/stat) != OK);
619
620        if (currentStatus != stat) {
621            if (stat == ServiceListener::STATUS_PRESENT) {
622                dout << "Reconnecting to camera" << std::endl;
623                mCamera = ProCamera::connect(CAMERA_ID);
624            } else if (stat == ServiceListener::STATUS_NOT_AVAILABLE) {
625                dout << "Disconnecting from camera" << std::endl;
626                mCamera->disconnect();
627            } else if (stat == ServiceListener::STATUS_NOT_PRESENT) {
628                dout << "Camera unplugged" << std::endl;
629                mCamera = NULL;
630            } else {
631                dout << "Unknown status change "
632                     << std::hex << stat << std::endl;
633            }
634
635            currentStatus = stat;
636        }
637    }
638
639    EXPECT_OK(ProCamera::removeServiceListener(listener));
640    EXPECT_OK(mCamera->deleteStream(depthStreamId));
641    EXPECT_OK(mCamera->exclusiveUnlock());
642}
643
644// Stream directly to the screen.
645TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
646    if (HasFatalFailure()) {
647        return;
648    }
649    sp<Surface> surface;
650    sp<Surface> depthSurface;
651    if (mDisplaySecs > 0) {
652        createOnScreenSurface(/*out*/surface);
653        createDepthOnScreenSurface(/*out*/depthSurface);
654    }
655
656    int streamId = -1;
657    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
658              TEST_FORMAT_MAIN, surface, &streamId));
659    EXPECT_NE(-1, streamId);
660
661    int depthStreamId = -1;
662    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
663              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
664    EXPECT_NE(-1, depthStreamId);
665
666    EXPECT_OK(mCamera->exclusiveTryLock());
667    /*
668    */
669    /* iterate in a loop submitting requests every frame.
670     *  what kind of requests doesnt really matter, just whatever.
671     */
672
673    // it would probably be better to use CameraMetadata from camera service.
674    camera_metadata_t *request = NULL;
675    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
676              /*out*/&request));
677    EXPECT_NE((void*)NULL, request);
678
679    /*FIXME: dont need this later, at which point the above should become an
680             ASSERT_NE*/
681    if(request == NULL) request = allocate_camera_metadata(10, 100);
682
683    // set the output streams to just this stream ID
684
685    // wow what a verbose API.
686    uint8_t allStreams[] = { streamId, depthStreamId };
687    // IMPORTANT. bad things will happen if its not a uint8.
688    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
689    camera_metadata_entry_t entry;
690    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
691    int find = find_camera_metadata_entry(request, tag, &entry);
692    if (find == -ENOENT) {
693        if (add_camera_metadata_entry(request, tag, &allStreams,
694                                      /*data_count*/streamCount) != OK) {
695            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
696            ASSERT_OK(append_camera_metadata(tmp, request));
697            free_camera_metadata(request);
698            request = tmp;
699
700            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
701                                                /*data_count*/streamCount));
702        }
703    } else {
704        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
705                  &allStreams, /*data_count*/streamCount, &entry));
706    }
707
708    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
709
710    dout << "will sleep now for " << mDisplaySecs << std::endl;
711    sleep(mDisplaySecs);
712
713    free_camera_metadata(request);
714
715    for (int i = 0; i < streamCount; ++i) {
716        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
717    }
718    EXPECT_OK(mCamera->exclusiveUnlock());
719}
720
721TEST_F(ProCameraTest, CpuConsumerSingle) {
722    if (HasFatalFailure()) {
723        return;
724    }
725
726    // FIXME: Note this test is broken because onBufferReceived was removed
727    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
728
729    int streamId = -1;
730    sp<CpuConsumer> consumer;
731    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
732                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
733    EXPECT_NE(-1, streamId);
734
735    EXPECT_OK(mCamera->exclusiveTryLock());
736    EXPECT_EQ(OK, mListener->WaitForEvent());
737    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
738    /* iterate in a loop submitting requests every frame.
739     *  what kind of requests doesnt really matter, just whatever.
740     */
741
742    // it would probably be better to use CameraMetadata from camera service.
743    camera_metadata_t *request = NULL;
744    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
745        /*out*/&request));
746    EXPECT_NE((void*)NULL, request);
747
748    /*FIXME: dont need this later, at which point the above should become an
749      ASSERT_NE*/
750    if(request == NULL) request = allocate_camera_metadata(10, 100);
751
752    // set the output streams to just this stream ID
753
754    uint8_t allStreams[] = { streamId };
755    camera_metadata_entry_t entry;
756    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
757    int find = find_camera_metadata_entry(request, tag, &entry);
758    if (find == -ENOENT) {
759        if (add_camera_metadata_entry(request, tag, &allStreams,
760                /*data_count*/1) != OK) {
761            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
762            ASSERT_OK(append_camera_metadata(tmp, request));
763            free_camera_metadata(request);
764            request = tmp;
765
766            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
767                /*data_count*/1));
768        }
769    } else {
770        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
771            &allStreams, /*data_count*/1, &entry));
772    }
773
774    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
775
776    // Consume a couple of frames
777    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
778        EXPECT_EQ(OK, mListener->WaitForEvent());
779        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
780    }
781
782    // Done: clean up
783    free_camera_metadata(request);
784    EXPECT_OK(mCamera->deleteStream(streamId));
785    EXPECT_OK(mCamera->exclusiveUnlock());
786}
787
788TEST_F(ProCameraTest, CpuConsumerDual) {
789    if (HasFatalFailure()) {
790        return;
791    }
792
793    // FIXME: Note this test is broken because onBufferReceived was removed
794    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
795
796    int streamId = -1;
797    sp<CpuConsumer> consumer;
798    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
799                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
800    EXPECT_NE(-1, streamId);
801
802    int depthStreamId = -1;
803    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
804            TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
805    EXPECT_NE(-1, depthStreamId);
806
807    EXPECT_OK(mCamera->exclusiveTryLock());
808    /*
809    */
810    /* iterate in a loop submitting requests every frame.
811     *  what kind of requests doesnt really matter, just whatever.
812     */
813
814    // it would probably be better to use CameraMetadata from camera service.
815    camera_metadata_t *request = NULL;
816    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
817                                            /*out*/&request));
818    EXPECT_NE((void*)NULL, request);
819
820    if(request == NULL) request = allocate_camera_metadata(10, 100);
821
822    // set the output streams to just this stream ID
823
824    // wow what a verbose API.
825    uint8_t allStreams[] = { streamId, depthStreamId };
826    size_t streamCount = 2;
827    camera_metadata_entry_t entry;
828    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
829    int find = find_camera_metadata_entry(request, tag, &entry);
830    if (find == -ENOENT) {
831        if (add_camera_metadata_entry(request, tag, &allStreams,
832                                      /*data_count*/streamCount) != OK) {
833            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
834            ASSERT_OK(append_camera_metadata(tmp, request));
835            free_camera_metadata(request);
836            request = tmp;
837
838            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
839                                                   /*data_count*/streamCount));
840        }
841    } else {
842        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
843                              &allStreams, /*data_count*/streamCount, &entry));
844    }
845
846    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
847
848    // Consume a couple of frames
849    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
850        // stream id 1
851        EXPECT_EQ(OK, mListener->WaitForEvent());
852        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
853
854        // stream id 2
855        EXPECT_EQ(OK, mListener->WaitForEvent());
856        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
857
858        //TODO: events should be a struct with some data like the stream id
859    }
860
861    // Done: clean up
862    free_camera_metadata(request);
863    EXPECT_OK(mCamera->deleteStream(streamId));
864    EXPECT_OK(mCamera->exclusiveUnlock());
865}
866
867TEST_F(ProCameraTest, ResultReceiver) {
868    if (HasFatalFailure()) {
869        return;
870    }
871
872    mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
873    //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
874    // need to filter out events at read time
875
876    int streamId = -1;
877    sp<CpuConsumer> consumer;
878    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
879                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
880    EXPECT_NE(-1, streamId);
881
882    EXPECT_OK(mCamera->exclusiveTryLock());
883    /*
884    */
885    /* iterate in a loop submitting requests every frame.
886     *  what kind of requests doesnt really matter, just whatever.
887     */
888
889    camera_metadata_t *request = NULL;
890    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
891                                            /*out*/&request));
892    EXPECT_NE((void*)NULL, request);
893
894    /*FIXME*/
895    if(request == NULL) request = allocate_camera_metadata(10, 100);
896
897    // set the output streams to just this stream ID
898
899    uint8_t allStreams[] = { streamId };
900    size_t streamCount = 1;
901    camera_metadata_entry_t entry;
902    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
903    int find = find_camera_metadata_entry(request, tag, &entry);
904    if (find == -ENOENT) {
905        if (add_camera_metadata_entry(request, tag, &allStreams,
906                                      /*data_count*/streamCount) != OK) {
907            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
908            ASSERT_OK(append_camera_metadata(tmp, request));
909            free_camera_metadata(request);
910            request = tmp;
911
912            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
913                                                /*data_count*/streamCount));
914        }
915    } else {
916        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
917                               &allStreams, /*data_count*/streamCount, &entry));
918    }
919
920    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
921
922    // Consume a couple of results
923    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
924        EXPECT_EQ(OK, mListener->WaitForEvent());
925        EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
926    }
927
928    // Done: clean up
929    free_camera_metadata(request);
930    EXPECT_OK(mCamera->deleteStream(streamId));
931    EXPECT_OK(mCamera->exclusiveUnlock());
932}
933
934TEST_F(ProCameraTest, WaitForResult) {
935    if (HasFatalFailure()) {
936        return;
937    }
938
939    int streamId = -1;
940    sp<CpuConsumer> consumer;
941    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
942                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
943    EXPECT_NE(-1, streamId);
944
945    EXPECT_OK(mCamera->exclusiveTryLock());
946
947    uint8_t streams[] = { streamId };
948    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
949
950    // Consume a couple of results
951    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
952        EXPECT_OK(mCamera->waitForFrameMetadata());
953        CameraMetadata meta = mCamera->consumeFrameMetadata();
954        EXPECT_FALSE(meta.isEmpty());
955    }
956
957    // Done: clean up
958    consumer->abandon(); // since we didn't consume any of the buffers
959    EXPECT_OK(mCamera->deleteStream(streamId));
960    EXPECT_OK(mCamera->exclusiveUnlock());
961}
962
963TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
964    if (HasFatalFailure()) {
965        return;
966    }
967
968    int streamId = -1;
969    sp<CpuConsumer> consumer;
970    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
971                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
972    EXPECT_NE(-1, streamId);
973
974    EXPECT_OK(mCamera->exclusiveTryLock());
975
976    uint8_t streams[] = { streamId };
977    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
978                                            /*requests*/TEST_CPU_FRAME_COUNT));
979
980    // Consume a couple of results
981    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
982        EXPECT_EQ(1, mCamera->waitForFrameBuffer(streamId));
983
984        CpuConsumer::LockedBuffer buf;
985        EXPECT_OK(consumer->lockNextBuffer(&buf));
986
987        dout << "Buffer synchronously received on streamId = " << streamId <<
988                ", dataPtr = " << (void*)buf.data <<
989                ", timestamp = " << buf.timestamp << std::endl;
990
991        EXPECT_OK(consumer->unlockBuffer(buf));
992    }
993
994    // Done: clean up
995    EXPECT_OK(mCamera->deleteStream(streamId));
996    EXPECT_OK(mCamera->exclusiveUnlock());
997}
998
999TEST_F(ProCameraTest, WaitForDualStreamBuffer) {
1000    if (HasFatalFailure()) {
1001        return;
1002    }
1003
1004    const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
1005
1006    // 15 fps
1007    int streamId = -1;
1008    sp<CpuConsumer> consumer;
1009    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1010                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
1011    EXPECT_NE(-1, streamId);
1012
1013    // 30 fps
1014    int depthStreamId = -1;
1015    sp<CpuConsumer> depthConsumer;
1016    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
1017       TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
1018    EXPECT_NE(-1, depthStreamId);
1019
1020    EXPECT_OK(mCamera->exclusiveTryLock());
1021
1022    uint8_t streams[] = { streamId, depthStreamId };
1023    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
1024                                                    /*requests*/REQUEST_COUNT));
1025
1026    int depthFrames = 0;
1027    int greyFrames = 0;
1028
1029    // Consume two frames simultaneously. Unsynchronized by timestamps.
1030    for (int i = 0; i < REQUEST_COUNT; ++i) {
1031
1032        // Get the metadata
1033        EXPECT_OK(mCamera->waitForFrameMetadata());
1034        CameraMetadata meta = mCamera->consumeFrameMetadata();
1035        EXPECT_FALSE(meta.isEmpty());
1036
1037        // Get the buffers
1038
1039        EXPECT_EQ(1, mCamera->waitForFrameBuffer(depthStreamId));
1040
1041        /**
1042          * Guaranteed to be able to consume the depth frame,
1043          * since we waited on it.
1044          */
1045        CpuConsumer::LockedBuffer depthBuffer;
1046        EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
1047
1048        dout << "Depth Buffer synchronously received on streamId = " <<
1049                streamId <<
1050                ", dataPtr = " << (void*)depthBuffer.data <<
1051                ", timestamp = " << depthBuffer.timestamp << std::endl;
1052
1053        EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
1054
1055        depthFrames++;
1056
1057
1058        /** Consume Greyscale frames if there are any.
1059          * There may not be since it runs at half FPS */
1060        CpuConsumer::LockedBuffer greyBuffer;
1061        while (consumer->lockNextBuffer(&greyBuffer) == OK) {
1062
1063            dout << "GRAY Buffer synchronously received on streamId = " <<
1064                streamId <<
1065                ", dataPtr = " << (void*)greyBuffer.data <<
1066                ", timestamp = " << greyBuffer.timestamp << std::endl;
1067
1068            EXPECT_OK(consumer->unlockBuffer(greyBuffer));
1069
1070            greyFrames++;
1071        }
1072    }
1073
1074    dout << "Done, summary: depth frames " << std::dec << depthFrames
1075         << ", grey frames " << std::dec << greyFrames << std::endl;
1076
1077    // Done: clean up
1078    EXPECT_OK(mCamera->deleteStream(streamId));
1079    EXPECT_OK(mCamera->exclusiveUnlock());
1080}
1081
1082TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) {
1083    if (HasFatalFailure()) {
1084        return;
1085    }
1086
1087    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1088
1089    int streamId = -1;
1090    sp<CpuConsumer> consumer;
1091    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1092                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1093                  /*synchronousMode*/true, &consumer, &streamId));
1094    EXPECT_NE(-1, streamId);
1095
1096    EXPECT_OK(mCamera->exclusiveTryLock());
1097
1098    uint8_t streams[] = { streamId };
1099    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1100                                                     /*requests*/NUM_REQUESTS));
1101
1102    // Consume a couple of results
1103    for (int i = 0; i < NUM_REQUESTS; ++i) {
1104        int numFrames;
1105        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1106
1107        // Drop all but the newest framebuffer
1108        EXPECT_EQ(numFrames-1, mCamera->dropFrameBuffer(streamId, numFrames-1));
1109
1110        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1111
1112        // Skip the counter ahead, don't try to consume these frames again
1113        i += numFrames-1;
1114
1115        // "Consume" the buffer
1116        CpuConsumer::LockedBuffer buf;
1117        EXPECT_OK(consumer->lockNextBuffer(&buf));
1118
1119        dout << "Buffer synchronously received on streamId = " << streamId <<
1120                ", dataPtr = " << (void*)buf.data <<
1121                ", timestamp = " << buf.timestamp << std::endl;
1122
1123        // Process at 10fps, stream is at 15fps.
1124        // This means we will definitely fill up the buffer queue with
1125        // extra buffers and need to drop them.
1126        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1127
1128        EXPECT_OK(consumer->unlockBuffer(buf));
1129    }
1130
1131    // Done: clean up
1132    EXPECT_OK(mCamera->deleteStream(streamId));
1133    EXPECT_OK(mCamera->exclusiveUnlock());
1134}
1135
1136TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) {
1137    if (HasFatalFailure()) {
1138        return;
1139    }
1140
1141    const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT;
1142
1143    int streamId = -1;
1144    sp<CpuConsumer> consumer;
1145    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
1146                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT,
1147                  /*synchronousMode*/false, &consumer, &streamId));
1148    EXPECT_NE(-1, streamId);
1149
1150    EXPECT_OK(mCamera->exclusiveTryLock());
1151
1152    uint8_t streams[] = { streamId };
1153    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
1154                                                     /*requests*/NUM_REQUESTS));
1155
1156    // Consume a couple of results
1157    for (int i = 0; i < NUM_REQUESTS; ++i) {
1158        int numFrames;
1159        EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0);
1160
1161        dout << "Dropped " << (numFrames - 1) << " frames" << std::endl;
1162
1163        // Skip the counter ahead, don't try to consume these frames again
1164        i += numFrames-1;
1165
1166        // "Consume" the buffer
1167        CpuConsumer::LockedBuffer buf;
1168        EXPECT_OK(consumer->lockNextBuffer(&buf));
1169
1170        dout << "Buffer asynchronously received on streamId = " << streamId <<
1171                ", dataPtr = " << (void*)buf.data <<
1172                ", timestamp = " << buf.timestamp << std::endl;
1173
1174        // Process at 10fps, stream is at 15fps.
1175        // This means we will definitely fill up the buffer queue with
1176        // extra buffers and need to drop them.
1177        usleep(TEST_FRAME_PROCESSING_DELAY_US);
1178
1179        EXPECT_OK(consumer->unlockBuffer(buf));
1180    }
1181
1182    // Done: clean up
1183    EXPECT_OK(mCamera->deleteStream(streamId));
1184    EXPECT_OK(mCamera->exclusiveUnlock());
1185}
1186
1187
1188
1189//TODO: refactor into separate file
1190TEST_F(ProCameraTest, ServiceListenersSubscribe) {
1191
1192    ASSERT_EQ(4u, sizeof(ServiceListener::Status));
1193
1194    sp<ServiceListener> listener = new ServiceListener();
1195
1196    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1197    EXPECT_OK(ProCamera::addServiceListener(listener));
1198
1199    EXPECT_EQ(ALREADY_EXISTS, ProCamera::addServiceListener(listener));
1200    EXPECT_OK(ProCamera::removeServiceListener(listener));
1201
1202    EXPECT_EQ(BAD_VALUE, ProCamera::removeServiceListener(listener));
1203}
1204
1205//TODO: refactor into separate file
1206TEST_F(ProCameraTest, ServiceListenersFunctional) {
1207
1208    sp<ServiceListener> listener = new ServiceListener();
1209
1210    EXPECT_OK(ProCamera::addServiceListener(listener));
1211
1212    sp<Camera> cam = Camera::connect(CAMERA_ID,
1213                                     /*clientPackageName*/String16(),
1214                                     -1);
1215    EXPECT_NE((void*)NULL, cam.get());
1216
1217    ServiceListener::Status stat = ServiceListener::STATUS_UNKNOWN;
1218    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1219
1220    EXPECT_EQ(ServiceListener::STATUS_NOT_AVAILABLE, stat);
1221
1222    if (cam.get()) {
1223        cam->disconnect();
1224    }
1225
1226    EXPECT_OK(listener->waitForStatusChange(/*out*/stat));
1227    EXPECT_EQ(ServiceListener::STATUS_PRESENT, stat);
1228
1229    EXPECT_OK(ProCamera::removeServiceListener(listener));
1230}
1231
1232
1233
1234}
1235}
1236}
1237}
1238
1239