From d5d7dcfb15c0b5c5e9009b83fba922ea0b7e86f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20Str=C3=B8mme?= <christian.stromme@qt.io>
Date: Tue, 13 Dec 2016 17:26:18 +0100
Subject: [PATCH] OpenSL ES: Added run-time permission checks for recording on
 Android

Make sure that we have permission to record before starting a recording
session.

[ChangeLog][OpenSL ES][Android] Added run-time permission checks for
recording on Android.

Task-number: QTBUG-55992
Change-Id: Iab7416384336975fdf4de8024f02ab2414033163
Reviewed-by: Yoann Lopes <yoann.lopes@qt.io>
---
 src/plugins/opensles/qopenslesaudioinput.cpp | 31 ++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/plugins/opensles/qopenslesaudioinput.cpp b/src/plugins/opensles/qopenslesaudioinput.cpp
index 30860650b..c3f5ed422 100644
--- a/src/plugins/opensles/qopenslesaudioinput.cpp
+++ b/src/plugins/opensles/qopenslesaudioinput.cpp
@@ -46,6 +46,8 @@
 
 #ifdef ANDROID
 #include <SLES/OpenSLES_AndroidConfiguration.h>
+#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/private/qjni_p.h>
 #endif
 
 QT_BEGIN_NAMESPACE
@@ -55,6 +57,32 @@ QT_BEGIN_NAMESPACE
 #define MINIMUM_PERIOD_TIME_MS 5
 
 #ifdef ANDROID
+static bool hasRecordingPermission()
+{
+    using namespace QtAndroidPrivate;
+    if (androidSdkVersion() < 23)
+        return true;
+
+    const QString key(QLatin1String("android.permission.RECORD_AUDIO"));
+    PermissionsResult res = checkPermission(key);
+    if (res == PermissionsResult::Granted) // Permission already granted?
+        return true;
+
+    QJNIEnvironmentPrivate env;
+    const auto &results = requestPermissionsSync(env, QStringList() << key);
+    if (!results.contains(key)) {
+        qWarning("No permission found for key: %s", qPrintable(key));
+        return false;
+    }
+
+    if (results[key] == PermissionsResult::Denied) {
+        qDebug("%s - Permission denied by user!", qPrintable(key));
+        return false;
+    }
+
+    return true;
+}
+
 static void bufferQueueCallback(SLAndroidSimpleBufferQueueItf, void *context)
 #else
 static void bufferQueueCallback(SLBufferQueueItf, void *context)
@@ -179,6 +207,9 @@ QIODevice *QOpenSLESAudioInput::start()
 
 bool QOpenSLESAudioInput::startRecording()
 {
+    if (!hasRecordingPermission())
+        return false;
+
     m_processedBytes = 0;
     m_clockStamp.restart();
     m_lastNotifyTime = 0;
-- 
GitLab