CameraZSLTests.cpp revision b12fb5d4642ee1651ae4432d3bebc4b0a33469e9
1/*
2 * Copyright (C) 2017 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 "CameraZSLTests"
19
20#include <gtest/gtest.h>
21
22#include <binder/ProcessState.h>
23#include <utils/Errors.h>
24#include <utils/Log.h>
25#include <gui/Surface.h>
26#include <gui/SurfaceComposerClient.h>
27#include <camera/CameraParameters.h>
28#include <camera/CameraMetadata.h>
29#include <camera/Camera.h>
30#include <android/hardware/ICameraService.h>
31
32using namespace android;
33using namespace android::hardware;
34
35class CameraZSLTests : public ::testing::Test,
36    public ::android::hardware::BnCameraClient {
37protected:
38
39    CameraZSLTests() : numCameras(0), mPreviewBufferCount(0),
40    mAutoFocusMessage(false), mSnapshotNotification(false) {}
41
42    //Gtest interface
43    void SetUp() override;
44    void TearDown() override;
45
46    //CameraClient interface
47    void notifyCallback(int32_t msgType, int32_t, int32_t) override;
48    void dataCallback(int32_t msgType, const sp<IMemory>&,
49            camera_frame_metadata_t *) override;
50    void dataCallbackTimestamp(nsecs_t, int32_t,
51            const sp<IMemory>&) override {};
52    void recordingFrameHandleCallbackTimestamp(nsecs_t,
53            native_handle_t*) override {};
54
55    status_t waitForPreviewStart();
56    status_t waitForEvent(Mutex &mutex, Condition &condition, bool &flag);
57
58    mutable Mutex mPreviewLock;
59    mutable Condition mPreviewCondition;
60    mutable Mutex mAutoFocusLock;
61    mutable Condition mAutoFocusCondition;
62    mutable Mutex mSnapshotLock;
63    mutable Condition mSnapshotCondition;
64
65    int32_t numCameras;
66    size_t mPreviewBufferCount;
67    sp<ICameraService> mCameraService;
68    sp<SurfaceComposerClient> mComposerClient;
69    bool mAutoFocusMessage;
70    bool mSnapshotNotification;
71    static const int32_t kPreviewThreshold  = 8;
72    static const nsecs_t kPreviewTimeout    = 5000000000;  // 5 [s.]
73    static const nsecs_t kEventTimeout      = 10000000000; // 10 [s.]
74};
75
76void CameraZSLTests::SetUp() {
77    ::android::binder::Status rc;
78    ProcessState::self()->startThreadPool();
79    sp<IServiceManager> sm = defaultServiceManager();
80    sp<IBinder> binder = sm->getService(String16("media.camera"));
81    mCameraService = interface_cast<ICameraService>(binder);
82    rc = mCameraService->getNumberOfCameras(
83            hardware::ICameraService::CAMERA_TYPE_ALL, &numCameras);
84    EXPECT_TRUE(rc.isOk());
85
86    mComposerClient = new SurfaceComposerClient;
87    ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
88}
89
90void CameraZSLTests::TearDown() {
91    mCameraService.clear();
92    mComposerClient->dispose();
93}
94
95void CameraZSLTests::notifyCallback(int32_t msgType, int32_t,
96        int32_t) {
97    if (CAMERA_MSG_FOCUS == msgType) {
98        Mutex::Autolock l(mAutoFocusLock);
99        mAutoFocusMessage = true;
100        mAutoFocusCondition.broadcast();
101    } else {
102        ALOGV("%s: msgType: %d", __FUNCTION__, msgType);
103    }
104};
105
106void CameraZSLTests::dataCallback(int32_t msgType, const sp<IMemory>& /*data*/,
107        camera_frame_metadata_t *) {
108
109    switch (msgType) {
110    case CAMERA_MSG_PREVIEW_FRAME: {
111        Mutex::Autolock l(mPreviewLock);
112        mPreviewBufferCount++;
113        mPreviewCondition.broadcast();
114        break;
115    }
116    case CAMERA_MSG_COMPRESSED_IMAGE: {
117        Mutex::Autolock l(mSnapshotLock);
118        mSnapshotNotification = true;
119        //TODO: Add checks on incoming Jpeg
120        mSnapshotCondition.broadcast();
121        break;
122    }
123    default:
124        ALOGV("%s: msgType: %d", __FUNCTION__, msgType);
125    }
126};
127
128status_t CameraZSLTests::waitForPreviewStart() {
129    status_t rc = NO_ERROR;
130    Mutex::Autolock l(mPreviewLock);
131    mPreviewBufferCount = 0;
132
133    while (mPreviewBufferCount < kPreviewThreshold) {
134        rc = mPreviewCondition.waitRelative(mPreviewLock,
135                kPreviewTimeout);
136        if (NO_ERROR != rc) {
137            break;
138        }
139    }
140
141    return rc;
142}
143
144status_t CameraZSLTests::waitForEvent(Mutex &mutex,
145        Condition &condition, bool &flag) {
146    status_t rc = NO_ERROR;
147    Mutex::Autolock l(mutex);
148    flag = false;
149
150    while (!flag) {
151        rc = condition.waitRelative(mutex,
152                kEventTimeout);
153        if (NO_ERROR != rc) {
154            break;
155        }
156    }
157
158    return rc;
159}
160
161TEST_F(CameraZSLTests, TestAllPictureSizes) {
162    ::android::binder::Status rc;
163
164    for (int32_t cameraId = 0; cameraId < numCameras; cameraId++) {
165        sp<Surface> previewSurface;
166        sp<SurfaceControl> surfaceControl;
167        sp<ICamera> cameraDevice;
168
169        String16 cameraIdStr = String16(String8::format("%d", cameraId));
170        bool isSupported = false;
171        rc = mCameraService->supportsCameraApi(cameraIdStr,
172                hardware::ICameraService::API_VERSION_1, &isSupported);
173        EXPECT_TRUE(rc.isOk());
174
175        // We only care about camera Camera1 ZSL support.
176        if (!isSupported) {
177            continue;
178        }
179
180        CameraMetadata metadata;
181        rc = mCameraService->getCameraCharacteristics(cameraIdStr, &metadata);
182        if (!rc.isOk()) {
183            // The test is relevant only for cameras with Hal 3.x
184            // support.
185            continue;
186        }
187        EXPECT_FALSE(metadata.isEmpty());
188        camera_metadata_entry_t availableCapabilities =
189                metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
190        EXPECT_TRUE(0 < availableCapabilities.count);
191        bool isReprocessSupported = false;
192        const uint8_t *caps = availableCapabilities.data.u8;
193        for (size_t i = 0; i < availableCapabilities.count; i++) {
194            if (ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING ==
195                caps[i]) {
196                isReprocessSupported = true;
197                break;
198            }
199        }
200        if (!isReprocessSupported) {
201            // ZSL relies on this feature
202            continue;
203        }
204
205        rc = mCameraService->connect(this, cameraId,
206                String16("ZSLTest"), hardware::ICameraService::USE_CALLING_UID,
207                hardware::ICameraService::USE_CALLING_PID, &cameraDevice);
208        EXPECT_TRUE(rc.isOk());
209
210        CameraParameters params(cameraDevice->getParameters());
211
212        String8 focusModes(params.get(
213                CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
214        bool isAFSupported = false;
215        const char *focusMode = nullptr;
216        if (focusModes.contains(CameraParameters::FOCUS_MODE_AUTO)) {
217            // If supported 'auto' should be set by default
218            isAFSupported = true;
219        } else if (focusModes.contains(
220                CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE)) {
221            isAFSupported = true;
222            focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
223        } else if (focusModes.contains(
224                CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO)) {
225            isAFSupported = true;
226            focusMode = CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
227        } else if (focusModes.contains(CameraParameters::FOCUS_MODE_MACRO)) {
228            isAFSupported = true;
229            focusMode = CameraParameters::FOCUS_MODE_MACRO;
230        }
231
232        if (!isAFSupported) {
233            // AF state is needed
234            continue;
235        }
236
237        if (nullptr != focusMode) {
238            params.set(CameraParameters::KEY_FOCUS_MODE, focusMode);
239            ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten()));
240        }
241
242        int previewWidth, previewHeight;
243        params.getPreviewSize(&previewWidth, &previewHeight);
244        ASSERT_TRUE((0 < previewWidth) && (0 < previewHeight));
245
246        surfaceControl = mComposerClient->createSurface(
247                String8("Test Surface"),
248                previewWidth, previewHeight,
249                CameraParameters::previewFormatToEnum(
250                        params.getPreviewFormat()),
251                GRALLOC_USAGE_HW_RENDER);
252
253        ASSERT_TRUE(nullptr != surfaceControl.get());
254        ASSERT_TRUE(surfaceControl->isValid());
255
256        SurfaceComposerClient::openGlobalTransaction();
257        ASSERT_EQ(NO_ERROR, surfaceControl->setLayer(0x7fffffff));
258        ASSERT_EQ(NO_ERROR, surfaceControl->show());
259        SurfaceComposerClient::closeGlobalTransaction();
260
261        previewSurface = surfaceControl->getSurface();
262        ASSERT_TRUE(previewSurface != NULL);
263        ASSERT_EQ(NO_ERROR, cameraDevice->setPreviewTarget(
264                previewSurface->getIGraphicBufferProducer()));
265
266        cameraDevice->setPreviewCallbackFlag(
267                CAMERA_FRAME_CALLBACK_FLAG_CAMCORDER);
268
269        Vector<Size> pictureSizes;
270        params.getSupportedPictureSizes(pictureSizes);
271        for (size_t i = 0; i < pictureSizes.size(); i++) {
272            params.setPictureSize(pictureSizes[i].width,
273                    pictureSizes[i].height);
274            ASSERT_EQ(NO_ERROR, cameraDevice->setParameters(params.flatten()));
275            ASSERT_EQ(NO_ERROR, cameraDevice->startPreview());
276            ASSERT_EQ(NO_ERROR, waitForPreviewStart());
277
278            ASSERT_EQ(NO_ERROR, cameraDevice->autoFocus());
279            ASSERT_EQ(NO_ERROR, waitForEvent(mAutoFocusLock,
280                    mAutoFocusCondition, mAutoFocusMessage));
281
282            ASSERT_EQ(NO_ERROR,
283                    cameraDevice->takePicture(CAMERA_MSG_COMPRESSED_IMAGE));
284            ASSERT_EQ(NO_ERROR, waitForEvent(mSnapshotLock, mSnapshotCondition,
285                    mSnapshotNotification));
286        }
287
288        cameraDevice->stopPreview();
289        rc = cameraDevice->disconnect();
290        EXPECT_TRUE(rc.isOk());
291    }
292}
293