Remove old Android code that have now has alternative public APIs
* Remove the old qjni private APIs. * Remove the Android permission private APIs. * Remove runOnAndroidThread(). Pick-to: 6.2 Change-Id: I37ba8b4cb87a099f067e2e0b6744b8d01a0f9bbc Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
182afbe335
commit
03eb44394e
@ -994,7 +994,6 @@ qt_internal_extend_target(Core CONDITION ANDROID AND NOT ANDROID_EMBEDDED
|
||||
io/qstandardpaths_android.cpp
|
||||
kernel/qcoreapplication_android.cpp
|
||||
io/qstorageinfo_unix.cpp
|
||||
kernel/qjni.cpp kernel/qjni_p.h
|
||||
kernel/qjnienvironment.cpp kernel/qjnienvironment.h
|
||||
kernel/qjniobject.cpp kernel/qjniobject.h
|
||||
kernel/qjnihelpers.cpp kernel/qjnihelpers_p.h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,292 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
// FIXME: Remove this once the JNI API is used by other modules.
|
||||
|
||||
#ifndef QJNI_P_H
|
||||
#define QJNI_P_H
|
||||
|
||||
#include <jni.h>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct Q_CORE_EXPORT QJNILocalRefDeleter
|
||||
{
|
||||
static void cleanup(jobject obj);
|
||||
};
|
||||
|
||||
// To simplify this we only define it for jobjects.
|
||||
typedef QScopedPointer<_jobject, QJNILocalRefDeleter> QJNIScopedLocalRef;
|
||||
|
||||
class Q_CORE_EXPORT QJNIEnvironmentPrivate
|
||||
{
|
||||
public:
|
||||
QJNIEnvironmentPrivate();
|
||||
~QJNIEnvironmentPrivate();
|
||||
JNIEnv *operator->();
|
||||
operator JNIEnv *() const;
|
||||
static jclass findClass(const char *className, JNIEnv *env = nullptr);
|
||||
|
||||
private:
|
||||
friend class QAndroidJniEnvironment;
|
||||
Q_DISABLE_COPY_MOVE(QJNIEnvironmentPrivate)
|
||||
JNIEnv *jniEnv;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QJNIObjectData
|
||||
{
|
||||
public:
|
||||
QJNIObjectData();
|
||||
~QJNIObjectData();
|
||||
jobject m_jobject;
|
||||
jclass m_jclass;
|
||||
bool m_own_jclass;
|
||||
QByteArray m_className;
|
||||
};
|
||||
|
||||
class Q_CORE_EXPORT QJNIObjectPrivate
|
||||
{
|
||||
public:
|
||||
QJNIObjectPrivate();
|
||||
explicit QJNIObjectPrivate(const char *className);
|
||||
QJNIObjectPrivate(const char *className, const char *sig, ...);
|
||||
explicit QJNIObjectPrivate(jclass clazz);
|
||||
QJNIObjectPrivate(jclass clazz, const char *sig, ...);
|
||||
// In most cases you should never call this function with a local ref. unless you intend
|
||||
// to manage the local ref. yourself.
|
||||
// NOTE: see fromLocalRef() for converting a local ref. to QJNIObjectPrivate.
|
||||
explicit QJNIObjectPrivate(jobject globalRef);
|
||||
|
||||
template <typename T>
|
||||
T callMethod(const char *methodName,
|
||||
const char *sig,
|
||||
...) const;
|
||||
template <typename T>
|
||||
T callMethod(const char *methodName) const;
|
||||
template <typename T>
|
||||
QJNIObjectPrivate callObjectMethod(const char *methodName) const;
|
||||
QJNIObjectPrivate callObjectMethod(const char *methodName,
|
||||
const char *sig,
|
||||
...) const;
|
||||
template <typename T>
|
||||
static T callStaticMethod(const char *className,
|
||||
const char *methodName,
|
||||
const char *sig, ...);
|
||||
template <typename T>
|
||||
static T callStaticMethod(const char *className,
|
||||
const char *methodName);
|
||||
template <typename T>
|
||||
static T callStaticMethod(jclass clazz,
|
||||
const char *methodName,
|
||||
const char *sig, ...);
|
||||
template <typename T>
|
||||
static T callStaticMethod(jclass clazz,
|
||||
const char *methodName);
|
||||
static QJNIObjectPrivate callStaticObjectMethod(const char *className,
|
||||
const char *methodName,
|
||||
const char *sig, ...);
|
||||
|
||||
static QJNIObjectPrivate callStaticObjectMethod(jclass clazz,
|
||||
const char *methodName,
|
||||
const char *sig, ...);
|
||||
|
||||
template <typename T>
|
||||
T getField(const char *fieldName) const;
|
||||
template <typename T>
|
||||
static T getStaticField(const char *className, const char *fieldName);
|
||||
template <typename T>
|
||||
static T getStaticField(jclass clazz, const char *fieldName);
|
||||
|
||||
QJNIObjectPrivate getObjectField(const char *fieldName, const char *sig) const;
|
||||
static QJNIObjectPrivate getStaticObjectField(const char *className,
|
||||
const char *fieldName,
|
||||
const char *sig);
|
||||
static QJNIObjectPrivate getStaticObjectField(jclass clazz,
|
||||
const char *fieldName,
|
||||
const char *sig);
|
||||
|
||||
template <typename T>
|
||||
void setField(const char *fieldName, T value);
|
||||
template <typename T>
|
||||
void setField(const char *fieldName, const char *sig, T value);
|
||||
template <typename T>
|
||||
static void setStaticField(const char *className,
|
||||
const char *fieldName,
|
||||
T value);
|
||||
template <typename T>
|
||||
static void setStaticField(const char *className,
|
||||
const char *fieldName,
|
||||
const char *sig,
|
||||
T value);
|
||||
template <typename T>
|
||||
static void setStaticField(jclass clazz,
|
||||
const char *fieldName,
|
||||
const char *sig,
|
||||
T value);
|
||||
|
||||
template <typename T>
|
||||
static void setStaticField(jclass clazz,
|
||||
const char *fieldName,
|
||||
T value);
|
||||
|
||||
static QJNIObjectPrivate fromString(const QString &string);
|
||||
QString toString() const;
|
||||
|
||||
static bool isClassAvailable(const char *className);
|
||||
bool isValid() const;
|
||||
jobject object() const { return d->m_jobject; }
|
||||
|
||||
template <typename T>
|
||||
inline QJNIObjectPrivate &operator=(T o)
|
||||
{
|
||||
jobject jobj = static_cast<jobject>(o);
|
||||
if (!isSameObject(jobj)) {
|
||||
d = QSharedPointer<QJNIObjectData>::create();
|
||||
if (jobj) {
|
||||
QJNIEnvironmentPrivate env;
|
||||
d->m_jobject = env->NewGlobalRef(jobj);
|
||||
jclass objectClass = env->GetObjectClass(jobj);
|
||||
d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
|
||||
env->DeleteLocalRef(objectClass);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This function takes ownership of the jobject and releases the local ref. before returning.
|
||||
static QJNIObjectPrivate fromLocalRef(jobject lref);
|
||||
|
||||
private:
|
||||
friend class QAndroidJniObject;
|
||||
|
||||
struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; };
|
||||
|
||||
QJNIObjectPrivate(const char *className, const char *sig, const QVaListPrivate &args);
|
||||
QJNIObjectPrivate(jclass clazz, const char *sig, const QVaListPrivate &args);
|
||||
|
||||
template <typename T>
|
||||
T callMethodV(const char *methodName,
|
||||
const char *sig,
|
||||
va_list args) const;
|
||||
QJNIObjectPrivate callObjectMethodV(const char *methodName,
|
||||
const char *sig,
|
||||
va_list args) const;
|
||||
template <typename T>
|
||||
static T callStaticMethodV(const char *className,
|
||||
const char *methodName,
|
||||
const char *sig,
|
||||
va_list args);
|
||||
template <typename T>
|
||||
static T callStaticMethodV(jclass clazz,
|
||||
const char *methodName,
|
||||
const char *sig,
|
||||
va_list args);
|
||||
static QJNIObjectPrivate callStaticObjectMethodV(const char *className,
|
||||
const char *methodName,
|
||||
const char *sig,
|
||||
va_list args);
|
||||
|
||||
static QJNIObjectPrivate callStaticObjectMethodV(jclass clazz,
|
||||
const char *methodName,
|
||||
const char *sig,
|
||||
va_list args);
|
||||
|
||||
bool isSameObject(jobject obj) const;
|
||||
bool isSameObject(const QJNIObjectPrivate &other) const;
|
||||
|
||||
friend bool operator==(const QJNIObjectPrivate &, const QJNIObjectPrivate &);
|
||||
friend bool operator!=(const QJNIObjectPrivate&, const QJNIObjectPrivate&);
|
||||
template <typename T> friend bool operator!=(const QJNIObjectPrivate&, T);
|
||||
template <typename T> friend bool operator==(const QJNIObjectPrivate&, T);
|
||||
template <typename T> friend bool operator!=(T, const QJNIObjectPrivate&);
|
||||
template <typename T> friend bool operator==(T, const QJNIObjectPrivate&);
|
||||
|
||||
QSharedPointer<QJNIObjectData> d;
|
||||
};
|
||||
|
||||
inline bool operator==(const QJNIObjectPrivate &obj1, const QJNIObjectPrivate &obj2)
|
||||
{
|
||||
return obj1.isSameObject(obj2);
|
||||
}
|
||||
|
||||
inline bool operator!=(const QJNIObjectPrivate &obj1, const QJNIObjectPrivate &obj2)
|
||||
{
|
||||
return !obj1.isSameObject(obj2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(const QJNIObjectPrivate &obj1, T obj2)
|
||||
{
|
||||
return obj1.isSameObject(static_cast<jobject>(obj2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(T obj1, const QJNIObjectPrivate &obj2)
|
||||
{
|
||||
return obj2.isSameObject(static_cast<jobject>(obj1));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator!=(const QJNIObjectPrivate &obj1, T obj2)
|
||||
{
|
||||
return !obj1.isSameObject(obj2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator!=(T obj1, const QJNIObjectPrivate &obj2)
|
||||
{
|
||||
return !obj2.isSameObject(obj1);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QJNI_P_H
|
@ -37,18 +37,14 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qcoreapplication.h"
|
||||
#include "qjnienvironment.h"
|
||||
#include "qjnihelpers_p.h"
|
||||
|
||||
#include "qjnienvironment.h"
|
||||
#include "qjniobject.h"
|
||||
#include "qlist.h"
|
||||
#include "qmutex.h"
|
||||
#include "qsemaphore.h"
|
||||
#include "qsharedpointer.h"
|
||||
#include "qthread.h"
|
||||
|
||||
#include <QtCore/private/qcoreapplication_p.h>
|
||||
#include <QtCore/qrunnable.h>
|
||||
|
||||
#include <android/log.h>
|
||||
#include <deque>
|
||||
@ -72,91 +68,20 @@ static JavaVM *g_javaVM = nullptr;
|
||||
static jobject g_jActivity = nullptr;
|
||||
static jobject g_jService = nullptr;
|
||||
static jobject g_jClassLoader = nullptr;
|
||||
static jclass g_jNativeClass = nullptr;
|
||||
static jmethodID g_runPendingCppRunnablesMethodID = nullptr;
|
||||
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
|
||||
static QBasicMutex g_pendingRunnablesMutex;
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QtAndroidPrivate::OnBindListener*, g_onBindListener, (nullptr));
|
||||
Q_GLOBAL_STATIC(QMutex, g_onBindListenerMutex);
|
||||
Q_GLOBAL_STATIC(QSemaphore, g_waitForServiceSetupSemaphore);
|
||||
Q_GLOBAL_STATIC(QAtomicInt, g_serviceSetupLockers);
|
||||
|
||||
class PermissionsResultClass : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PermissionsResultClass(const QtAndroidPrivate::PermissionsResultFunc &func) : m_func(func) {}
|
||||
Q_INVOKABLE void sendResult(const QtAndroidPrivate::PermissionsHash &result) { m_func(result); delete this;}
|
||||
|
||||
private:
|
||||
QtAndroidPrivate::PermissionsResultFunc m_func;
|
||||
};
|
||||
|
||||
typedef QHash<int, PermissionsResultClass*> PendingPermissionRequestsHash;
|
||||
Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests);
|
||||
static QBasicMutex g_pendingPermissionRequestsMutex;
|
||||
static int nextRequestCode()
|
||||
{
|
||||
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||
return counter.fetchAndAddRelaxed(1);
|
||||
}
|
||||
|
||||
// function called from Java from Android UI thread
|
||||
static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/)
|
||||
{
|
||||
for (;;) { // run all posted runnables
|
||||
QMutexLocker locker(&g_pendingRunnablesMutex);
|
||||
if (g_pendingRunnables->empty()) {
|
||||
break;
|
||||
}
|
||||
QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front()));
|
||||
g_pendingRunnables->pop_front();
|
||||
locker.unlock();
|
||||
runnable(); // run it outside the sync block!
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct GenericMotionEventListeners {
|
||||
QMutex mutex;
|
||||
QList<QtAndroidPrivate::GenericMotionEventListener *> listeners;
|
||||
};
|
||||
|
||||
enum {
|
||||
PERMISSION_GRANTED = 0
|
||||
};
|
||||
}
|
||||
Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
|
||||
|
||||
static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode,
|
||||
jobjectArray permissions, jintArray grantResults)
|
||||
{
|
||||
QMutexLocker locker(&g_pendingPermissionRequestsMutex);
|
||||
auto it = g_pendingPermissionRequests->find(requestCode);
|
||||
if (it == g_pendingPermissionRequests->end()) {
|
||||
// show an error or something ?
|
||||
return;
|
||||
}
|
||||
auto request = *it;
|
||||
g_pendingPermissionRequests->erase(it);
|
||||
locker.unlock();
|
||||
|
||||
Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::QueuedConnection;
|
||||
QtAndroidPrivate::PermissionsHash hash;
|
||||
const int size = env->GetArrayLength(permissions);
|
||||
std::unique_ptr<jint[]> results(new jint[size]);
|
||||
env->GetIntArrayRegion(grantResults, 0, size, results.get());
|
||||
for (int i = 0 ; i < size; ++i) {
|
||||
const auto &permission = QJniObject(env->GetObjectArrayElement(permissions, i)).toString();
|
||||
auto value = results[i] == PERMISSION_GRANTED ?
|
||||
QtAndroidPrivate::PermissionsResult::Granted :
|
||||
QtAndroidPrivate::PermissionsResult::Denied;
|
||||
hash[permission] = value;
|
||||
}
|
||||
QMetaObject::invokeMethod(request, "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash));
|
||||
}
|
||||
|
||||
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
|
||||
{
|
||||
jboolean ret = JNI_FALSE;
|
||||
@ -344,14 +269,12 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
|
||||
}
|
||||
|
||||
static const JNINativeMethod methods[] = {
|
||||
{"runPendingCppRunnables", "()V", reinterpret_cast<void *>(runPendingCppRunnables)},
|
||||
{"dispatchGenericMotionEvent", "(Landroid/view/MotionEvent;)Z", reinterpret_cast<void *>(dispatchGenericMotionEvent)},
|
||||
{"dispatchKeyEvent", "(Landroid/view/KeyEvent;)Z", reinterpret_cast<void *>(dispatchKeyEvent)},
|
||||
{"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", reinterpret_cast<void *>(sendRequestPermissionsResult)},
|
||||
};
|
||||
|
||||
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
|
||||
|
||||
env->DeleteLocalRef(jQtNative);
|
||||
if (!regOk && QJniEnvironment::checkAndClearExceptions(env))
|
||||
return JNI_ERR;
|
||||
|
||||
@ -361,17 +284,9 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
|
||||
if (!registerNativeInterfaceNatives())
|
||||
return JNI_ERR;
|
||||
|
||||
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
|
||||
"runPendingCppRunnablesOnAndroidThread",
|
||||
"()V");
|
||||
g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative));
|
||||
env->DeleteLocalRef(jQtNative);
|
||||
|
||||
qRegisterMetaType<QtAndroidPrivate::PermissionsHash>();
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
|
||||
jobject QtAndroidPrivate::activity()
|
||||
{
|
||||
return g_jActivity;
|
||||
@ -410,110 +325,6 @@ jint QtAndroidPrivate::androidSdkVersion()
|
||||
return sdkVersion;
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env)
|
||||
{
|
||||
QMutexLocker locker(&g_pendingRunnablesMutex);
|
||||
const bool triggerRun = g_pendingRunnables->empty();
|
||||
g_pendingRunnables->push_back(runnable);
|
||||
locker.unlock();
|
||||
if (triggerRun)
|
||||
env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID);
|
||||
}
|
||||
|
||||
static bool waitForSemaphore(int timeoutMs, QSharedPointer<QSemaphore> sem)
|
||||
{
|
||||
while (timeoutMs > 0) {
|
||||
if (sem->tryAcquire(1, 10))
|
||||
return true;
|
||||
timeoutMs -= 10;
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env, int timeoutMs)
|
||||
{
|
||||
QSharedPointer<QSemaphore> sem(new QSemaphore);
|
||||
runOnAndroidThread([&runnable, sem]{
|
||||
runnable();
|
||||
sem->release();
|
||||
}, env);
|
||||
waitForSemaphore(timeoutMs, sem);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::requestPermissions(JNIEnv *env,
|
||||
const QStringList &permissions,
|
||||
const QtAndroidPrivate::PermissionsResultFunc &callbackFunc,
|
||||
bool directCall)
|
||||
{
|
||||
if (androidSdkVersion() < 23 || !activity()) {
|
||||
QHash<QString, QtAndroidPrivate::PermissionsResult> res;
|
||||
for (const auto &perm : permissions)
|
||||
res[perm] = checkPermission(perm);
|
||||
callbackFunc(res);
|
||||
return;
|
||||
}
|
||||
// Check API 23+ permissions
|
||||
const int requestCode = nextRequestCode();
|
||||
if (!directCall) {
|
||||
QMutexLocker locker(&g_pendingPermissionRequestsMutex);
|
||||
(*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
|
||||
}
|
||||
|
||||
runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] {
|
||||
if (directCall) {
|
||||
QMutexLocker locker(&g_pendingPermissionRequestsMutex);
|
||||
(*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
|
||||
}
|
||||
|
||||
QJniEnvironment env;
|
||||
jclass clazz = env->FindClass("java/lang/String");
|
||||
|
||||
if (env.checkAndClearExceptions())
|
||||
return;
|
||||
|
||||
auto array = env->NewObjectArray(permissions.size(), clazz, nullptr);
|
||||
int index = 0;
|
||||
for (const auto &perm : permissions)
|
||||
env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object());
|
||||
QJniObject(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
|
||||
env->DeleteLocalRef(array);
|
||||
}, env);
|
||||
}
|
||||
|
||||
QtAndroidPrivate::PermissionsHash QtAndroidPrivate::requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs)
|
||||
{
|
||||
QSharedPointer<QHash<QString, QtAndroidPrivate::PermissionsResult>> res(new QHash<QString, QtAndroidPrivate::PermissionsResult>());
|
||||
QSharedPointer<QSemaphore> sem(new QSemaphore);
|
||||
requestPermissions(env, permissions, [sem, res](const QHash<QString, PermissionsResult> &result){
|
||||
*res = result;
|
||||
sem->release();
|
||||
}, true);
|
||||
if (waitForSemaphore(timeoutMs, sem))
|
||||
return std::move(*res);
|
||||
else // mustn't touch *res
|
||||
return QHash<QString, QtAndroidPrivate::PermissionsResult>();
|
||||
}
|
||||
|
||||
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
|
||||
{
|
||||
const auto res = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
|
||||
"checkSelfPermission",
|
||||
"(Ljava/lang/String;)I",
|
||||
QJniObject::fromString(permission).object());
|
||||
return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
|
||||
}
|
||||
|
||||
bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permission)
|
||||
{
|
||||
if (androidSdkVersion() < 23 || !activity())
|
||||
return false;
|
||||
|
||||
return QJniObject(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale",
|
||||
"(Ljava/lang/String;)Z",
|
||||
QJniObject::fromString(permission).object());
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
|
||||
{
|
||||
QMutexLocker locker(&g_genericMotionEventListeners()->mutex);
|
||||
@ -538,13 +349,6 @@ void QtAndroidPrivate::unregisterKeyEventListener(QtAndroidPrivate::KeyEventList
|
||||
g_keyEventListeners()->listeners.removeOne(listener);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::hideSplashScreen(JNIEnv *env, int duration)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
QJniObject::callStaticMethod<void>("org/qtproject/qt/android/QtNative",
|
||||
"hideSplashScreen", "(I)V", duration);
|
||||
}
|
||||
|
||||
void QtAndroidPrivate::waitForServiceSetup()
|
||||
{
|
||||
g_waitForServiceSetupSemaphore->acquire();
|
||||
@ -608,5 +412,3 @@ Q_CORE_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
#include "qjnihelpers.moc"
|
||||
|
@ -54,13 +54,9 @@
|
||||
#include <jni.h>
|
||||
#include <functional>
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QHash>
|
||||
#include <QMetaType>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QRunnable;
|
||||
|
||||
namespace QtAndroidPrivate
|
||||
{
|
||||
class Q_CORE_EXPORT ActivityResultListener
|
||||
@ -106,14 +102,6 @@ namespace QtAndroidPrivate
|
||||
virtual jobject onBind(jobject intent) = 0;
|
||||
};
|
||||
|
||||
enum class PermissionsResult {
|
||||
Granted,
|
||||
Denied
|
||||
};
|
||||
typedef QHash<QString, QtAndroidPrivate::PermissionsResult> PermissionsHash;
|
||||
typedef std::function<void()> Runnable;
|
||||
typedef std::function<void(const PermissionsHash &)> PermissionsResultFunc;
|
||||
|
||||
Q_CORE_EXPORT jobject activity();
|
||||
Q_CORE_EXPORT jobject service();
|
||||
Q_CORE_EXPORT jobject context();
|
||||
@ -122,12 +110,6 @@ namespace QtAndroidPrivate
|
||||
Q_CORE_EXPORT jclass findClass(const char *className, JNIEnv *env);
|
||||
jobject classLoader();
|
||||
Q_CORE_EXPORT jint androidSdkVersion();
|
||||
Q_CORE_EXPORT void runOnAndroidThread(const Runnable &runnable, JNIEnv *env);
|
||||
Q_CORE_EXPORT void runOnAndroidThreadSync(const Runnable &runnable, JNIEnv *env, int timeoutMs = INT_MAX);
|
||||
Q_CORE_EXPORT void requestPermissions(JNIEnv *env, const QStringList &permissions, const PermissionsResultFunc &callbackFunc, bool directCall = false);
|
||||
Q_CORE_EXPORT PermissionsHash requestPermissionsSync(JNIEnv *env, const QStringList &permissions, int timeoutMs = INT_MAX);
|
||||
Q_CORE_EXPORT PermissionsResult checkPermission(const QString &permission);
|
||||
Q_CORE_EXPORT bool shouldShowRequestPermissionRationale(const QString &permission);
|
||||
|
||||
bool registerPermissionNatives();
|
||||
bool registerNativeInterfaceNatives();
|
||||
@ -151,9 +133,6 @@ namespace QtAndroidPrivate
|
||||
Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener);
|
||||
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener);
|
||||
|
||||
// TODO: Remove once other modules refectoring is done and androidextras is not needed.
|
||||
Q_CORE_EXPORT void hideSplashScreen(JNIEnv *env, int duration = 0);
|
||||
|
||||
Q_CORE_EXPORT void waitForServiceSetup();
|
||||
Q_CORE_EXPORT int acuqireServiceSetup(int flags);
|
||||
Q_CORE_EXPORT void setOnBindListener(OnBindListener *listener);
|
||||
@ -162,6 +141,4 @@ namespace QtAndroidPrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QtAndroidPrivate::PermissionsHash)
|
||||
|
||||
#endif // QJNIHELPERS_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user