Android: check for exceptions in some camera operations.
Not all camera operations are documented to raise exceptions, but they actually might do so depending on the hardware/drivers. Check for exceptions in all functions that could porentially fail and react appropriately. Task-number: QTBUG-49134 Change-Id: I633ca7f2e3aeb6532e1c445735e62135f52cf25f Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
This commit is contained in:
@@ -214,6 +214,8 @@ bool QAndroidCameraSession::open()
|
||||
connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray)));
|
||||
connect(m_camera, SIGNAL(previewStarted()), this, SLOT(onCameraPreviewStarted()));
|
||||
connect(m_camera, SIGNAL(previewStopped()), this, SLOT(onCameraPreviewStopped()));
|
||||
connect(m_camera, &AndroidCamera::previewFailedToStart, this, &QAndroidCameraSession::onCameraPreviewFailedToStart);
|
||||
connect(m_camera, &AndroidCamera::takePictureFailed, this, &QAndroidCameraSession::onCameraTakePictureFailed);
|
||||
|
||||
m_nativeOrientation = m_camera->getNativeOrientation();
|
||||
|
||||
@@ -554,6 +556,12 @@ void QAndroidCameraSession::cancelCapture()
|
||||
m_captureCanceled = true;
|
||||
}
|
||||
|
||||
void QAndroidCameraSession::onCameraTakePictureFailed()
|
||||
{
|
||||
emit imageCaptureError(m_currentImageCaptureId, QCameraImageCapture::ResourceError,
|
||||
tr("Failed to capture image"));
|
||||
}
|
||||
|
||||
void QAndroidCameraSession::onCameraPictureExposed()
|
||||
{
|
||||
if (m_captureCanceled)
|
||||
@@ -646,6 +654,27 @@ void QAndroidCameraSession::onCameraPreviewStarted()
|
||||
setReadyForCapture(true);
|
||||
}
|
||||
|
||||
void QAndroidCameraSession::onCameraPreviewFailedToStart()
|
||||
{
|
||||
if (m_status == QCamera::StartingStatus) {
|
||||
Q_EMIT error(QCamera::CameraError, tr("Camera preview failed to start."));
|
||||
|
||||
AndroidMultimediaUtils::enableOrientationListener(false);
|
||||
m_camera->setPreviewSize(QSize());
|
||||
m_camera->setPreviewTexture(0);
|
||||
if (m_videoOutput) {
|
||||
m_videoOutput->stop();
|
||||
m_videoOutput->reset();
|
||||
}
|
||||
m_previewStarted = false;
|
||||
|
||||
m_status = QCamera::LoadedStatus;
|
||||
emit statusChanged(m_status);
|
||||
|
||||
setReadyForCapture(false);
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidCameraSession::onCameraPreviewStopped()
|
||||
{
|
||||
if (m_status == QCamera::StoppingStatus) {
|
||||
|
||||
@@ -112,11 +112,13 @@ private Q_SLOTS:
|
||||
|
||||
void onApplicationStateChanged(Qt::ApplicationState state);
|
||||
|
||||
void onCameraTakePictureFailed();
|
||||
void onCameraPictureExposed();
|
||||
void onCameraPictureCaptured(const QByteArray &data);
|
||||
void onLastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
||||
void onNewPreviewFrame(const QByteArray &frame, int width, int height);
|
||||
void onCameraPreviewStarted();
|
||||
void onCameraPreviewFailedToStart();
|
||||
void onCameraPreviewStopped();
|
||||
|
||||
private:
|
||||
|
||||
@@ -224,12 +224,15 @@ public:
|
||||
Q_SIGNALS:
|
||||
void previewSizeChanged();
|
||||
void previewStarted();
|
||||
void previewFailedToStart();
|
||||
void previewStopped();
|
||||
|
||||
void autoFocusStarted();
|
||||
|
||||
void whiteBalanceChanged();
|
||||
|
||||
void takePictureFailed();
|
||||
|
||||
void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
||||
};
|
||||
|
||||
@@ -245,9 +248,11 @@ AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker)
|
||||
|
||||
connect(d, &AndroidCameraPrivate::previewSizeChanged, this, &AndroidCamera::previewSizeChanged);
|
||||
connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted);
|
||||
connect(d, &AndroidCameraPrivate::previewFailedToStart, this, &AndroidCamera::previewFailedToStart);
|
||||
connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped);
|
||||
connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted);
|
||||
connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged);
|
||||
connect(d, &AndroidCameraPrivate::takePictureFailed, this, &AndroidCamera::takePictureFailed);
|
||||
connect(d, &AndroidCameraPrivate::lastPreviewFrameFetched, this, &AndroidCamera::lastPreviewFrameFetched);
|
||||
}
|
||||
|
||||
@@ -1057,15 +1062,21 @@ void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
|
||||
|
||||
void AndroidCameraPrivate::autoFocus()
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
|
||||
m_camera.callMethod<void>("autoFocus",
|
||||
"(Landroid/hardware/Camera$AutoFocusCallback;)V",
|
||||
m_cameraListener.object());
|
||||
emit autoFocusStarted();
|
||||
|
||||
if (!exceptionCheckAndClear(env))
|
||||
emit autoFocusStarted();
|
||||
}
|
||||
|
||||
void AndroidCameraPrivate::cancelAutoFocus()
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
m_camera.callMethod<void>("cancelAutoFocus");
|
||||
exceptionCheckAndClear(env);
|
||||
}
|
||||
|
||||
bool AndroidCameraPrivate::isAutoExposureLockSupported()
|
||||
@@ -1314,25 +1325,40 @@ void AndroidCameraPrivate::setJpegQuality(int quality)
|
||||
|
||||
void AndroidCameraPrivate::startPreview()
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
|
||||
setupPreviewFrameCallback();
|
||||
m_camera.callMethod<void>("startPreview");
|
||||
emit previewStarted();
|
||||
|
||||
if (exceptionCheckAndClear(env))
|
||||
emit previewFailedToStart();
|
||||
else
|
||||
emit previewStarted();
|
||||
}
|
||||
|
||||
void AndroidCameraPrivate::stopPreview()
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
|
||||
m_camera.callMethod<void>("stopPreview");
|
||||
|
||||
exceptionCheckAndClear(env);
|
||||
emit previewStopped();
|
||||
}
|
||||
|
||||
void AndroidCameraPrivate::takePicture()
|
||||
{
|
||||
QJNIEnvironmentPrivate env;
|
||||
|
||||
m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;"
|
||||
"Landroid/hardware/Camera$PictureCallback;"
|
||||
"Landroid/hardware/Camera$PictureCallback;)V",
|
||||
m_cameraListener.object(),
|
||||
jobject(0),
|
||||
m_cameraListener.object());
|
||||
|
||||
if (exceptionCheckAndClear(env))
|
||||
emit takePictureFailed();
|
||||
}
|
||||
|
||||
void AndroidCameraPrivate::setupPreviewFrameCallback()
|
||||
|
||||
@@ -168,6 +168,7 @@ public:
|
||||
Q_SIGNALS:
|
||||
void previewSizeChanged();
|
||||
void previewStarted();
|
||||
void previewFailedToStart();
|
||||
void previewStopped();
|
||||
|
||||
void autoFocusStarted();
|
||||
@@ -175,6 +176,7 @@ Q_SIGNALS:
|
||||
|
||||
void whiteBalanceChanged();
|
||||
|
||||
void takePictureFailed();
|
||||
void pictureExposed();
|
||||
void pictureCaptured(const QByteArray &data);
|
||||
void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
||||
|
||||
Reference in New Issue
Block a user