Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
androidbackendregister.h
Go to the documentation of this file.
1
// Copyright (C) 2024 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
// Qt-Security score:significant reason:default
4
5
#
ifndef
ANDROIDBACKENDREGISTER_H
6
#
define
ANDROIDBACKENDREGISTER_H
7
8
#
include
<
type_traits
>
9
10
#
include
<
QtCore
/
qjnienvironment
.
h
>
11
#
include
<
QtCore
/
qjnitypes
.
h
>
12
#
include
<
QtCore
/
qjniobject
.
h
>
13
14
#
include
<
QtCore
/
qstring
.
h
>
15
#
include
<
QtCore
/
qmap
.
h
>
16
#
include
<
QtCore
/
qmutex
.
h
>
17
#
include
<
QtCore
/
qloggingcategory
.
h
>
18
19
QT_BEGIN_NAMESPACE
20
21
Q_DECLARE_LOGGING_CATEGORY(lcAndroidBackendRegister)
22
23
/*
24
\internal
25
26
This class is used to [un]register QJniObjects which implement specific interfaces. These
27
objects can then be fetched or directly called by using that interface.
28
29
This is intended to decouple the Qt C++ code from the underlying Java implementation, as Qt now
30
has multiple separate usecases, each of which may have different implementations and support
31
different features.
32
33
To use this register, the interface must be declared as a JNI class via Q_DECLARE_JNI_CLASS:
34
35
Q_DECLARE_JNI_CLASS(ImaginaryInterface, "org/qtproject/qt/android/ImaginaryInterface")
36
37
Where ImaginaryInterface is a Java interface like this:
38
39
@UsedFromNativeCode
40
interface ImaginaryInterface {
41
void doSomething(int imaginary, int imaginary2);
42
}
43
44
After that, the features provided by that interface can be used in the C++ code in two ways:
45
46
Use the convenience method callInterface() to call a method directly:
47
48
AndroidBackendRegister *reg = QtAndroid::backendRegister();
49
int imaginary, imaginary2;
50
reg->callInterface<QtJniTypes::ImaginaryInterface, void>("doSomething", imaginary, imaginary2);
51
52
Or get the QJniObject directly and use it as you would any other QJniObject:
53
AndroidBackendRegister *reg = QtAndroid::backendRegister();
54
auto imaginary = reg->getInterface<QtJniTypes::ImaginaryInterface>();
55
// ... do whatever with QJniObject
56
57
In order to register a new interface on the Java side, the BackendRegister class must be used,
58
with its native functions registerBackend() and unregisterBackend():
59
60
BackendRegister.registerBackend(ImaginaryInterface.class, imaginaryInterfaceObject);
61
62
and
63
64
BackendRegister.unregisterBackend(ImaginaryInterface.class);
65
66
Note that only one object can be registered for each interface. If multiple objects are
67
registered, only the latest one is kept. Thus, you only need to declare the interface you want
68
to unregister, not the object that implements the interface as well.
69
70
If the interface needs to be available as soon as possible, it should be registered immediately
71
after Qt has started, by using the QtNative app state listener functionality.
72
*/
73
74
template
<
typename
T>
75
using
ValidInterfaceType = std::enable_if_t<std::is_base_of_v<QtJniTypes::JObjectBase, T>,
bool
>;
76
77
class
AndroidBackendRegister
78
{
79
public
:
80
static
bool
registerNatives
();
81
82
/*
83
\internal
84
85
Returns a QJniObject which is registered for the given interface.
86
Requires the type of the requested interface to be registered via
87
Q_DECLARE_JNI_CLASS. (see ValidInterfaceType).
88
*/
89
template
<
typename
T, ValidInterfaceType<T> =
true
>
90
[[nodiscard]] T
getInterface
()
91
{
92
QMutexLocker lock(&m_registerMutex);
93
return
m_register.value(QString(QtJniTypes::Traits<T>::className().data()));
94
}
95
96
template
<
typename
Object
>
97
using
IsObjectType
=
98
typename
std
::
disjunction
<
std
::
is_base_of
<
QJniObject
,
Object
>,
99
std
::
is_base_of
<
QtJniTypes
::
JObjectBase
,
Object
>>;
100
101
/*
102
\internal
103
104
Convenience function that calls getInterface<Interface>() and then QJniObject::callMethod()
105
on the resulting object, forwarding the rest of the parameters to that function.
106
107
If the interface is not registered, a warning is printed and an empty object is returned.
108
*/
109
template
<
typename
Interface,
typename
Ret =
void
,
typename
... Args,
110
ValidInterfaceType<Interface> =
true
>
111
auto
callInterface
(
const
char
*func, Args... args)
112
{
113
if
(
const
auto
obj = getInterface<Interface>(); obj.isValid()) {
114
return
obj.
template
callMethod<Ret, Args...>(func, std::forward<Args>(args)...);
115
}
else
{
116
qWarning() <<
"No interface with className"
117
<< QtJniTypes::Traits<Interface>::className() <<
"has been registered."
;
118
}
119
120
if
constexpr
(IsObjectType<Ret>::value)
121
return
Ret(QJniObject());
122
if
constexpr
(!
std
::is_same_v<Ret,
void
>)
123
return
Ret{};
124
}
125
126
private
:
127
QMutex m_registerMutex;
128
QMap<QString, QJniObject> m_register;
129
130
static
jboolean isNull(JNIEnv *, jclass);
131
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE
(
isNull
)
132
static
void
registerBackend(JNIEnv *, jclass, jclass interfaceClass, jobject interface);
133
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE
(
registerBackend
)
134
static
void
unregisterBackend(JNIEnv *, jclass, jclass interfaceClass);
135
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE
(
unregisterBackend
)
136
};
137
138
QT_END_NAMESPACE
139
140
#
endif
// ANDROIDBACKENDREGISTER_H
AndroidBackendRegister
Definition
androidbackendregister.h:78
AndroidBackendRegister::callInterface
auto callInterface(const char *func, Args... args)
Definition
androidbackendregister.h:111
AndroidBackendRegister::registerNatives
static bool registerNatives()
Definition
androidbackendregister.cpp:15
AndroidBackendRegister::getInterface
T getInterface()
Definition
androidbackendregister.h:90
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QtAndroid
Definition
androidjnimain.h:35
QtAndroid::backendRegister
AndroidBackendRegister * backendRegister()
Definition
androidjnimain.cpp:385
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtbase
src
plugins
platforms
android
androidbackendregister.h
Generated on
for Qt by
1.18.0