blob: adc3c758be6fc4a86b6c32c88431506d4d28d52e [file] [log] [blame]
Igor Murashkin634a5152013-02-20 17:15:11 -08001/*
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
Igor Murashkin53765732013-02-20 17:41:57 -080020#include <binder/IPCThreadState.h>
21#include <utils/Thread.h>
22
Igor Murashkin634a5152013-02-20 17:15:11 -080023#include "Camera.h"
24#include "ProCamera.h"
Igor Murashkin53765732013-02-20 17:41:57 -080025#include <utils/Vector.h>
26#include <utils/Mutex.h>
27#include <utils/Condition.h>
Igor Murashkin634a5152013-02-20 17:15:11 -080028
29namespace android {
30namespace camera2 {
31namespace tests {
32namespace client {
33
34#define CAMERA_ID 0
35#define TEST_DEBUGGING 0
36
Igor Murashkin53765732013-02-20 17:41:57 -080037#define TEST_LISTENER_TIMEOUT 2000000000 // 2 second listener timeout
38
Igor Murashkin634a5152013-02-20 17:15:11 -080039#if TEST_DEBUGGING
40#define dout std::cerr
41#else
42#define dout if (0) std::cerr
43#endif
44
Igor Murashkin39f79f72013-01-30 10:14:24 -080045#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
46#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
47
48class ProCameraTest;
49
Igor Murashkin53765732013-02-20 17:41:57 -080050enum 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
Igor Murashkin53765732013-02-20 17:41:57 -080071 ptr->joinThreadPool();
Igor Murashkin53765732013-02-20 17:41:57 -080072
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
Igor Murashkin634a5152013-02-20 17:15:11 -0800178class ProCameraTest : public ::testing::Test {
179
Igor Murashkin53765732013-02-20 17:41:57 -0800180public:
181 ProCameraTest() {
182 }
183
Igor Murashkin39f79f72013-01-30 10:14:24 -0800184 static void SetUpTestCase() {
185 // Binder Thread Pool Initialization
Igor Murashkin53765732013-02-20 17:41:57 -0800186 mTestThread = new ProCameraTestThread();
187 mTestThread->run("ProCameraTestThread");
Igor Murashkin39f79f72013-01-30 10:14:24 -0800188 }
Igor Murashkin53765732013-02-20 17:41:57 -0800189
Igor Murashkin39f79f72013-01-30 10:14:24 -0800190 virtual void SetUp() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800191 mCamera = ProCamera::connect(CAMERA_ID);
192 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin53765732013-02-20 17:41:57 -0800193
194 mListener = new ProCameraTestListener();
195 mCamera->setListener(mListener);
Igor Murashkin634a5152013-02-20 17:15:11 -0800196 }
197
198 virtual void TearDown() {
199 ASSERT_NE((void*)NULL, mCamera.get());
200 mCamera->disconnect();
201 }
202
203protected:
204 sp<ProCamera> mCamera;
Igor Murashkin53765732013-02-20 17:41:57 -0800205 sp<ProCameraTestListener> mListener;
206
Igor Murashkin39f79f72013-01-30 10:14:24 -0800207 static sp<Thread> mTestThread;
Igor Murashkin53765732013-02-20 17:41:57 -0800208
Igor Murashkin634a5152013-02-20 17:15:11 -0800209};
210
Igor Murashkin39f79f72013-01-30 10:14:24 -0800211sp<Thread> ProCameraTest::mTestThread;
212
213// test around exclusiveTryLock (immediate locking)
Igor Murashkin53765732013-02-20 17:41:57 -0800214TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800215
216 if (HasFatalFailure()) {
217 return;
218 }
219
Igor Murashkin53765732013-02-20 17:41:57 -0800220 EXPECT_FALSE(mCamera->hasExclusiveLock());
221 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin39f79f72013-01-30 10:14:24 -0800222 // 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
Igor Murashkin53765732013-02-20 17:41:57 -0800250
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());
Igor Murashkin634a5152013-02-20 17:15:11 -0800261}
262
263}
264}
265}
266}
267