summaryrefslogtreecommitdiffstats
path: root/src/plugins/android
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-20 13:46:06 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-20 13:46:06 +0100
commit5c0cca78f410e8a89d3216aeba916d73070398f4 (patch)
treee21b54b36dde0825f9c07899c705dcbb91dcabbd /src/plugins/android
parent4e809d4be9bb60cb20e5c98e4b2664af8e1cc2f3 (diff)
parent49bf444b44dac10602af0af862f0951835ea5895 (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
Diffstat (limited to 'src/plugins/android')
-rw-r--r--src/plugins/android/src/common/qandroidmultimediautils.cpp12
-rw-r--r--src/plugins/android/src/common/qandroidmultimediautils.h3
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.cpp33
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.h5
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.cpp13
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.h2
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcapturesession.cpp6
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp15
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp5
-rw-r--r--src/plugins/android/src/wrappers/jni/androidmediarecorder.h1
10 files changed, 72 insertions, 23 deletions
diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp
index a4a7f773d..1f03d5d29 100644
--- a/src/plugins/android/src/common/qandroidmultimediautils.cpp
+++ b/src/plugins/android/src/common/qandroidmultimediautils.cpp
@@ -113,7 +113,7 @@ AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::Pix
}
}
-bool qt_androidRequestPermission(const QString &key)
+static bool androidRequestPermission(const QString &key)
{
using namespace QtAndroidPrivate;
@@ -139,4 +139,14 @@ bool qt_androidRequestPermission(const QString &key)
return true;
}
+bool qt_androidRequestCameraPermission()
+{
+ return androidRequestPermission(QLatin1String("android.permission.CAMERA"));
+}
+
+bool qt_androidRequestRecordingPermission()
+{
+ return androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO"));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h
index 0a837ae3c..381671cb8 100644
--- a/src/plugins/android/src/common/qandroidmultimediautils.h
+++ b/src/plugins/android/src/common/qandroidmultimediautils.h
@@ -55,7 +55,8 @@ bool qt_sizeLessThan(const QSize &s1, const QSize &s2);
QVideoFrame::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f);
AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrame::PixelFormat f);
-bool qt_androidRequestPermission(const QString &key);
+bool qt_androidRequestCameraPermission();
+bool qt_androidRequestRecordingPermission();
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp
index 25e67e865..fd6eb0e8b 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.cpp
+++ b/src/plugins/android/src/common/qandroidvideooutput.cpp
@@ -49,6 +49,8 @@
#include <qopenglshaderprogram.h>
#include <qopenglframebufferobject.h>
#include <QtCore/private/qjnihelpers_p.h>
+#include <QtGui/QWindow>
+#include <QtGui/QOffscreenSurface>
QT_BEGIN_NAMESPACE
@@ -182,6 +184,8 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent)
QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput()
{
+ delete m_offscreenSurface;
+ delete m_glContext;
clearSurfaceTexture();
if (m_glDeleter) { // Make sure all of these are deleted on the render thread.
@@ -345,6 +349,35 @@ bool QAndroidTextureVideoOutput::renderFrameToFbo()
if (!m_nativeSize.isValid() || !m_surfaceTexture)
return false;
+ // Make sure we have an OpenGL context to make current.
+ if (!QOpenGLContext::currentContext() && !m_glContext) {
+ // Create Hidden QWindow surface to create context in this thread.
+ m_offscreenSurface = new QWindow();
+ m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface);
+ // Needs geometry to be a valid surface, but size is not important.
+ m_offscreenSurface->setGeometry(0, 0, 1, 1);
+ m_offscreenSurface->create();
+
+ // Create OpenGL context and set share context from surface.
+ m_glContext = new QOpenGLContext();
+ m_glContext->setFormat(m_offscreenSurface->requestedFormat());
+
+ auto surface = qobject_cast<QAbstractVideoSurface *>(m_surface->property("videoSurface").value<QObject *>());
+ if (!surface)
+ surface = m_surface;
+ auto shareContext = qobject_cast<QOpenGLContext *>(surface->property("GLContext").value<QObject *>());
+ if (shareContext)
+ m_glContext->setShareContext(shareContext);
+
+ if (!m_glContext->create()) {
+ qWarning("Failed to create QOpenGLContext");
+ return false;
+ }
+ }
+
+ if (m_glContext)
+ m_glContext->makeCurrent(m_offscreenSurface);
+
createGLResources();
m_surfaceTexture->updateTexImage();
diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h
index 2a35247e9..456fe8e22 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.h
+++ b/src/plugins/android/src/common/qandroidvideooutput.h
@@ -51,6 +51,8 @@ class AndroidSurfaceHolder;
class QOpenGLFramebufferObject;
class QOpenGLShaderProgram;
class QAbstractVideoSurface;
+class QWindow;
+class QOpenGLContext;
class QAndroidVideoOutput : public QObject
{
@@ -132,6 +134,9 @@ private:
bool m_surfaceTextureCanAttachToContext;
+ QWindow *m_offscreenSurface = nullptr;
+ QOpenGLContext *m_glContext = nullptr;
+
friend class AndroidTextureVideoBuffer;
};
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
index 5df8241e0..a0f809376 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
@@ -77,6 +77,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
, m_captureCanceled(false)
, m_currentImageCaptureId(-1)
, m_previewCallback(0)
+ , m_keepActive(false)
{
m_mediaStorageLocation.addStorageLocation(
QMediaStorageLocation::Pictures,
@@ -182,7 +183,7 @@ bool QAndroidCameraSession::open()
m_status = QCamera::LoadingStatus;
emit statusChanged(m_status);
- m_camera = AndroidCamera::requestCameraPermission() ? AndroidCamera::open(m_selectedCamera) : nullptr;
+ m_camera = AndroidCamera::open(m_selectedCamera);
if (m_camera) {
connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed()));
@@ -912,7 +913,7 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state
{
switch (state) {
case Qt::ApplicationInactive:
- if (m_state != QCamera::UnloadedState) {
+ if (!m_keepActive && m_state != QCamera::UnloadedState) {
m_savedState = m_state;
close();
m_state = QCamera::UnloadedState;
@@ -930,4 +931,12 @@ void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state
}
}
+bool QAndroidCameraSession::requestRecordingPermission()
+{
+ m_keepActive = true;
+ const bool result = qt_androidRequestRecordingPermission();
+ m_keepActive = false;
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h
index b51dcc628..728dc484e 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h
@@ -112,6 +112,7 @@ public:
virtual void onFrameAvailable(const QVideoFrame &frame) = 0;
};
void setPreviewCallback(PreviewCallback *callback);
+ bool requestRecordingPermission();
Q_SIGNALS:
void statusChanged(QCamera::Status status);
@@ -196,6 +197,7 @@ private:
QSet<QAndroidMediaVideoProbeControl *> m_videoProbes;
QMutex m_videoProbesMutex;
PreviewCallback *m_previewCallback;
+ bool m_keepActive;
};
QT_END_NAMESPACE
diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp
index bc9bc983e..7cc3ad619 100644
--- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp
+++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp
@@ -206,8 +206,10 @@ void QAndroidCaptureSession::start()
delete m_mediaRecorder;
}
-
- if (!AndroidMediaRecorder::requestRecordingPermission()) {
+ const bool granted = m_cameraSession
+ ? m_cameraSession->requestRecordingPermission()
+ : qt_androidRequestRecordingPermission();
+ if (!granted) {
setStatus(QMediaRecorder::UnavailableStatus);
Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Permission denied."));
return;
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index 2f32fb742..3ea7bc773 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -58,11 +58,6 @@ QT_BEGIN_NAMESPACE
static const char QtCameraListenerClassName[] = "org/qtproject/qt5/android/multimedia/QtCameraListener";
-static QString cameraPermissionKey()
-{
- return QStringLiteral("android.permission.CAMERA");
-}
-
typedef QHash<int, AndroidCamera *> CameraMap;
Q_GLOBAL_STATIC(CameraMap, cameras)
Q_GLOBAL_STATIC(QReadWriteLock, rwLock)
@@ -324,6 +319,9 @@ AndroidCamera::~AndroidCamera()
AndroidCamera *AndroidCamera::open(int cameraId)
{
+ if (!qt_androidRequestCameraPermission())
+ return nullptr;
+
AndroidCameraPrivate *d = new AndroidCameraPrivate();
QThread *worker = new QThread;
worker->start();
@@ -764,7 +762,7 @@ QJNIObjectPrivate AndroidCamera::getCameraObject()
int AndroidCamera::getNumberOfCameras()
{
- if (!requestCameraPermission())
+ if (!qt_androidRequestCameraPermission())
return 0;
return QJNIObjectPrivate::callStaticMethod<jint>("android/hardware/Camera",
@@ -801,11 +799,6 @@ void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info)
}
}
-bool AndroidCamera::requestCameraPermission()
-{
- return qt_androidRequestPermission(cameraPermissionKey());
-}
-
void AndroidCamera::startPreview()
{
Q_D(AndroidCamera);
diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
index d0101411b..d607ab806 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp
@@ -383,11 +383,6 @@ void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder)
}
}
-bool AndroidMediaRecorder::requestRecordingPermission()
-{
- return qt_androidRequestPermission(QLatin1String("android.permission.RECORD_AUDIO"));
-}
-
bool AndroidMediaRecorder::initJNI(JNIEnv *env)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtMediaRecorderListenerClassName,
diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h
index cd2d164d8..e4b3a80ea 100644
--- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h
+++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h
@@ -160,7 +160,6 @@ public:
void setSurfaceTexture(AndroidSurfaceTexture *texture);
void setSurfaceHolder(AndroidSurfaceHolder *holder);
- static bool requestRecordingPermission();
static bool initJNI(JNIEnv *env);
Q_SIGNALS: