summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2021-09-08 17:00:20 +0300
committerSamuel Mira <samuel.mira@qt.io>2021-09-10 06:06:59 +0000
commit3c6f6ae6b49ae397e1071245bea9d94a0cf919e8 (patch)
tree68b0cf1e56721bf31a67af0bb2f1fa6a655fecc1 /src/multimedia
parente22ddea9d62d84a4b28b2395d4f259dd1d4b1094 (diff)
Fix crash in Android Recorder example on permission request
On the first time the app runs, it asks for permission for recording video as soon it starts and asks for permission to record audio only when it is needed. This permission to record audio can make a crash because requesting permission makes the app go to background which can make android to remove the camera surfaceTexture. Fixed by forcing the app to request permission before creating the surfaceTexture. Pick-to: 6.2 6.2.0 Change-Id: I920917a6decf25f7b5f78ee8364d2b9403207aa4 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/platform/android/common/qandroidmultimediautils.cpp19
-rw-r--r--src/multimedia/platform/android/common/qandroidmultimediautils_p.h3
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp4
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h2
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp33
5 files changed, 49 insertions, 12 deletions
diff --git a/src/multimedia/platform/android/common/qandroidmultimediautils.cpp b/src/multimedia/platform/android/common/qandroidmultimediautils.cpp
index 51c08006f..75f012f07 100644
--- a/src/multimedia/platform/android/common/qandroidmultimediautils.cpp
+++ b/src/multimedia/platform/android/common/qandroidmultimediautils.cpp
@@ -124,6 +124,25 @@ static bool androidRequestPermission(QtAndroidPrivate::PermissionType key)
return true;
}
+static bool androidCheckPermission(QtAndroidPrivate::PermissionType key)
+{
+ if (QNativeInterface::QAndroidApplication::sdkVersion() < 23)
+ return true;
+
+ // Permission already granted?
+ return (QtAndroidPrivate::checkPermission(key).result() == QtAndroidPrivate::Authorized);
+}
+
+bool qt_androidCheckCameraPermission()
+{
+ return androidCheckPermission(QtAndroidPrivate::Camera);
+}
+
+bool qt_androidCheckMicrophonePermission()
+{
+ return androidCheckPermission(QtAndroidPrivate::Microphone);
+}
+
bool qt_androidRequestCameraPermission()
{
if (!androidRequestPermission(QtAndroidPrivate::Camera)) {
diff --git a/src/multimedia/platform/android/common/qandroidmultimediautils_p.h b/src/multimedia/platform/android/common/qandroidmultimediautils_p.h
index 9a341c43b..5bc187da3 100644
--- a/src/multimedia/platform/android/common/qandroidmultimediautils_p.h
+++ b/src/multimedia/platform/android/common/qandroidmultimediautils_p.h
@@ -70,6 +70,9 @@ bool qt_androidRequestCameraPermission();
bool qt_androidRequestRecordingPermission();
bool qt_androidRequestWriteStoragePermission();
+bool qt_androidCheckCameraPermission();
+bool qt_androidCheckMicrophonePermission();
+
QT_END_NAMESPACE
#endif // QANDROIDMULTIMEDIAUTILS_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
index 1d85acf95..d89e494b1 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
+++ b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
@@ -748,10 +748,10 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state
}
}
-bool QAndroidCameraSession::requestRecordingPermission()
+bool QAndroidCameraSession::requestCameraPermission()
{
m_keepActive = true;
- const bool result = qt_androidRequestRecordingPermission();
+ const bool result = qt_androidRequestCameraPermission();
m_keepActive = false;
return result;
}
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h b/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
index 56674757d..fd225ae04 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
+++ b/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
@@ -108,7 +108,7 @@ public:
virtual void onFrameAvailable(const QVideoFrame &frame) = 0;
};
void setPreviewCallback(PreviewCallback *callback);
- bool requestRecordingPermission();
+ bool requestCameraPermission();
void setVideoSink(QVideoSink *surface);
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp
index 677c3614d..ac2dad0d6 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp
+++ b/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp
@@ -92,12 +92,24 @@ void QAndroidCaptureSession::setCameraSession(QAndroidCameraSession *cameraSessi
if (!isActive)
stop();
});
+
+ // It requests permission on setAudioInput instead of on start because asking for
+ // permission can pause the activity and android can release the surface referenced
+ // by camera crashing the app when mediaRecorder tries to use it
+ // TODO: https://bugreports.qt.io/browse/QTBUG-96346
+ m_cameraSession->requestCameraPermission();
}
}
void QAndroidCaptureSession::setAudioInput(QPlatformAudioInput *input)
{
m_audioInput = input;
+
+ // It requests permission on setAudioInput instead of on start because asking for
+ // permission can pause the activity and android can release the surface referenced
+ // by camera crashing the app when mediaRecorder tries to use it
+ // TODO: https://bugreports.qt.io/browse/QTBUG-96346
+ qt_androidRequestRecordingPermission();
}
void QAndroidCaptureSession::setAudioOutput(QPlatformAudioOutput *output)
@@ -128,15 +140,7 @@ void QAndroidCaptureSession::start(QMediaEncoderSettings &settings, const QUrl &
}
if (!m_cameraSession && !m_audioInput) {
- Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Audio Input device not set"));
- return;
- }
-
- const bool granted = m_cameraSession
- ? m_cameraSession->requestRecordingPermission()
- : qt_androidRequestRecordingPermission();
- if (!granted) {
- Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Permission denied."));
+ Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("No devices are set"));
return;
}
@@ -148,6 +152,11 @@ void QAndroidCaptureSession::start(QMediaEncoderSettings &settings, const QUrl &
// Set audio/video sources
if (m_cameraSession) {
+ if (!qt_androidCheckCameraPermission()) {
+ Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Camera permission denied."));
+ return;
+ }
+
m_cameraSession->camera()->stopPreviewSynchronous();
m_cameraSession->applyResolution(settings.videoResolution(), false);
m_cameraSession->camera()->unlock();
@@ -157,6 +166,12 @@ void QAndroidCaptureSession::start(QMediaEncoderSettings &settings, const QUrl &
}
if (m_audioInput) {
+ if (!qt_androidCheckMicrophonePermission()) {
+ Q_EMIT error(QMediaRecorder::ResourceError,
+ QLatin1String("Microphone permission denied."));
+ return;
+ }
+
m_mediaRecorder->setAudioInput(m_audioInput->device.id());
if (!m_mediaRecorder->isAudioSourceSet())
m_mediaRecorder->setAudioSource(AndroidMediaRecorder::DefaultAudioSource);