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