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(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray)));
|
||||||
connect(m_camera, SIGNAL(previewStarted()), this, SLOT(onCameraPreviewStarted()));
|
connect(m_camera, SIGNAL(previewStarted()), this, SLOT(onCameraPreviewStarted()));
|
||||||
connect(m_camera, SIGNAL(previewStopped()), this, SLOT(onCameraPreviewStopped()));
|
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();
|
m_nativeOrientation = m_camera->getNativeOrientation();
|
||||||
|
|
||||||
@@ -554,6 +556,12 @@ void QAndroidCameraSession::cancelCapture()
|
|||||||
m_captureCanceled = true;
|
m_captureCanceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QAndroidCameraSession::onCameraTakePictureFailed()
|
||||||
|
{
|
||||||
|
emit imageCaptureError(m_currentImageCaptureId, QCameraImageCapture::ResourceError,
|
||||||
|
tr("Failed to capture image"));
|
||||||
|
}
|
||||||
|
|
||||||
void QAndroidCameraSession::onCameraPictureExposed()
|
void QAndroidCameraSession::onCameraPictureExposed()
|
||||||
{
|
{
|
||||||
if (m_captureCanceled)
|
if (m_captureCanceled)
|
||||||
@@ -646,6 +654,27 @@ void QAndroidCameraSession::onCameraPreviewStarted()
|
|||||||
setReadyForCapture(true);
|
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()
|
void QAndroidCameraSession::onCameraPreviewStopped()
|
||||||
{
|
{
|
||||||
if (m_status == QCamera::StoppingStatus) {
|
if (m_status == QCamera::StoppingStatus) {
|
||||||
|
|||||||
@@ -112,11 +112,13 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void onApplicationStateChanged(Qt::ApplicationState state);
|
void onApplicationStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
|
void onCameraTakePictureFailed();
|
||||||
void onCameraPictureExposed();
|
void onCameraPictureExposed();
|
||||||
void onCameraPictureCaptured(const QByteArray &data);
|
void onCameraPictureCaptured(const QByteArray &data);
|
||||||
void onLastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
void onLastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
||||||
void onNewPreviewFrame(const QByteArray &frame, int width, int height);
|
void onNewPreviewFrame(const QByteArray &frame, int width, int height);
|
||||||
void onCameraPreviewStarted();
|
void onCameraPreviewStarted();
|
||||||
|
void onCameraPreviewFailedToStart();
|
||||||
void onCameraPreviewStopped();
|
void onCameraPreviewStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -224,12 +224,15 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void previewSizeChanged();
|
void previewSizeChanged();
|
||||||
void previewStarted();
|
void previewStarted();
|
||||||
|
void previewFailedToStart();
|
||||||
void previewStopped();
|
void previewStopped();
|
||||||
|
|
||||||
void autoFocusStarted();
|
void autoFocusStarted();
|
||||||
|
|
||||||
void whiteBalanceChanged();
|
void whiteBalanceChanged();
|
||||||
|
|
||||||
|
void takePictureFailed();
|
||||||
|
|
||||||
void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
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::previewSizeChanged, this, &AndroidCamera::previewSizeChanged);
|
||||||
connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted);
|
connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted);
|
||||||
|
connect(d, &AndroidCameraPrivate::previewFailedToStart, this, &AndroidCamera::previewFailedToStart);
|
||||||
connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped);
|
connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped);
|
||||||
connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted);
|
connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted);
|
||||||
connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged);
|
connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged);
|
||||||
|
connect(d, &AndroidCameraPrivate::takePictureFailed, this, &AndroidCamera::takePictureFailed);
|
||||||
connect(d, &AndroidCameraPrivate::lastPreviewFrameFetched, this, &AndroidCamera::lastPreviewFrameFetched);
|
connect(d, &AndroidCameraPrivate::lastPreviewFrameFetched, this, &AndroidCamera::lastPreviewFrameFetched);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1057,15 +1062,21 @@ void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
|
|||||||
|
|
||||||
void AndroidCameraPrivate::autoFocus()
|
void AndroidCameraPrivate::autoFocus()
|
||||||
{
|
{
|
||||||
|
QJNIEnvironmentPrivate env;
|
||||||
|
|
||||||
m_camera.callMethod<void>("autoFocus",
|
m_camera.callMethod<void>("autoFocus",
|
||||||
"(Landroid/hardware/Camera$AutoFocusCallback;)V",
|
"(Landroid/hardware/Camera$AutoFocusCallback;)V",
|
||||||
m_cameraListener.object());
|
m_cameraListener.object());
|
||||||
|
|
||||||
|
if (!exceptionCheckAndClear(env))
|
||||||
emit autoFocusStarted();
|
emit autoFocusStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidCameraPrivate::cancelAutoFocus()
|
void AndroidCameraPrivate::cancelAutoFocus()
|
||||||
{
|
{
|
||||||
|
QJNIEnvironmentPrivate env;
|
||||||
m_camera.callMethod<void>("cancelAutoFocus");
|
m_camera.callMethod<void>("cancelAutoFocus");
|
||||||
|
exceptionCheckAndClear(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidCameraPrivate::isAutoExposureLockSupported()
|
bool AndroidCameraPrivate::isAutoExposureLockSupported()
|
||||||
@@ -1314,25 +1325,40 @@ void AndroidCameraPrivate::setJpegQuality(int quality)
|
|||||||
|
|
||||||
void AndroidCameraPrivate::startPreview()
|
void AndroidCameraPrivate::startPreview()
|
||||||
{
|
{
|
||||||
|
QJNIEnvironmentPrivate env;
|
||||||
|
|
||||||
setupPreviewFrameCallback();
|
setupPreviewFrameCallback();
|
||||||
m_camera.callMethod<void>("startPreview");
|
m_camera.callMethod<void>("startPreview");
|
||||||
|
|
||||||
|
if (exceptionCheckAndClear(env))
|
||||||
|
emit previewFailedToStart();
|
||||||
|
else
|
||||||
emit previewStarted();
|
emit previewStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidCameraPrivate::stopPreview()
|
void AndroidCameraPrivate::stopPreview()
|
||||||
{
|
{
|
||||||
|
QJNIEnvironmentPrivate env;
|
||||||
|
|
||||||
m_camera.callMethod<void>("stopPreview");
|
m_camera.callMethod<void>("stopPreview");
|
||||||
|
|
||||||
|
exceptionCheckAndClear(env);
|
||||||
emit previewStopped();
|
emit previewStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidCameraPrivate::takePicture()
|
void AndroidCameraPrivate::takePicture()
|
||||||
{
|
{
|
||||||
|
QJNIEnvironmentPrivate env;
|
||||||
|
|
||||||
m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;"
|
m_camera.callMethod<void>("takePicture", "(Landroid/hardware/Camera$ShutterCallback;"
|
||||||
"Landroid/hardware/Camera$PictureCallback;"
|
"Landroid/hardware/Camera$PictureCallback;"
|
||||||
"Landroid/hardware/Camera$PictureCallback;)V",
|
"Landroid/hardware/Camera$PictureCallback;)V",
|
||||||
m_cameraListener.object(),
|
m_cameraListener.object(),
|
||||||
jobject(0),
|
jobject(0),
|
||||||
m_cameraListener.object());
|
m_cameraListener.object());
|
||||||
|
|
||||||
|
if (exceptionCheckAndClear(env))
|
||||||
|
emit takePictureFailed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidCameraPrivate::setupPreviewFrameCallback()
|
void AndroidCameraPrivate::setupPreviewFrameCallback()
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ public:
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void previewSizeChanged();
|
void previewSizeChanged();
|
||||||
void previewStarted();
|
void previewStarted();
|
||||||
|
void previewFailedToStart();
|
||||||
void previewStopped();
|
void previewStopped();
|
||||||
|
|
||||||
void autoFocusStarted();
|
void autoFocusStarted();
|
||||||
@@ -175,6 +176,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
void whiteBalanceChanged();
|
void whiteBalanceChanged();
|
||||||
|
|
||||||
|
void takePictureFailed();
|
||||||
void pictureExposed();
|
void pictureExposed();
|
||||||
void pictureCaptured(const QByteArray &data);
|
void pictureCaptured(const QByteArray &data);
|
||||||
void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
|
||||||
|
|||||||
Reference in New Issue
Block a user