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