Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
androidsurfaceview.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/qcoreapplication.h>
7#include <QtCore/qdebug.h>
8#include <QtCore/qlist.h>
9#include <QtCore/qmutex.h>
10#include <QtGui/qwindow.h>
11
13
14static const char QtSurfaceHolderCallbackClassName[] = "org/qtproject/qt/android/multimedia/QtSurfaceHolderCallback";
16Q_GLOBAL_STATIC(SurfaceHolders, surfaceHolders)
17Q_GLOBAL_STATIC(QMutex, shLock)
18
19AndroidSurfaceHolder::AndroidSurfaceHolder(QJniObject object)
20 : m_surfaceHolder(object)
21 , m_surfaceCreated(false)
22{
23 if (!m_surfaceHolder.isValid())
24 return;
25
26 {
27 QMutexLocker locker(shLock());
28 surfaceHolders->append(this);
29 }
30
31 QJniObject callback(QtSurfaceHolderCallbackClassName, "(J)V", reinterpret_cast<jlong>(this));
32 m_surfaceHolder.callMethod<void>("addCallback",
33 "(Landroid/view/SurfaceHolder$Callback;)V",
34 callback.object());
35}
36
37AndroidSurfaceHolder::~AndroidSurfaceHolder()
38{
39 QMutexLocker locker(shLock());
40 const int i = surfaceHolders->indexOf(this);
41 if (Q_UNLIKELY(i == -1))
42 return;
43
44 surfaceHolders->remove(i);
45}
46
47jobject AndroidSurfaceHolder::surfaceHolder() const
48{
49 return m_surfaceHolder.object();
50}
51
52bool AndroidSurfaceHolder::isSurfaceCreated() const
53{
54 QMutexLocker locker(shLock());
55 return m_surfaceCreated;
56}
57
58void AndroidSurfaceHolder::handleSurfaceCreated(JNIEnv*, jobject, jlong id)
59{
60 QMutexLocker locker(shLock());
61 const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id));
62 if (Q_UNLIKELY(i == -1))
63 return;
64
65 (*surfaceHolders)[i]->m_surfaceCreated = true;
66 Q_EMIT (*surfaceHolders)[i]->surfaceCreated();
67}
68
69void AndroidSurfaceHolder::handleSurfaceDestroyed(JNIEnv*, jobject, jlong id)
70{
71 QMutexLocker locker(shLock());
72 const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id));
73 if (Q_UNLIKELY(i == -1))
74 return;
75
76 (*surfaceHolders)[i]->m_surfaceCreated = false;
77}
78
79bool AndroidSurfaceHolder::registerNativeMethods()
80{
81 static const JNINativeMethod methods[] = {
82 {"notifySurfaceCreated", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceCreated},
83 {"notifySurfaceDestroyed", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceDestroyed}
84 };
85
86 const int size = std::size(methods);
87 return QJniEnvironment().registerNativeMethods(QtSurfaceHolderCallbackClassName, methods, size);
88}
89
90AndroidSurfaceView::AndroidSurfaceView()
91 : m_window(0)
92 , m_surfaceHolder(0)
93 , m_pendingVisible(-1)
94{
95 QNativeInterface::QAndroidApplication::runOnAndroidMainThread([this] {
96 m_surfaceView = QJniObject("android/view/SurfaceView",
97 "(Landroid/content/Context;)V",
98 QNativeInterface::QAndroidApplication::context().object());
99 }).waitForFinished();
100
101 Q_ASSERT(m_surfaceView.isValid());
102
103 QJniObject holder = m_surfaceView.callObjectMethod("getHolder",
104 "()Landroid/view/SurfaceHolder;");
105 if (!holder.isValid()) {
106 m_surfaceView = QJniObject();
107 } else {
108 m_surfaceHolder = new AndroidSurfaceHolder(holder);
109 connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated,
110 this, &AndroidSurfaceView::surfaceCreated);
111 { // Lock now to avoid a race with handleSurfaceCreated()
112 QMutexLocker locker(shLock());
113 m_window = QWindow::fromWinId(WId(m_surfaceView.object()));
114
115 if (m_pendingVisible != -1)
116 m_window->setVisible(m_pendingVisible);
117 if (m_pendingGeometry.isValid())
118 m_window->setGeometry(m_pendingGeometry);
119 }
120 }
121}
122
123AndroidSurfaceView::~AndroidSurfaceView()
124{
125 delete m_surfaceHolder;
126 delete m_window;
127}
128
129AndroidSurfaceHolder *AndroidSurfaceView::holder() const
130{
131 return m_surfaceHolder;
132}
133
134void AndroidSurfaceView::setVisible(bool v)
135{
136 if (m_window)
137 m_window->setVisible(v);
138 else
139 m_pendingVisible = int(v);
140}
141
142void AndroidSurfaceView::setGeometry(int x, int y, int width, int height)
143{
144 if (m_window)
145 m_window->setGeometry(x, y, width, height);
146 else
147 m_pendingGeometry = QRect(x, y, width, height);
148}
149
150QT_END_NAMESPACE
151
152#include "moc_androidsurfaceview_p.cpp"
QList< AndroidSurfaceHolder * > SurfaceHolders
static QT_BEGIN_NAMESPACE const char QtSurfaceHolderCallbackClassName[]