summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-01-30 17:18:50 +0100
committerIvan Solovev <ivan.solovev@qt.io>2023-02-08 10:17:39 +0100
commite3c0c190136a55634451024cfa3ac8024c74caa3 (patch)
tree59880c5e4b9901fa9bbf302191b549024d5226f0 /examples
parented04adaf7cffa247fd2b5fee9b5b53b0269997ab (diff)
Adjust multimedia examples to use new QPermission API
Now when the library itself does not request permissions, that needs to be done on the user application level. This patch updates all examples to query the required permissions. As there is no QML API yet, the QML examples do it directly from main. Note: the WRITE_EXTERNAL_STORAGE Android permission is not handled by this patch, because it's currently not supported by the QPermission API. Task-number: QTBUG-109965 Change-Id: Iaeb09f9e32fced0ecb0f5ffc63d40c64ec386cfb Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/multimedia/audiodevices/audiodevices.cpp35
-rw-r--r--examples/multimedia/audiodevices/audiodevices.h1
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.cpp58
-rw-r--r--examples/multimedia/audiorecorder/audiorecorder.h1
-rw-r--r--examples/multimedia/audiosource/audiosource.cpp38
-rw-r--r--examples/multimedia/audiosource/audiosource.h2
-rw-r--r--examples/multimedia/camera/camera.cpp44
-rw-r--r--examples/multimedia/camera/camera.h2
-rw-r--r--examples/multimedia/declarative-camera/qmlcamera.cpp33
-rw-r--r--examples/multimedia/spectrum/engine.cpp31
-rw-r--r--examples/multimedia/spectrum/engine.h5
-rw-r--r--examples/multimedia/video/qmlvideo/main.cpp23
-rw-r--r--examples/multimedia/video/recorder/CMakeLists.txt1
-rw-r--r--examples/multimedia/video/recorder/main.cpp28
-rw-r--r--examples/multimedia/video/recorder/main_no_permissions.qml26
15 files changed, 295 insertions, 33 deletions
diff --git a/examples/multimedia/audiodevices/audiodevices.cpp b/examples/multimedia/audiodevices/audiodevices.cpp
index 018983e92..453f055f7 100644
--- a/examples/multimedia/audiodevices/audiodevices.cpp
+++ b/examples/multimedia/audiodevices/audiodevices.cpp
@@ -7,6 +7,10 @@
#include <QMediaDevices>
#include <QMediaFormat>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
// Utility functions for converting QAudioFormat fields into text
static QString toString(QAudioFormat::SampleFormat sampleFormat)
@@ -34,6 +38,37 @@ AudioDevicesBase::~AudioDevicesBase() = default;
AudioTest::AudioTest(QWidget *parent) : AudioDevicesBase(parent), m_devices(new QMediaDevices(this))
{
+ init();
+}
+
+void AudioTest::init()
+{
+#if QT_CONFIG(permissions)
+ // camera
+ QCameraPermission cameraPermission;
+ switch (qApp->checkPermission(cameraPermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(cameraPermission, this, &AudioTest::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Camera permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+ // microphone
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &AudioTest::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
m_devices->videoInputs();
qDebug() << "<<<<<<<<<<<<<<<<<<";
QMediaFormat().supportedFileFormats(QMediaFormat::Encode);
diff --git a/examples/multimedia/audiodevices/audiodevices.h b/examples/multimedia/audiodevices/audiodevices.h
index ad1de73e1..efe4e373c 100644
--- a/examples/multimedia/audiodevices/audiodevices.h
+++ b/examples/multimedia/audiodevices/audiodevices.h
@@ -32,6 +32,7 @@ private:
QMediaDevices *m_devices = nullptr;
private slots:
+ void init();
void updateAudioDevices();
void modeChanged(int idx);
void deviceChanged(int idx);
diff --git a/examples/multimedia/audiorecorder/audiorecorder.cpp b/examples/multimedia/audiorecorder/audiorecorder.cpp
index f96a925b8..8d97ce705 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.cpp
+++ b/examples/multimedia/audiorecorder/audiorecorder.cpp
@@ -17,12 +17,53 @@
#include <QMimeType>
#include <QStandardPaths>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
static QList<qreal> getBufferLevels(const QAudioBuffer &buffer);
AudioRecorder::AudioRecorder() : ui(new Ui::AudioRecorder)
{
ui->setupUi(this);
+ // channels
+ ui->channelsBox->addItem(tr("Default"), QVariant(-1));
+ ui->channelsBox->addItem(QStringLiteral("1"), QVariant(1));
+ ui->channelsBox->addItem(QStringLiteral("2"), QVariant(2));
+ ui->channelsBox->addItem(QStringLiteral("4"), QVariant(4));
+
+ // quality
+ ui->qualitySlider->setRange(0, int(QImageCapture::VeryHighQuality));
+ ui->qualitySlider->setValue(int(QImageCapture::NormalQuality));
+
+ // bit rates:
+ ui->bitrateBox->addItem(tr("Default"), QVariant(0));
+ ui->bitrateBox->addItem(QStringLiteral("32000"), QVariant(32000));
+ ui->bitrateBox->addItem(QStringLiteral("64000"), QVariant(64000));
+ ui->bitrateBox->addItem(QStringLiteral("96000"), QVariant(96000));
+ ui->bitrateBox->addItem(QStringLiteral("128000"), QVariant(128000));
+
+ // audio input initialization
+ init();
+}
+
+void AudioRecorder::init()
+{
+#if QT_CONFIG(permissions)
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &AudioRecorder::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
+
m_audioRecorder = new QMediaRecorder(this);
m_captureSession.setRecorder(m_audioRecorder);
m_captureSession.setAudioInput(new QAudioInput(this));
@@ -52,23 +93,6 @@ AudioRecorder::AudioRecorder() : ui(new Ui::AudioRecorder)
qBound(m_captureSession.audioInput()->device().minimumSampleRate(), 44100,
m_captureSession.audioInput()->device().maximumSampleRate()));
- // channels
- ui->channelsBox->addItem(tr("Default"), QVariant(-1));
- ui->channelsBox->addItem(QStringLiteral("1"), QVariant(1));
- ui->channelsBox->addItem(QStringLiteral("2"), QVariant(2));
- ui->channelsBox->addItem(QStringLiteral("4"), QVariant(4));
-
- // quality
- ui->qualitySlider->setRange(0, int(QImageCapture::VeryHighQuality));
- ui->qualitySlider->setValue(int(QImageCapture::NormalQuality));
-
- // bit rates:
- ui->bitrateBox->addItem(tr("Default"), QVariant(0));
- ui->bitrateBox->addItem(QStringLiteral("32000"), QVariant(32000));
- ui->bitrateBox->addItem(QStringLiteral("64000"), QVariant(64000));
- ui->bitrateBox->addItem(QStringLiteral("96000"), QVariant(96000));
- ui->bitrateBox->addItem(QStringLiteral("128000"), QVariant(128000));
-
connect(m_audioRecorder, &QMediaRecorder::durationChanged, this,
&AudioRecorder::updateProgress);
connect(m_audioRecorder, &QMediaRecorder::recorderStateChanged, this,
diff --git a/examples/multimedia/audiorecorder/audiorecorder.h b/examples/multimedia/audiorecorder/audiorecorder.h
index 830e4b001..47d7ed1e2 100644
--- a/examples/multimedia/audiorecorder/audiorecorder.h
+++ b/examples/multimedia/audiorecorder/audiorecorder.h
@@ -29,6 +29,7 @@ public slots:
void processBuffer(const QAudioBuffer &);
private slots:
+ void init();
void setOutputLocation();
void togglePause();
void toggleRecord();
diff --git a/examples/multimedia/audiosource/audiosource.cpp b/examples/multimedia/audiosource/audiosource.cpp
index 39a7f3b32..8a06191c5 100644
--- a/examples/multimedia/audiosource/audiosource.cpp
+++ b/examples/multimedia/audiosource/audiosource.cpp
@@ -7,10 +7,16 @@
#include <QAudioSource>
#include <QDateTime>
#include <QDebug>
+#include <QLabel>
#include <QPainter>
#include <QVBoxLayout>
#include <QtEndian>
+#if QT_CONFIG(permissions)
+ #include <QCoreApplication>
+ #include <QPermission>
+#endif
+
#include <math.h>
#include <stdlib.h>
@@ -92,8 +98,7 @@ void RenderArea::setLevel(qreal value)
InputTest::InputTest() : m_devices(new QMediaDevices(this))
{
- initializeWindow();
- initializeAudio(QMediaDevices::defaultAudioInput());
+ init();
}
void InputTest::initializeWindow()
@@ -147,6 +152,35 @@ void InputTest::initializeAudio(const QAudioDevice &deviceInfo)
toggleMode();
}
+void InputTest::initializeErrorWindow()
+{
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QLabel *errorLabel = new QLabel(tr("Microphone permission is not granted!"));
+ errorLabel->setWordWrap(true);
+ errorLabel->setAlignment(Qt::AlignCenter);
+ layout->addWidget(errorLabel);
+}
+
+void InputTest::init()
+{
+#if QT_CONFIG(permissions)
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &InputTest::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ initializeErrorWindow();
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
+ initializeWindow();
+ initializeAudio(QMediaDevices::defaultAudioInput());
+}
+
void InputTest::toggleMode()
{
m_audioInput->stop();
diff --git a/examples/multimedia/audiosource/audiosource.h b/examples/multimedia/audiosource/audiosource.h
index 05b891fe7..dd9a7bc4a 100644
--- a/examples/multimedia/audiosource/audiosource.h
+++ b/examples/multimedia/audiosource/audiosource.h
@@ -68,8 +68,10 @@ public:
private:
void initializeWindow();
void initializeAudio(const QAudioDevice &deviceInfo);
+ void initializeErrorWindow();
private slots:
+ void init();
void toggleMode();
void toggleSuspend();
void deviceChanged(int index);
diff --git a/examples/multimedia/camera/camera.cpp b/examples/multimedia/camera/camera.cpp
index 221dd58e0..5fd8837f6 100644
--- a/examples/multimedia/camera/camera.cpp
+++ b/examples/multimedia/camera/camera.cpp
@@ -30,9 +30,53 @@
#include <QTimer>
#include <QVideoWidget>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
Camera::Camera() : ui(new Ui::Camera)
{
ui->setupUi(this);
+ // disable all buttons by default
+ updateCameraActive(false);
+ readyForCapture(false);
+ ui->recordButton->setEnabled(false);
+ ui->pauseButton->setEnabled(false);
+ ui->stopButton->setEnabled(false);
+ ui->metaDataButton->setEnabled(false);
+
+ // try to actually initialize camera & mic
+ init();
+}
+
+void Camera::init()
+{
+#if QT_CONFIG(permissions)
+ // camera
+ QCameraPermission cameraPermission;
+ switch (qApp->checkPermission(cameraPermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(cameraPermission, this, &Camera::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Camera permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+ // microphone
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &Camera::init);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
m_audioInput.reset(new QAudioInput);
m_captureSession.setAudioInput(m_audioInput.get());
diff --git a/examples/multimedia/camera/camera.h b/examples/multimedia/camera/camera.h
index 4ba58a770..c92aa2d6a 100644
--- a/examples/multimedia/camera/camera.h
+++ b/examples/multimedia/camera/camera.h
@@ -35,6 +35,8 @@ public slots:
void saveMetaData();
private slots:
+ void init();
+
void setCamera(const QCameraDevice &cameraDevice);
void startCamera();
diff --git a/examples/multimedia/declarative-camera/qmlcamera.cpp b/examples/multimedia/declarative-camera/qmlcamera.cpp
index 347b7684f..d399ecd1b 100644
--- a/examples/multimedia/declarative-camera/qmlcamera.cpp
+++ b/examples/multimedia/declarative-camera/qmlcamera.cpp
@@ -5,16 +5,37 @@
#include <QQmlEngine>
#include <QQuickView>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
- // Qt.quit() called in embedded .qml by default only emits
- // quit() signal, so do this (optionally use Qt.exit()).
- QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QGuiApplication::quit);
- view.setSource(QUrl("qrc:///declarative-camera.qml"));
- view.resize(800, 480);
- view.show();
+
+ auto setupView = [&view]() {
+ // Qt.quit() called in embedded .qml by default only emits
+ // quit() signal, so do this (optionally use Qt.exit()).
+ QObject::connect(view.engine(), &QQmlEngine::quit, qApp, &QGuiApplication::quit);
+ view.setSource(QUrl("qrc:///declarative-camera.qml"));
+ view.resize(800, 480);
+ view.show();
+ };
+
+#if QT_CONFIG(permissions)
+ QCameraPermission cameraPermission;
+ qApp->requestPermission(cameraPermission, [&setupView](const QPermission &permission) {
+ // Show UI in any case. If there is no permission, the UI will just
+ // be disabled.
+ if (permission.status() != Qt::PermissionStatus::Granted)
+ qWarning("Camera permission is not granted!");
+ setupView();
+ });
+#else
+ setupView();
+#endif
+
return app.exec();
}
diff --git a/examples/multimedia/spectrum/engine.cpp b/examples/multimedia/spectrum/engine.cpp
index 296d4e4dd..cb7aeadcb 100644
--- a/examples/multimedia/spectrum/engine.cpp
+++ b/examples/multimedia/spectrum/engine.cpp
@@ -14,6 +14,10 @@
#include <QSet>
#include <QThread>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
#include <math.h>
//-----------------------------------------------------------------------------
@@ -37,13 +41,9 @@ Engine::Engine(QObject *parent)
m_generateTone(false),
m_file(nullptr),
m_analysisFile(nullptr),
- m_availableAudioInputDevices(m_devices->audioInputs()),
- m_audioInputDevice(m_devices->defaultAudioInput()),
m_audioInput(nullptr),
m_audioInputIODevice(nullptr),
m_recordPosition(0),
- m_availableAudioOutputDevices(m_devices->audioOutputs()),
- m_audioOutputDevice(m_devices->defaultAudioOutput()),
m_audioOutput(nullptr),
m_playPosition(0),
m_bufferPosition(0),
@@ -68,6 +68,8 @@ Engine::Engine(QObject *parent)
break;
}
+ initAudioDevices();
+
initialize();
#ifdef DUMP_DATA
@@ -272,6 +274,27 @@ void Engine::setAudioOutputDevice(const QAudioDevice &device)
// Private slots
//-----------------------------------------------------------------------------
+void Engine::initAudioDevices()
+{
+#if QT_CONFIG(permissions)
+ QMicrophonePermission microphonePermission;
+ switch (qApp->checkPermission(microphonePermission)) {
+ case Qt::PermissionStatus::Undetermined:
+ qApp->requestPermission(microphonePermission, this, &Engine::initAudioDevices);
+ return;
+ case Qt::PermissionStatus::Denied:
+ qWarning("Microphone permission is not granted!");
+ return;
+ case Qt::PermissionStatus::Granted:
+ break;
+ }
+#endif
+ m_availableAudioInputDevices = m_devices->audioInputs();
+ m_audioInputDevice = m_devices->defaultAudioInput();
+ m_availableAudioOutputDevices = m_devices->audioOutputs();
+ m_audioOutputDevice = m_devices->defaultAudioOutput();
+}
+
void Engine::audioNotify()
{
switch (m_mode) {
diff --git a/examples/multimedia/spectrum/engine.h b/examples/multimedia/spectrum/engine.h
index 0ac454484..9e8ba51d0 100644
--- a/examples/multimedia/spectrum/engine.h
+++ b/examples/multimedia/spectrum/engine.h
@@ -203,6 +203,7 @@ signals:
void bufferChanged(qint64 position, qint64 length, const QByteArray &buffer);
private slots:
+ void initAudioDevices();
void audioNotify();
void audioStateChanged(QAudio::State state);
void audioDataReady();
@@ -251,13 +252,13 @@ private:
QAudioFormat m_format;
- const QList<QAudioDevice> m_availableAudioInputDevices;
+ QList<QAudioDevice> m_availableAudioInputDevices;
QAudioDevice m_audioInputDevice;
QAudioSource *m_audioInput;
QIODevice *m_audioInputIODevice;
qint64 m_recordPosition;
- const QList<QAudioDevice> m_availableAudioOutputDevices;
+ QList<QAudioDevice> m_availableAudioOutputDevices;
QAudioDevice m_audioOutputDevice;
QAudioSink *m_audioOutput;
qint64 m_playPosition;
diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp
index a63146df0..c8d5fa048 100644
--- a/examples/multimedia/video/qmlvideo/main.cpp
+++ b/examples/multimedia/video/qmlvideo/main.cpp
@@ -16,6 +16,10 @@
#include <QString>
#include <QStringList>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
static const QString DefaultFileName1 = "";
static const QString DefaultFileName2 = "";
@@ -99,8 +103,23 @@ int main(int argc, char *argv[])
QMetaObject::invokeMethod(rootObject, "init");
- viewer.setMinimumSize(QSize(640, 360));
- viewer.show();
+ auto setupView = [&viewer]() {
+ viewer.setMinimumSize(QSize(640, 360));
+ viewer.show();
+ };
+
+#if QT_CONFIG(permissions)
+ QCameraPermission cameraPermission;
+ qApp->requestPermission(cameraPermission, [&setupView](const QPermission &permission) {
+ // Show UI in any case. If there is no permission, the UI will just
+ // be disabled.
+ if (permission.status() != Qt::PermissionStatus::Granted)
+ qWarning("Camera permission is not granted! Camera will not be available.");
+ setupView();
+ });
+#else
+ setupView();
+#endif
return app.exec();
}
diff --git a/examples/multimedia/video/recorder/CMakeLists.txt b/examples/multimedia/video/recorder/CMakeLists.txt
index 96077b732..ec84533e4 100644
--- a/examples/multimedia/video/recorder/CMakeLists.txt
+++ b/examples/multimedia/video/recorder/CMakeLists.txt
@@ -21,6 +21,7 @@ qt_add_executable(recorder
set(resource_files
"main.qml"
+ "main_no_permissions.qml"
"qmldir"
"MediaList.qml"
"AudioInputSelect.qml"
diff --git a/examples/multimedia/video/recorder/main.cpp b/examples/multimedia/video/recorder/main.cpp
index 195290319..92e54cb1b 100644
--- a/examples/multimedia/video/recorder/main.cpp
+++ b/examples/multimedia/video/recorder/main.cpp
@@ -4,6 +4,10 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
+#if QT_CONFIG(permissions)
+ #include <QPermission>
+#endif
+
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
@@ -17,7 +21,31 @@ int main(int argc, char *argv[])
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
+
+#if QT_CONFIG(permissions)
+ // If the permissions are not granted, display another main window, which
+ // simply contains the error message.
+ const QUrl noPermissionsUrl(QStringLiteral("qrc:/main_no_permissions.qml"));
+ QCameraPermission cameraPermission;
+ qApp->requestPermission(cameraPermission, [&](const QPermission &permission) {
+ if (permission.status() != Qt::PermissionStatus::Granted) {
+ qWarning("Camera permission is not granted!");
+ engine.load(noPermissionsUrl);
+ return;
+ }
+ QMicrophonePermission micPermission;
+ qApp->requestPermission(micPermission, [&](const QPermission &permission) {
+ if (permission.status() != Qt::PermissionStatus::Granted) {
+ qWarning("Microphone permission is not granted!");
+ engine.load(noPermissionsUrl);
+ } else {
+ engine.load(url);
+ }
+ });
+ });
+#else
engine.load(url);
+#endif
return app.exec();
}
diff --git a/examples/multimedia/video/recorder/main_no_permissions.qml b/examples/multimedia/video/recorder/main_no_permissions.qml
new file mode 100644
index 000000000..8c76533b0
--- /dev/null
+++ b/examples/multimedia/video/recorder/main_no_permissions.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+
+Window {
+ id: root
+ visible: true
+ title: "Media recorder"
+ width: Style.screenWidth
+ height: Style.screenHeigth
+
+ StyleRectangle {
+ anchors.fill: parent
+ Text {
+ anchors.fill: parent
+ anchors.margins: 20
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: qsTr("The example is not usable without the permissions.\n"
+ + "Please grant all requested permissions and restart the application.")
+ }
+ }
+}