ProCameraTests.cpp revision 39f79f77a435c2f769477caeb071e2f9f6e78742
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
29namespace android {
30namespace camera2 {
31namespace tests {
32namespace client {
33
34#define CAMERA_ID 0
35#define TEST_DEBUGGING 0
36
37#define TEST_LISTENER_TIMEOUT 2000000000 // 2 second listener timeout
38
39#if TEST_DEBUGGING
40#define dout std::cerr
41#else
42#define dout if (0) std::cerr
43#endif
44
45#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
46#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
47
48class ProCameraTest;
49
50enum LockEvent {
51    UNKNOWN,
52    ACQUIRED,
53    RELEASED,
54    STOLEN
55};
56
57typedef Vector<LockEvent> EventList;
58
59class ProCameraTestThread : public Thread
60{
61public:
62    ProCameraTestThread() {
63    }
64
65    virtual bool threadLoop() {
66        mProc = ProcessState::self();
67        mProc->startThreadPool();
68
69        IPCThreadState *ptr = IPCThreadState::self();
70
71        ptr->joinThreadPool();
72
73        return false;
74    }
75
76    sp<ProcessState> mProc;
77};
78
79class ProCameraTestListener : public ProCameraListener {
80
81public:
82    status_t WaitForEvent() {
83        Mutex::Autolock cal(mConditionMutex);
84
85        {
86            Mutex::Autolock al(mListenerMutex);
87
88            if (mLockEventList.size() > 0) {
89                return OK;
90            }
91        }
92
93        return mListenerCondition.waitRelative(mConditionMutex,
94                                               TEST_LISTENER_TIMEOUT);
95    }
96
97    /* Read events into out. Existing queue is flushed */
98    void ReadEvents(EventList& out) {
99        Mutex::Autolock al(mListenerMutex);
100
101        for (size_t i = 0; i < mLockEventList.size(); ++i) {
102            out.push(mLockEventList[i]);
103        }
104
105        mLockEventList.clear();
106    }
107
108    /**
109      * Dequeue 1 event from the event queue.
110      * Returns UNKNOWN if queue is empty
111      */
112    LockEvent ReadEvent() {
113        Mutex::Autolock al(mListenerMutex);
114
115        if (mLockEventList.size() == 0) {
116            return UNKNOWN;
117        }
118
119        LockEvent ev = mLockEventList[0];
120        mLockEventList.removeAt(0);
121
122        return ev;
123    }
124
125private:
126    void QueueEvent(LockEvent ev) {
127        {
128            Mutex::Autolock al(mListenerMutex);
129            mLockEventList.push(ev);
130        }
131
132
133        mListenerCondition.broadcast();
134    }
135
136protected:
137
138    //////////////////////////////////////////////////
139    ///////// ProCameraListener //////////////////////
140    //////////////////////////////////////////////////
141
142
143    // Lock has been acquired. Write operations now available.
144    virtual void onLockAcquired() {
145        QueueEvent(ACQUIRED);
146    }
147    // Lock has been released with exclusiveUnlock
148    virtual void onLockReleased() {
149        QueueEvent(RELEASED);
150    }
151
152    // Lock has been stolen by another client.
153    virtual void onLockStolen() {
154        QueueEvent(STOLEN);
155    }
156
157    // Lock free.
158    virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
159
160        dout << "Trigger notify: " << ext1 << " " << ext2
161             << " " << ext3 << std::endl;
162    }
163
164    // TODO: remove
165
166    virtual void notify(int32_t , int32_t , int32_t ) {}
167    virtual void postData(int32_t , const sp<IMemory>& ,
168                          camera_frame_metadata_t *) {}
169    virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
170
171
172    Vector<LockEvent> mLockEventList;
173    Mutex             mListenerMutex;
174    Mutex             mConditionMutex;
175    Condition         mListenerCondition;
176};
177
178class ProCameraTest : public ::testing::Test {
179
180public:
181    ProCameraTest() {
182    }
183
184    static void SetUpTestCase() {
185        // Binder Thread Pool Initialization
186        mTestThread = new ProCameraTestThread();
187        mTestThread->run("ProCameraTestThread");
188    }
189
190    virtual void SetUp() {
191        mCamera = ProCamera::connect(CAMERA_ID);
192        ASSERT_NE((void*)NULL, mCamera.get());
193
194        mListener = new ProCameraTestListener();
195        mCamera->setListener(mListener);
196    }
197
198    virtual void TearDown() {
199        ASSERT_NE((void*)NULL, mCamera.get());
200        mCamera->disconnect();
201    }
202
203protected:
204    sp<ProCamera> mCamera;
205    sp<ProCameraTestListener> mListener;
206
207    static sp<Thread> mTestThread;
208
209};
210
211sp<Thread> ProCameraTest::mTestThread;
212
213// test around exclusiveTryLock (immediate locking)
214TEST_F(ProCameraTest, LockingImmediate) {
215
216    if (HasFatalFailure()) {
217        return;
218    }
219
220    EXPECT_FALSE(mCamera->hasExclusiveLock());
221    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
222    // at this point we definitely have the lock
223
224    EXPECT_EQ(OK, mListener->WaitForEvent());
225    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
226
227    EXPECT_TRUE(mCamera->hasExclusiveLock());
228    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
229
230    EXPECT_EQ(OK, mListener->WaitForEvent());
231    EXPECT_EQ(RELEASED, mListener->ReadEvent());
232
233    EXPECT_FALSE(mCamera->hasExclusiveLock());
234}
235
236// test around exclusiveLock (locking at some future point in time)
237TEST_F(ProCameraTest, LockingAsynchronous) {
238
239    if (HasFatalFailure()) {
240        return;
241    }
242
243    // TODO: Add another procamera that has a lock here.
244    // then we can be test that the lock wont immediately be acquired
245
246    EXPECT_FALSE(mCamera->hasExclusiveLock());
247    EXPECT_EQ(OK, mCamera->exclusiveLock());
248    // at this point we may or may not have the lock
249    // we cant be sure until we get an ACQUIRED event
250
251    EXPECT_EQ(OK, mListener->WaitForEvent());
252    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
253
254    EXPECT_TRUE(mCamera->hasExclusiveLock());
255    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
256
257    EXPECT_EQ(OK, mListener->WaitForEvent());
258    EXPECT_EQ(RELEASED, mListener->ReadEvent());
259
260    EXPECT_FALSE(mCamera->hasExclusiveLock());
261}
262
263}
264}
265}
266}
267
268