ProCameraTests.cpp revision 5376573eff55f370f041889618c9a7a9e1894615
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 45enum LockEvent { 46 UNKNOWN, 47 ACQUIRED, 48 RELEASED, 49 STOLEN 50}; 51 52typedef Vector<LockEvent> EventList; 53 54class ProCameraTestThread : public Thread 55{ 56public: 57 ProCameraTestThread() { 58 } 59 60 virtual bool threadLoop() { 61 mProc = ProcessState::self(); 62 mProc->startThreadPool(); 63 64 IPCThreadState *ptr = IPCThreadState::self(); 65 66 dout << "will join thread pool" << std::endl; 67 ptr->joinThreadPool(); 68 dout << "joined thread pool (done)" << std::endl; 69 70 return false; 71 } 72 73 sp<ProcessState> mProc; 74}; 75 76class ProCameraTestListener : public ProCameraListener { 77 78public: 79 status_t WaitForEvent() { 80 Mutex::Autolock cal(mConditionMutex); 81 82 { 83 Mutex::Autolock al(mListenerMutex); 84 85 if (mLockEventList.size() > 0) { 86 return OK; 87 } 88 } 89 90 return mListenerCondition.waitRelative(mConditionMutex, 91 TEST_LISTENER_TIMEOUT); 92 } 93 94 /* Read events into out. Existing queue is flushed */ 95 void ReadEvents(EventList& out) { 96 Mutex::Autolock al(mListenerMutex); 97 98 for (size_t i = 0; i < mLockEventList.size(); ++i) { 99 out.push(mLockEventList[i]); 100 } 101 102 mLockEventList.clear(); 103 } 104 105 /** 106 * Dequeue 1 event from the event queue. 107 * Returns UNKNOWN if queue is empty 108 */ 109 LockEvent ReadEvent() { 110 Mutex::Autolock al(mListenerMutex); 111 112 if (mLockEventList.size() == 0) { 113 return UNKNOWN; 114 } 115 116 LockEvent ev = mLockEventList[0]; 117 mLockEventList.removeAt(0); 118 119 return ev; 120 } 121 122private: 123 void QueueEvent(LockEvent ev) { 124 { 125 Mutex::Autolock al(mListenerMutex); 126 mLockEventList.push(ev); 127 } 128 129 130 mListenerCondition.broadcast(); 131 } 132 133protected: 134 135 ////////////////////////////////////////////////// 136 ///////// ProCameraListener ////////////////////// 137 ////////////////////////////////////////////////// 138 139 140 // Lock has been acquired. Write operations now available. 141 virtual void onLockAcquired() { 142 QueueEvent(ACQUIRED); 143 } 144 // Lock has been released with exclusiveUnlock 145 virtual void onLockReleased() { 146 QueueEvent(RELEASED); 147 } 148 149 // Lock has been stolen by another client. 150 virtual void onLockStolen() { 151 QueueEvent(STOLEN); 152 } 153 154 // Lock free. 155 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) { 156 157 dout << "Trigger notify: " << ext1 << " " << ext2 158 << " " << ext3 << std::endl; 159 } 160 161 // TODO: remove 162 163 virtual void notify(int32_t , int32_t , int32_t ) {} 164 virtual void postData(int32_t , const sp<IMemory>& , 165 camera_frame_metadata_t *) {} 166 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {} 167 168 169 Vector<LockEvent> mLockEventList; 170 Mutex mListenerMutex; 171 Mutex mConditionMutex; 172 Condition mListenerCondition; 173}; 174 175class ProCameraTest : public ::testing::Test { 176 177public: 178 ProCameraTest() { 179 } 180 181 virtual void SetUp() { 182 mTestThread = new ProCameraTestThread(); 183 mTestThread->run("ProCameraTestThread"); 184 185 mCamera = ProCamera::connect(CAMERA_ID); 186 ASSERT_NE((void*)NULL, mCamera.get()); 187 188 mListener = new ProCameraTestListener(); 189 mCamera->setListener(mListener); 190 } 191 192 virtual void TearDown() { 193 ASSERT_NE((void*)NULL, mCamera.get()); 194 mCamera->disconnect(); 195 } 196 197protected: 198 sp<ProCamera> mCamera; 199 sp<ProCameraTestListener> mListener; 200 201 sp<Thread> mTestThread; 202 203}; 204 205TEST_F(ProCameraTest, LockingImmediate) { 206 207 if (HasFatalFailure()) { 208 return; 209 } 210 211 212 EXPECT_FALSE(mCamera->hasExclusiveLock()); 213 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 214 215 EXPECT_EQ(OK, mListener->WaitForEvent()); 216 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 217 218 EXPECT_TRUE(mCamera->hasExclusiveLock()); 219 EXPECT_EQ(OK, mCamera->exclusiveUnlock()); 220 221 EXPECT_EQ(OK, mListener->WaitForEvent()); 222 EXPECT_EQ(RELEASED, mListener->ReadEvent()); 223 224 EXPECT_FALSE(mCamera->hasExclusiveLock()); 225} 226 227} 228} 229} 230} 231 232