summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2021-09-08 17:00:20 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-09-10 07:53:54 +0000
commit383f3d2433c4d2044f52e2acff3bac79b7c6f4e4 (patch)
tree6c2205a4b44e1324b8e427a000a8147c0f22f8e0 /src
parenta7fdbb5cae7341572f258de5777a084b551dc74a (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. Change-Id: I920917a6decf25f7b5f78ee8364d2b9403207aa4 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit 3c6f6ae6b49ae397e1071245bea9d94a0cf919e8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-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);