qtmobility/tests/auto/symbian/qcamera/tst_qcamera.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 15:51:22 +0300
changeset 1 2b40d63a9c3d
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtTest/QtTest>
#include <QDebug>

#include <experimental/qcameracontrol.h>
#include <experimental/qcameraexposurecontrol.h>
#include <experimental/qcamerafocuscontrol.h>
#include <experimental/qimagecapturecontrol.h>
#include <qimageencodercontrol.h>
#include <experimental/qimageprocessingcontrol.h>
#include <qmediaservice.h>
#include <experimental/qcamera.h>
#include <experimental/qstillimagecapture.h>


#define QTRY_COMPARE(a,e)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if ((a) == (e)) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QCOMPARE(a, e)

#define QTRY_VERIFY(a)                       \
    for (int _i = 0; _i < 5000; _i += 100) {    \
        if (a) break;                  \
        QTest::qWait(100);                      \
    }                                           \
    QVERIFY(a)

QTM_USE_NAMESPACE

class tst_QCamera: public QObject
{
    Q_OBJECT

private:
    
    QString capturePath(QDir dir);
public slots:
    void initTestCase();
    void cleanupTestCase();

private slots:
    void testAvailableDevices();
    void testDeviceDescription();
    void testCtorWithDevice();
    void testSimpleCamera();
    void testSimpleCameraWhiteBalance();
    void testSimpleCameraExposure();
    void testSimpleCameraFocus();
    void testSimpleCameraCapture();

    void testCameraWhiteBalance();
    void testCameraExposure();
    void testCameraFocus();
    void testCameraCapture();
    void testImageSettings();

};

void tst_QCamera::initTestCase()
{
    qRegisterMetaType<QCamera::State>("QCamera::State");
    qRegisterMetaType<QCamera::Error>("QCamera::Error");
}

void tst_QCamera::cleanupTestCase()
{
}
QString tst_QCamera::capturePath(QDir dir)
{
    int lastImage = 0;
    foreach( QString fileName, dir.entryList(QStringList() << "img_*.jpg") ) {
        int imgNumber = fileName.mid(4, fileName.size()-8).toInt();
        lastImage = qMax(lastImage, imgNumber);
    }

    return dir.absolutePath() + QDir::separator()  + QString("img_%1.jpg").arg(lastImage+1,
        4, //fieldWidth
        10,
        QLatin1Char('0'));
}

void tst_QCamera::testAvailableDevices()
{
    int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();

    QVERIFY(QCamera::availableDevices().count() == deviceCount);
}

void tst_QCamera::testDeviceDescription()
{
    int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();

    if (deviceCount == 0)
        QVERIFY(QCamera::deviceDescription(QByteArray("random")).isNull());
    else {
        foreach (const QByteArray &device, QCamera::availableDevices())
            QVERIFY(QCamera::deviceDescription(device).length() > 0);
    }
}

void tst_QCamera::testCtorWithDevice()
{
    int deviceCount = QMediaServiceProvider::defaultServiceProvider()->devices(QByteArray(Q_MEDIASERVICE_CAMERA)).count();
    QCamera *camera = 0;

    if (deviceCount == 0) {
        camera = new QCamera("random");
        QVERIFY(camera->error() == QCamera::ServiceMissingError);
    }
    else {
        camera = new QCamera(QCamera::availableDevices().first());
        QVERIFY(camera->error() == QCamera::NoError);
    }

    delete camera;
}

void tst_QCamera::testSimpleCamera()
{
    QCamera camera(0);
    
    QSignalSpy spyAdd(&camera, SIGNAL(stateChanged(QCamera::State)));
    QVERIFY(camera.service() != NULL);

    QCOMPARE(camera.state(), QCamera::StoppedState);
    camera.start();
    QTRY_COMPARE(spyAdd.count(), 1);
    
    QCOMPARE(camera.state(), QCamera::ActiveState);
    camera.stop();
    QTRY_COMPARE(spyAdd.count(), 2);
    QCOMPARE(camera.state(), QCamera::StoppedState);
}

void tst_QCamera::testSimpleCameraWhiteBalance()
{
    QCamera camera(0);

    //only WhiteBalanceAuto is supported
    QCOMPARE(camera.supportedWhiteBalanceModes(), QCamera::WhiteBalanceAuto);
    QCOMPARE(camera.whiteBalanceMode(), QCamera::WhiteBalanceAuto);
    camera.setWhiteBalanceMode(QCamera::WhiteBalanceCloudy);
    QCOMPARE(camera.supportedWhiteBalanceModes(), QCamera::WhiteBalanceAuto);
    QCOMPARE(camera.manualWhiteBalance(), -1);
    camera.setManualWhiteBalance(5000);
    QCOMPARE(camera.manualWhiteBalance(), -1);
}

void tst_QCamera::testSimpleCameraExposure()
{
    QCamera camera(0);

    QCOMPARE(camera.supportedExposureModes(), QCamera::ExposureAuto);
    QCOMPARE(camera.exposureMode(), QCamera::ExposureAuto);
    camera.setExposureMode(QCamera::ExposureManual);//should be ignored
    QCOMPARE(camera.exposureMode(), QCamera::ExposureAuto);

    QCOMPARE(camera.supportedFlashModes(), QCamera::FlashOff);
    QCOMPARE(camera.flashMode(), QCamera::FlashOff);
    QCOMPARE(camera.isFlashReady(), false);
    camera.setFlashMode(QCamera::FlashOn);
    QCOMPARE(camera.flashMode(), QCamera::FlashOff);

    QCOMPARE(camera.supportedMeteringModes(), QCamera::MeteringMatrix);
    QCOMPARE(camera.meteringMode(), QCamera::MeteringMatrix);
    camera.setMeteringMode(QCamera::MeteringSpot);
    QCOMPARE(camera.meteringMode(), QCamera::MeteringMatrix);

    QCOMPARE(camera.exposureCompensation(), 0.0);
    camera.setExposureCompensation(2.0);
    QCOMPARE(camera.exposureCompensation(), 0.0);

    QCOMPARE(camera.isoSensitivity(), -1);    
    QVERIFY(camera.supportedIsoSensitivities().isEmpty());
    camera.setManualIsoSensitivity(100);
    QCOMPARE(camera.isoSensitivity(), -1);
    camera.setAutoIsoSensitivity();
    QCOMPARE(camera.isoSensitivity(), -1);

    QVERIFY(camera.aperture() < 0);
    QVERIFY(camera.supportedApertures().isEmpty());
    camera.setAutoAperture();
    QVERIFY(camera.aperture() < 0);
    camera.setManualAperture(5.6);
    QVERIFY(camera.aperture() < 0);

    QVERIFY(camera.shutterSpeed() < 0);
    QVERIFY(camera.supportedShutterSpeeds().isEmpty());
    camera.setAutoShutterSpeed();
    QVERIFY(camera.shutterSpeed() < 0);
    camera.setManualShutterSpeed(1/128.0);
    QVERIFY(camera.shutterSpeed() < 0);

    QCOMPARE(camera.isExposureLocked(), true);

}

void tst_QCamera::testSimpleCameraFocus()
{
    QCamera camera(0);

    QCOMPARE(camera.supportedFocusModes(), QCamera::AutoFocus);
    QCOMPARE(camera.focusMode(), QCamera::AutoFocus);
    camera.setFocusMode(QCamera::ContinuousFocus);
    QCOMPARE(camera.focusMode(), QCamera::AutoFocus);
    QCOMPARE(camera.focusStatus(), QCamera::FocusInitial);

    QVERIFY(!camera.isMacroFocusingSupported());
    QVERIFY(!camera.macroFocusingEnabled());
    // macro focusing not supported
    //camera.setMacroFocusingEnabled(true);
    //QVERIFY(!camera.macroFocusingEnabled());

    QCOMPARE(camera.maximumOpticalZoom(), 1.0); // these should be check model ny model
    QCOMPARE(camera.maximumDigitalZoom(), 3.0); // these should be check model ny model
    QCOMPARE(camera.digitalZoom(), 1.0);
    camera.zoomTo(0,2.0);
    QCOMPARE(camera.digitalZoom(), 2.0);
    QCOMPARE(camera.opticalZoom(), 1.0);

}

void tst_QCamera::testSimpleCameraCapture()
{
    // This tests that taking a picture works with default setup
    QCamera camera(0);
    QStillImageCapture imageCapture(&camera);
    // we need to start camera before we take images.
    QSignalSpy cameraState(&camera, SIGNAL(stateChanged(QCamera::State)));
    QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(QString,QImage)));
    QSignalSpy errorSignal(&imageCapture, SIGNAL(error(QStillImageCapture::Error)));
    QSignalSpy imageSavedSignal(&imageCapture, SIGNAL(imageSaved(const QString&)));
   
    QCOMPARE(camera.state(), QCamera::StoppedState);
    camera.start(); //we need to start camera before taking picture
    QTRY_COMPARE(cameraState.count(), 1); // wait for camera to initialize itself
    QCOMPARE(camera.state(), QCamera::ActiveState);
    QVERIFY(imageCapture.isAvailable());
    QVERIFY(imageCapture.isReadyForCapture());
    
    QCOMPARE(imageCapture.error(), QStillImageCapture::NoError);
    QVERIFY(imageCapture.errorString().isEmpty());
    
    imageCapture.capture(capturePath(QDir::rootPath()));
    QTRY_COMPARE(capturedSignal.count(), 1);
    QTRY_COMPARE(imageSavedSignal.count(), 1);
    
    QCOMPARE(errorSignal.size(), 0);
        
//    camera.stop();
}

void tst_QCamera::testCameraCapture()
{
    QCamera camera(0);
    QStillImageCapture imageCapture(&camera);
    // check we have some controls and devices
    //QVERIFY(!imageCapture.isAvailable());
    QVERIFY(!imageCapture.isReadyForCapture());

    QSignalSpy cameraState(&camera, SIGNAL(stateChanged(QCamera::State)));
    QSignalSpy capturedSignal(&imageCapture, SIGNAL(imageCaptured(QString,QImage)));
    QSignalSpy errorSignal(&imageCapture, SIGNAL(error(QStillImageCapture::Error)));
    QSignalSpy cameraErrorSignal(&camera, SIGNAL(error(QCamera::Error)));
    QSignalSpy imageSavedSignal(&imageCapture, SIGNAL(imageSaved(const QString&)));
    
    // case where we have not started the camera
    // we shoul receive NotReadyToCaptureError
    imageCapture.capture(QString::fromLatin1("/dev/null"));
    QCOMPARE(capturedSignal.size(), 0);
    
    qDebug()<<"Camera errorNumber=" <<camera.error();
    qDebug()<<"Camera errorText="  <<camera.errorString();
    
    QCOMPARE(cameraErrorSignal.size(), 1);
    QCOMPARE(camera.error(), QCamera::NotReadyToCaptureError);
    QCOMPARE(errorSignal.size(), 1);
    QCOMPARE(imageCapture.error(), QStillImageCapture::NotReadyError);
    QCOMPARE(camera.state(), QCamera::StoppedState);

    // Phase 2 test taking picture to a real path
    errorSignal.clear();
    cameraErrorSignal.clear();
    cameraState.clear();
    capturedSignal.clear();
    imageSavedSignal.clear();
    
    //we need to start camera before taking picture. this is the difference between previous test 
    camera.start();
    QTRY_COMPARE (errorSignal.count(), 0); // We should not have any error code.
    QTRY_COMPARE (cameraState.count(), 1); // wait for camera to initialize itself
    QCOMPARE(camera.state(), QCamera::ActiveState);
    QVERIFY(imageCapture.isReadyForCapture());
    imageCapture.capture(QString::fromLatin1("/dev/null"));
    // we should receive captured signal, but no imageSavedSignal()
    QCOMPARE(capturedSignal.size(), 1);
    QCOMPARE(errorSignal.size(), 0);
    QCOMPARE(cameraErrorSignal.size(), 0);
    // as this is no good place to save image we shouldn't have imageSaved signal
    QCOMPARE(imageSavedSignal.size(), 0);
    QCOMPARE(imageCapture.error(), QStillImageCapture::ResourceError);
    
    camera.stop();
}

void tst_QCamera::testCameraWhiteBalance()
{
    QCamera::WhiteBalanceModes whiteBalanceModes
            = QCamera::WhiteBalanceAuto
            | QCamera::WhiteBalanceFlash
            | QCamera::WhiteBalanceIncandescent;

    QCamera camera(0);

    QCOMPARE(camera.whiteBalanceMode(), QCamera::WhiteBalanceFlash);
    QCOMPARE(camera.supportedWhiteBalanceModes(), whiteBalanceModes);

    camera.setWhiteBalanceMode(QCamera::WhiteBalanceIncandescent);
    QCOMPARE(camera.whiteBalanceMode(), QCamera::WhiteBalanceIncandescent);

    camera.setWhiteBalanceMode(QCamera::WhiteBalanceManual);
    QCOMPARE(camera.whiteBalanceMode(), QCamera::WhiteBalanceManual);
    QCOMPARE(camera.manualWhiteBalance(), 34);

    camera.setManualWhiteBalance(432);
    QCOMPARE(camera.manualWhiteBalance(), 432);
}

void tst_QCamera::testCameraExposure()
{
    QCamera camera(0);

    QVERIFY(camera.supportedExposureModes() & QCamera::ExposureAuto);
    QCOMPARE(camera.exposureMode(), QCamera::ExposureAuto);
    camera.setExposureMode(QCamera::ExposureManual);
    QCOMPARE(camera.exposureMode(), QCamera::ExposureManual);

    QCOMPARE(camera.flashMode(), QCamera::FlashAuto);
    QCOMPARE(camera.isFlashReady(), true);
    camera.setFlashMode(QCamera::FlashOn);
    QCOMPARE(camera.flashMode(), QCamera::FlashOn);

    camera.setFlashMode(QCamera::FlashRedEyeReduction); // not expected to be supported
    QCOMPARE(camera.flashMode(), QCamera::FlashOn);

    QCOMPARE(camera.meteringMode(), QCamera::MeteringMatrix);
    camera.setMeteringMode(QCamera::MeteringAverage);
    QCOMPARE(camera.meteringMode(), QCamera::MeteringAverage);
    camera.setMeteringMode(QCamera::MeteringSpot);
    QCOMPARE(camera.meteringMode(), QCamera::MeteringAverage);


    QCOMPARE(camera.exposureCompensation(), 0.0);
    camera.setExposureCompensation(2.0);
    QCOMPARE(camera.exposureCompensation(), 2.0);

    int minIso = camera.supportedIsoSensitivities().first();
    int maxIso = camera.supportedIsoSensitivities().last();
    QVERIFY(camera.isoSensitivity() > 0);
    QVERIFY(minIso > 0);
    QVERIFY(maxIso > 0);
    camera.setManualIsoSensitivity(minIso);
    QCOMPARE(camera.isoSensitivity(), minIso);
    camera.setManualIsoSensitivity(maxIso*10);
    QCOMPARE(camera.isoSensitivity(), maxIso);
    camera.setManualIsoSensitivity(-10);
    QCOMPARE(camera.isoSensitivity(), minIso);
    camera.setAutoIsoSensitivity();
    QCOMPARE(camera.isoSensitivity(), 100);

    qreal minAperture = camera.supportedApertures().first();
    qreal maxAperture = camera.supportedApertures().last();
    QVERIFY(minAperture > 0);
    QVERIFY(maxAperture > 0);
    QVERIFY(camera.aperture() >= minAperture);
    QVERIFY(camera.aperture() <= maxAperture);

    camera.setAutoAperture();
    QVERIFY(camera.aperture() >= minAperture);
    QVERIFY(camera.aperture() <= maxAperture);

    camera.setManualAperture(0);
    QCOMPARE(camera.aperture(), minAperture);

    camera.setManualAperture(10000);
    QCOMPARE(camera.aperture(), maxAperture);


    qreal minShutterSpeed = camera.supportedShutterSpeeds().first();
    qreal maxShutterSpeed = camera.supportedShutterSpeeds().last();
    QVERIFY(minShutterSpeed > 0);
    QVERIFY(maxShutterSpeed > 0);
    QVERIFY(camera.shutterSpeed() >= minShutterSpeed);
    QVERIFY(camera.shutterSpeed() <= maxShutterSpeed);

    camera.setAutoShutterSpeed();
    QVERIFY(camera.shutterSpeed() >= minShutterSpeed);
    QVERIFY(camera.shutterSpeed() <= maxShutterSpeed);

    camera.setManualShutterSpeed(0);
    QCOMPARE(camera.shutterSpeed(), minShutterSpeed);

    camera.setManualShutterSpeed(10000);
    QCOMPARE(camera.shutterSpeed(), maxShutterSpeed);

    QCOMPARE(camera.isExposureLocked(), false);

    camera.lockExposure();
    QCOMPARE(camera.isExposureLocked(), true);

    camera.unlockExposure();
    QCOMPARE(camera.isExposureLocked(), false);
}

void tst_QCamera::testCameraFocus()
{
    QCamera camera(0);

    QCOMPARE(camera.supportedFocusModes(), QCamera::AutoFocus /*| QCamera::ContinuousFocus*/);
    QCOMPARE(camera.focusMode(), QCamera::AutoFocus);
    camera.setFocusMode(QCamera::ManualFocus);
    QCOMPARE(camera.focusMode(), QCamera::AutoFocus);
    camera.setFocusMode(QCamera::ContinuousFocus);
    QCOMPARE(camera.focusMode(), QCamera::AutoFocus);
    QCOMPARE(camera.focusStatus(), QCamera::FocusInitial);

    QVERIFY(camera.isMacroFocusingSupported());
    QVERIFY(!camera.macroFocusingEnabled());
    // macro focusing not supported
    //camera.setMacroFocusingEnabled(true);
    //QVERIFY(camera.macroFocusingEnabled());

    QVERIFY(camera.maximumOpticalZoom() == 1.0);
    QVERIFY(camera.maximumDigitalZoom() >= 1.0);
    QCOMPARE(camera.digitalZoom(), 1.0);
    camera.zoomTo(1.0,0.5);
    QCOMPARE(camera.digitalZoom(), 0.5);
    camera.zoomTo(1.0,2.0);
    QCOMPARE(camera.digitalZoom(), 2.0);
    camera.zoomTo(1.0,2000000.0);
    QVERIFY(qFuzzyCompare(camera.digitalZoom(), camera.maximumOpticalZoom()*camera.maximumDigitalZoom()));

    /* TODO: focusing has changed 
    camera.lockFocus();
    QCOMPARE(camera.isFocusLocked(), true);
    camera.unlockFocus();
    QCOMPARE(camera.isFocusLocked(), false);
    */
}

void tst_QCamera::testImageSettings()
{
    QImageEncoderSettings settings;
    QVERIFY(settings.isNull());
    QVERIFY(settings == QImageEncoderSettings());

    QCOMPARE(settings.codec(), QString());
    settings.setCodec(QLatin1String("codecName"));
    QCOMPARE(settings.codec(), QLatin1String("codecName"));
    QVERIFY(!settings.isNull());
    QVERIFY(settings != QImageEncoderSettings());

    settings = QImageEncoderSettings();
    QCOMPARE(settings.quality(), QtMedia::NormalQuality);
    settings.setQuality(QtMedia::HighQuality);
    QCOMPARE(settings.quality(), QtMedia::HighQuality);
    QVERIFY(!settings.isNull());

    settings = QImageEncoderSettings();
    QCOMPARE(settings.resolution(), QSize());
    settings.setResolution(QSize(320,240));
    QCOMPARE(settings.resolution(), QSize(320,240));
    settings.setResolution(800,600);
    QCOMPARE(settings.resolution(), QSize(800,600));
    QVERIFY(!settings.isNull());

    settings = QImageEncoderSettings();
    QVERIFY(settings.isNull());
    QCOMPARE(settings.codec(), QString());
    QCOMPARE(settings.quality(), QtMedia::NormalQuality);
    QCOMPARE(settings.resolution(), QSize());

    {
        QImageEncoderSettings settings1;
        QImageEncoderSettings settings2;
        QCOMPARE(settings2, settings1);

        settings2 = settings1;
        QCOMPARE(settings2, settings1);
        QVERIFY(settings2.isNull());

        settings1.setQuality(QtMedia::HighQuality);

        QVERIFY(settings2.isNull());
        QVERIFY(!settings1.isNull());
        QVERIFY(settings1 != settings2);
    }

    {
        QImageEncoderSettings settings1;
        QImageEncoderSettings settings2(settings1);
        QCOMPARE(settings2, settings1);

        settings2 = settings1;
        QCOMPARE(settings2, settings1);
        QVERIFY(settings2.isNull());

        settings1.setQuality(QtMedia::HighQuality);

        QVERIFY(settings2.isNull());
        QVERIFY(!settings1.isNull());
        QVERIFY(settings1 != settings2);
    }

    QImageEncoderSettings settings1;
    QImageEncoderSettings settings2;

    settings1 = QImageEncoderSettings();
    settings1.setResolution(800,600);
    settings2 = QImageEncoderSettings();
    settings2.setResolution(QSize(800,600));
    QVERIFY(settings1 == settings2);
    settings2.setResolution(QSize(400,300));
    QVERIFY(settings1 != settings2);

    settings1 = QImageEncoderSettings();
    settings1.setCodec("codec1");
    settings2 = QImageEncoderSettings();
    settings2.setCodec("codec1");
    QVERIFY(settings1 == settings2);
    settings2.setCodec("codec2");
    QVERIFY(settings1 != settings2);

    settings1 = QImageEncoderSettings();
    settings1.setQuality(QtMedia::NormalQuality);
    settings2 = QImageEncoderSettings();
    settings2.setQuality(QtMedia::NormalQuality);
    QVERIFY(settings1 == settings2);
    settings2.setQuality(QtMedia::LowQuality);
    QVERIFY(settings1 != settings2);
}

QTEST_MAIN(tst_QCamera)

#include "tst_qcamera.moc"