• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 #define LOG_NDEBUG 0
18 #define LOG_TAG "CameraBinderTests"
19 
20 #include <binder/IInterface.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/Parcel.h>
23 #include <binder/ProcessState.h>
24 #include <utils/Errors.h>
25 #include <utils/Log.h>
26 #include <utils/List.h>
27 #include <utils/String8.h>
28 #include <utils/String16.h>
29 #include <utils/Condition.h>
30 #include <utils/Mutex.h>
31 #include <system/graphics.h>
32 #include <hardware/gralloc.h>
33 
34 #include <camera/CameraMetadata.h>
35 #include <camera/ICameraService.h>
36 #include <camera/ICameraServiceListener.h>
37 #include <camera/camera2/CaptureRequest.h>
38 #include <camera/camera2/ICameraDeviceUser.h>
39 #include <camera/camera2/ICameraDeviceCallbacks.h>
40 #include <camera/camera2/OutputConfiguration.h>
41 
42 #include <gui/BufferItemConsumer.h>
43 #include <gui/IGraphicBufferProducer.h>
44 #include <gui/Surface.h>
45 
46 #include <gtest/gtest.h>
47 #include <unistd.h>
48 #include <stdint.h>
49 #include <utility>
50 #include <vector>
51 #include <map>
52 #include <algorithm>
53 
54 using namespace android;
55 
56 #define ASSERT_NOT_NULL(x) \
57     ASSERT_TRUE((x) != nullptr)
58 
59 #define SETUP_TIMEOUT 2000000000 // ns
60 #define IDLE_TIMEOUT 2000000000 // ns
61 
62 // Stub listener implementation
63 class TestCameraServiceListener : public BnCameraServiceListener {
64     std::map<String16, TorchStatus> mCameraTorchStatuses;
65     std::map<int32_t, Status> mCameraStatuses;
66     mutable Mutex mLock;
67     mutable Condition mCondition;
68     mutable Condition mTorchCondition;
69 public:
~TestCameraServiceListener()70     virtual ~TestCameraServiceListener() {};
71 
onStatusChanged(Status status,int32_t cameraId)72     virtual void onStatusChanged(Status status, int32_t cameraId) {
73         Mutex::Autolock l(mLock);
74         mCameraStatuses[cameraId] = status;
75         mCondition.broadcast();
76     };
77 
onTorchStatusChanged(TorchStatus status,const String16 & cameraId)78     virtual void onTorchStatusChanged(TorchStatus status, const String16& cameraId) {
79         Mutex::Autolock l(mLock);
80         mCameraTorchStatuses[cameraId] = status;
81         mTorchCondition.broadcast();
82     };
83 
waitForNumCameras(size_t num) const84     bool waitForNumCameras(size_t num) const {
85         Mutex::Autolock l(mLock);
86 
87         if (mCameraStatuses.size() == num) {
88             return true;
89         }
90 
91         while (mCameraStatuses.size() < num) {
92             if (mCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) {
93                 return false;
94             }
95         }
96         return true;
97     };
98 
waitForTorchState(TorchStatus status,int32_t cameraId) const99     bool waitForTorchState(TorchStatus status, int32_t cameraId) const {
100         Mutex::Autolock l(mLock);
101 
102         const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
103         if (iter != mCameraTorchStatuses.end() && iter->second == status) {
104             return true;
105         }
106 
107         bool foundStatus = false;
108         while (!foundStatus) {
109             if (mTorchCondition.waitRelative(mLock, SETUP_TIMEOUT) != OK) {
110                 return false;
111             }
112             const auto& iter =
113                     mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
114             foundStatus = (iter != mCameraTorchStatuses.end() && iter->second == status);
115         }
116         return true;
117     };
118 
getTorchStatus(int32_t cameraId) const119     TorchStatus getTorchStatus(int32_t cameraId) const {
120         Mutex::Autolock l(mLock);
121         const auto& iter = mCameraTorchStatuses.find(String16(String8::format("%d", cameraId)));
122         if (iter == mCameraTorchStatuses.end()) {
123             return ICameraServiceListener::TORCH_STATUS_UNKNOWN;
124         }
125         return iter->second;
126     };
127 
getStatus(int32_t cameraId) const128     Status getStatus(int32_t cameraId) const {
129         Mutex::Autolock l(mLock);
130         const auto& iter = mCameraStatuses.find(cameraId);
131         if (iter == mCameraStatuses.end()) {
132             return ICameraServiceListener::STATUS_UNKNOWN;
133         }
134         return iter->second;
135     };
136 };
137 
138 // Callback implementation
139 class TestCameraDeviceCallbacks : public BnCameraDeviceCallbacks {
140 public:
141     enum Status {
142         IDLE,
143         ERROR,
144         PREPARED,
145         RUNNING,
146         SENT_RESULT,
147         UNINITIALIZED
148     };
149 
150 protected:
151     bool mError;
152     Status mLastStatus;
153     mutable std::vector<Status> mStatusesHit;
154     mutable Mutex mLock;
155     mutable Condition mStatusCondition;
156 public:
TestCameraDeviceCallbacks()157     TestCameraDeviceCallbacks() : mError(false), mLastStatus(UNINITIALIZED) {}
158 
~TestCameraDeviceCallbacks()159     virtual ~TestCameraDeviceCallbacks() {}
160 
onDeviceError(CameraErrorCode errorCode,const CaptureResultExtras & resultExtras)161     virtual void onDeviceError(CameraErrorCode errorCode,
162             const CaptureResultExtras& resultExtras) {
163         ALOGE("%s: onDeviceError occurred with: %d", __FUNCTION__, static_cast<int>(errorCode));
164         Mutex::Autolock l(mLock);
165         mError = true;
166         mLastStatus = ERROR;
167         mStatusesHit.push_back(mLastStatus);
168         mStatusCondition.broadcast();
169     }
170 
onDeviceIdle()171     virtual void onDeviceIdle() {
172         Mutex::Autolock l(mLock);
173         mLastStatus = IDLE;
174         mStatusesHit.push_back(mLastStatus);
175         mStatusCondition.broadcast();
176     }
177 
onCaptureStarted(const CaptureResultExtras & resultExtras,int64_t timestamp)178     virtual void onCaptureStarted(const CaptureResultExtras& resultExtras,
179             int64_t timestamp) {
180         Mutex::Autolock l(mLock);
181         mLastStatus = RUNNING;
182         mStatusesHit.push_back(mLastStatus);
183         mStatusCondition.broadcast();
184     }
185 
186 
onResultReceived(const CameraMetadata & metadata,const CaptureResultExtras & resultExtras)187     virtual void onResultReceived(const CameraMetadata& metadata,
188             const CaptureResultExtras& resultExtras) {
189         Mutex::Autolock l(mLock);
190         mLastStatus = SENT_RESULT;
191         mStatusesHit.push_back(mLastStatus);
192         mStatusCondition.broadcast();
193     }
194 
onPrepared(int streamId)195     virtual void onPrepared(int streamId) {
196         Mutex::Autolock l(mLock);
197         mLastStatus = PREPARED;
198         mStatusesHit.push_back(mLastStatus);
199         mStatusCondition.broadcast();
200     }
201 
202     // Test helper functions:
203 
hadError() const204     bool hadError() const {
205         Mutex::Autolock l(mLock);
206         return mError;
207     }
208 
waitForStatus(Status status) const209     bool waitForStatus(Status status) const {
210         Mutex::Autolock l(mLock);
211         if (mLastStatus == status) {
212             return true;
213         }
214 
215         while (std::find(mStatusesHit.begin(), mStatusesHit.end(), status)
216                 == mStatusesHit.end()) {
217 
218             if (mStatusCondition.waitRelative(mLock, IDLE_TIMEOUT) != OK) {
219                 mStatusesHit.clear();
220                 return false;
221             }
222         }
223         mStatusesHit.clear();
224 
225         return true;
226 
227     }
228 
clearStatus() const229     void clearStatus() const {
230         Mutex::Autolock l(mLock);
231         mStatusesHit.clear();
232     }
233 
waitForIdle() const234     bool waitForIdle() const {
235         return waitForStatus(IDLE);
236     }
237 
238 };
239 
240 // Exercise basic binder calls for the camera service
TEST(CameraServiceBinderTest,CheckBinderCameraService)241 TEST(CameraServiceBinderTest, CheckBinderCameraService) {
242     ProcessState::self()->startThreadPool();
243     sp<IServiceManager> sm = defaultServiceManager();
244     sp<IBinder> binder = sm->getService(String16("media.camera"));
245     ASSERT_NOT_NULL(binder);
246     sp<ICameraService> service = interface_cast<ICameraService>(binder);
247 
248 
249     int32_t numCameras = service->getNumberOfCameras();
250     EXPECT_LE(0, numCameras);
251 
252     // Check listener binder calls
253     sp<TestCameraServiceListener> listener(new TestCameraServiceListener());
254     EXPECT_EQ(OK, service->addListener(listener));
255 
256     EXPECT_TRUE(listener->waitForNumCameras(numCameras));
257 
258     for (int32_t i = 0; i < numCameras; i++) {
259         // We only care about binder calls for the Camera2 API.  Camera1 is deprecated.
260         status_t camera2Support = service->supportsCameraApi(i, ICameraService::API_VERSION_2);
261         if (camera2Support != OK) {
262             EXPECT_EQ(-EOPNOTSUPP, camera2Support);
263             continue;
264         }
265 
266         // Check metadata binder call
267         CameraMetadata metadata;
268         EXPECT_EQ(OK, service->getCameraCharacteristics(i, &metadata));
269         EXPECT_FALSE(metadata.isEmpty());
270 
271         // Make sure we're available, or skip device tests otherwise
272         ICameraServiceListener::Status s = listener->getStatus(i);
273         EXPECT_EQ(ICameraServiceListener::STATUS_AVAILABLE, s);
274         if (s != ICameraServiceListener::STATUS_AVAILABLE) {
275             continue;
276         }
277 
278         // Check connect binder calls
279         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
280         sp<ICameraDeviceUser> device;
281         EXPECT_EQ(OK, service->connectDevice(callbacks, i, String16("meeeeeeeee!"),
282                 ICameraService::USE_CALLING_UID, /*out*/device));
283         ASSERT_NE(nullptr, device.get());
284         device->disconnect();
285         EXPECT_FALSE(callbacks->hadError());
286 
287         ICameraServiceListener::TorchStatus torchStatus = listener->getTorchStatus(i);
288         if (torchStatus == ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF) {
289             // Check torch calls
290             EXPECT_EQ(OK, service->setTorchMode(String16(String8::format("%d", i)),
291                     /*enabled*/true, callbacks));
292             EXPECT_TRUE(listener->waitForTorchState(
293                     ICameraServiceListener::TORCH_STATUS_AVAILABLE_ON, i));
294             EXPECT_EQ(OK, service->setTorchMode(String16(String8::format("%d", i)),
295                     /*enabled*/false, callbacks));
296             EXPECT_TRUE(listener->waitForTorchState(
297                     ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF, i));
298         }
299     }
300 
301     EXPECT_EQ(OK, service->removeListener(listener));
302 }
303 
304 // Test fixture for client focused binder tests
305 class CameraClientBinderTest : public testing::Test {
306 protected:
307     sp<ICameraService> service;
308     int32_t numCameras;
309     std::vector<std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>>> openDeviceList;
310     sp<TestCameraServiceListener> serviceListener;
311 
openNewDevice(int deviceId)312     std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>> openNewDevice(int deviceId) {
313 
314         sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
315         sp<ICameraDeviceUser> device;
316         {
317             SCOPED_TRACE("openNewDevice");
318             EXPECT_EQ(OK, service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
319                     ICameraService::USE_CALLING_UID, /*out*/device));
320         }
321         auto p = std::make_pair(callbacks, device);
322         openDeviceList.push_back(p);
323         return p;
324     }
325 
closeDevice(std::pair<sp<TestCameraDeviceCallbacks>,sp<ICameraDeviceUser>> & p)326     void closeDevice(std::pair<sp<TestCameraDeviceCallbacks>, sp<ICameraDeviceUser>>& p) {
327         if (p.second.get() != nullptr) {
328             p.second->disconnect();
329             {
330                 SCOPED_TRACE("closeDevice");
331                 EXPECT_FALSE(p.first->hadError());
332             }
333         }
334         auto iter = std::find(openDeviceList.begin(), openDeviceList.end(), p);
335         if (iter != openDeviceList.end()) {
336             openDeviceList.erase(iter);
337         }
338     }
339 
SetUp()340     virtual void SetUp() {
341         ProcessState::self()->startThreadPool();
342         sp<IServiceManager> sm = defaultServiceManager();
343         sp<IBinder> binder = sm->getService(String16("media.camera"));
344         service = interface_cast<ICameraService>(binder);
345         serviceListener = new TestCameraServiceListener();
346         service->addListener(serviceListener);
347         numCameras = service->getNumberOfCameras();
348     }
349 
TearDown()350     virtual void TearDown() {
351         service = nullptr;
352         numCameras = 0;
353         for (auto& p : openDeviceList) {
354             closeDevice(p);
355         }
356     }
357 
358 };
359 
TEST_F(CameraClientBinderTest,CheckBinderCameraDeviceUser)360 TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) {
361     ASSERT_NOT_NULL(service);
362 
363     EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras));
364     for (int32_t i = 0; i < numCameras; i++) {
365         // Make sure we're available, or skip device tests otherwise
366         ICameraServiceListener::Status s = serviceListener->getStatus(i);
367         EXPECT_EQ(ICameraServiceListener::STATUS_AVAILABLE, s);
368         if (s != ICameraServiceListener::STATUS_AVAILABLE) {
369             continue;
370         }
371 
372         auto p = openNewDevice(i);
373         sp<TestCameraDeviceCallbacks> callbacks = p.first;
374         sp<ICameraDeviceUser> device = p.second;
375 
376         // Setup a buffer queue; I'm just using the vendor opaque format here as that is
377         // guaranteed to be present
378         sp<IGraphicBufferProducer> gbProducer;
379         sp<IGraphicBufferConsumer> gbConsumer;
380         BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
381         sp<BufferItemConsumer> opaqueConsumer = new BufferItemConsumer(gbConsumer,
382                 GRALLOC_USAGE_SW_READ_NEVER, /*maxImages*/2, /*controlledByApp*/true);
383         EXPECT_TRUE(opaqueConsumer.get() != nullptr);
384         opaqueConsumer->setName(String8("nom nom nom"));
385 
386         // Set to VGA dimens for default, as that is guaranteed to be present
387         EXPECT_EQ(OK, gbConsumer->setDefaultBufferSize(640, 480));
388         EXPECT_EQ(OK, gbConsumer->setDefaultBufferFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED));
389 
390         sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false));
391 
392         OutputConfiguration output(gbProducer, /*rotation*/0);
393 
394         // Can we configure?
395         EXPECT_EQ(OK, device->beginConfigure());
396         status_t streamId = device->createStream(output);
397         EXPECT_LE(0, streamId);
398         EXPECT_EQ(OK, device->endConfigure());
399         EXPECT_FALSE(callbacks->hadError());
400 
401         // Can we make requests?
402         CameraMetadata requestTemplate;
403         EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1,
404                 /*out*/&requestTemplate));
405         sp<CaptureRequest> request(new CaptureRequest());
406         request->mMetadata = requestTemplate;
407         request->mSurfaceList.add(surface);
408         request->mIsReprocess = false;
409         int64_t lastFrameNumber = 0;
410         int64_t lastFrameNumberPrev = 0;
411         callbacks->clearStatus();
412         int requestId = device->submitRequest(request, /*streaming*/true, /*out*/&lastFrameNumber);
413         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
414         EXPECT_LE(0, requestId);
415 
416         // Can we stop requests?
417         EXPECT_EQ(OK, device->cancelRequest(requestId, /*out*/&lastFrameNumber));
418         EXPECT_TRUE(callbacks->waitForIdle());
419         EXPECT_FALSE(callbacks->hadError());
420 
421         // Can we do it again?
422         lastFrameNumberPrev = lastFrameNumber;
423         lastFrameNumber = 0;
424         requestTemplate.clear();
425         EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1,
426                 /*out*/&requestTemplate));
427         sp<CaptureRequest> request2(new CaptureRequest());
428         request2->mMetadata = requestTemplate;
429         request2->mSurfaceList.add(surface);
430         request2->mIsReprocess = false;
431         callbacks->clearStatus();
432         int requestId2 = device->submitRequest(request2, /*streaming*/true,
433                 /*out*/&lastFrameNumber);
434         EXPECT_EQ(-1, lastFrameNumber);
435         lastFrameNumber = 0;
436         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
437         EXPECT_LE(0, requestId2);
438         EXPECT_EQ(OK, device->cancelRequest(requestId2, /*out*/&lastFrameNumber));
439         EXPECT_TRUE(callbacks->waitForIdle());
440         EXPECT_LE(lastFrameNumberPrev, lastFrameNumber);
441         sleep(/*second*/1); // allow some time for errors to show up, if any
442         EXPECT_FALSE(callbacks->hadError());
443 
444         // Can we do it with a request list?
445         lastFrameNumberPrev = lastFrameNumber;
446         lastFrameNumber = 0;
447         requestTemplate.clear();
448         CameraMetadata requestTemplate2;
449         EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1,
450                 /*out*/&requestTemplate));
451         EXPECT_EQ(OK, device->createDefaultRequest(/*preview template*/1,
452                 /*out*/&requestTemplate2));
453         sp<CaptureRequest> request3(new CaptureRequest());
454         sp<CaptureRequest> request4(new CaptureRequest());
455         request3->mMetadata = requestTemplate;
456         request3->mSurfaceList.add(surface);
457         request3->mIsReprocess = false;
458         request4->mMetadata = requestTemplate2;
459         request4->mSurfaceList.add(surface);
460         request4->mIsReprocess = false;
461         List<sp<CaptureRequest>> requestList;
462         requestList.push_back(request3);
463         requestList.push_back(request4);
464 
465         callbacks->clearStatus();
466         int requestId3 = device->submitRequestList(requestList, /*streaming*/false,
467                 /*out*/&lastFrameNumber);
468         EXPECT_TRUE(callbacks->waitForStatus(TestCameraDeviceCallbacks::SENT_RESULT));
469         EXPECT_TRUE(callbacks->waitForIdle());
470         EXPECT_LE(lastFrameNumberPrev, lastFrameNumber);
471         sleep(/*second*/1); // allow some time for errors to show up, if any
472         EXPECT_FALSE(callbacks->hadError());
473 
474         // Can we unconfigure?
475         EXPECT_EQ(OK, device->beginConfigure());
476         EXPECT_EQ(OK, device->deleteStream(streamId));
477         EXPECT_EQ(OK, device->endConfigure());
478         sleep(/*second*/1); // allow some time for errors to show up, if any
479         EXPECT_FALSE(callbacks->hadError());
480 
481         closeDevice(p);
482     }
483 
484 };
485