diff options
-rw-r--r-- | src/corelib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_android.cpp | 300 | ||||
-rw-r--r-- | src/corelib/platform/android/qandroidextras.cpp | 252 | ||||
-rw-r--r-- | src/corelib/platform/android/qandroidextras_p.h | 40 |
5 files changed, 292 insertions, 303 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 2df53a0a00..d44011f6c3 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -981,7 +981,6 @@ qt_internal_extend_target(Core CONDITION UNIX AND NOT APPLE qt_internal_extend_target(Core CONDITION ANDROID AND NOT ANDROID_EMBEDDED SOURCES io/qstandardpaths_android.cpp - kernel/qcoreapplication_android.cpp io/qstorageinfo_unix.cpp kernel/qjnienvironment.cpp kernel/qjnienvironment.h kernel/qjniobject.cpp kernel/qjniobject.h diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 8f53790cb7..10dbe2f684 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -3084,7 +3084,6 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc \sa Q_OBJECT, QObject::tr() */ #if QT_CONFIG(future) && !defined(QT_NO_QOBJECT) -#if !defined(Q_OS_ANDROID) QFuture<QApplicationPermission::PermissionResult> defaultPermissionFuture() { @@ -3127,7 +3126,6 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc Q_UNUSED(permission) return defaultPermissionFuture(); } -#endif /*! Requests the \a permission and returns a QFuture representing the diff --git a/src/corelib/kernel/qcoreapplication_android.cpp b/src/corelib/kernel/qcoreapplication_android.cpp deleted file mode 100644 index 671db805e3..0000000000 --- a/src/corelib/kernel/qcoreapplication_android.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui 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$ -** -****************************************************************************/ - -#include "qcoreapplication.h" -#include "qcoreapplication_p.h" - -#include <QtCore/private/qjnihelpers_p.h> -#include <QtCore/qfuture.h> -#include <QtCore/qjnienvironment.h> -#include <QtCore/qjniobject.h> -#include <QtCore/qlist.h> -#include <QtCore/qmutex.h> -#include <QtCore/qpromise.h> -#include <QtCore/qscopedpointer.h> - -QT_BEGIN_NAMESPACE - -static const char qtNativeClassName[] = "org/qtproject/qt/android/QtNative"; - -QApplicationPermission::PermissionResult resultFromAndroid(jint value) -{ - return value == 0 ? QApplicationPermission::Authorized : QApplicationPermission::Denied; -} - -using PendingPermissionRequestsHash - = QHash<int, QSharedPointer<QPromise<QApplicationPermission::PermissionResult>>>; -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); -} - -static QStringList nativeStringsFromPermission(QApplicationPermission::PermissionType permission) -{ - static const auto precisePerm = QStringLiteral("android.permission.ACCESS_FINE_LOCATION"); - static const auto coarsePerm = QStringLiteral("android.permission.ACCESS_COARSE_LOCATION"); - static const auto backgroundPerm = - QStringLiteral("android.permission.ACCESS_BACKGROUND_LOCATION"); - - switch (permission) { - case QApplicationPermission::Location: - return {coarsePerm}; - case QApplicationPermission::PreciseLocation: - return {precisePerm}; - case QApplicationPermission::BackgroundLocation: - // Keep the background permission first to be able to use .first() - // in checkPermission because it takes single permission - if (QtAndroidPrivate::androidSdkVersion() >= 29) - return {backgroundPerm, coarsePerm}; - return {coarsePerm}; - case QApplicationPermission::PreciseBackgroundLocation: - // Keep the background permission first to be able to use .first() - // in checkPermission because it takes single permission - if (QtAndroidPrivate::androidSdkVersion() >= 29) - return {backgroundPerm, precisePerm}; - return {precisePerm}; - case QApplicationPermission::Camera: - return {QStringLiteral("android.permission.CAMERA")}; - case QApplicationPermission::Microphone: - return {QStringLiteral("android.permission.RECORD_AUDIO")}; - case QApplicationPermission::Bluetooth: - return { QStringLiteral("android.permission.BLUETOOTH") }; - case QApplicationPermission::BodySensors: - return {QStringLiteral("android.permission.BODY_SENSORS")}; - case QApplicationPermission::PhysicalActivity: - return {QStringLiteral("android.permission.ACTIVITY_RECOGNITION")}; - case QApplicationPermission::Contacts: - return {QStringLiteral("android.permission.READ_CONTACTS"), - QStringLiteral("android.permission.WRITE_CONTACTS")}; - case QApplicationPermission::Storage: - return {QStringLiteral("android.permission.READ_EXTERNAL_STORAGE"), - QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE")}; - case QApplicationPermission::Calendar: - return {QStringLiteral("android.permission.READ_CALENDAR"), - QStringLiteral("android.permission.WRITE_CALENDAR")}; - } - - return {}; -} - -/*! - \internal - - This function is called when the result of the permission request is available. - Once a permission is requested, the result is braodcast by the OS and listened - to by QtActivity which passes it to C++ through a native JNI method call. - */ -static void sendRequestPermissionsResult(JNIEnv *env, jobject *obj, jint requestCode, - jobjectArray permissions, jintArray grantResults) -{ - Q_UNUSED(obj); - - QMutexLocker locker(&g_pendingPermissionRequestsMutex); - auto it = g_pendingPermissionRequests->constFind(requestCode); - if (it == g_pendingPermissionRequests->constEnd()) { - qWarning() << "Found no valid pending permission request for request code" << requestCode; - return; - } - - auto request = *it; - g_pendingPermissionRequests->erase(it); - locker.unlock(); - - 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) { - QApplicationPermission::PermissionResult result = resultFromAndroid(results[i]); - request->addResult(result, i); - } - - request->finish(); -} - -QFuture<QApplicationPermission::PermissionResult> -requestPermissionsInternal(const QStringList &permissions) -{ - QSharedPointer<QPromise<QApplicationPermission::PermissionResult>> promise; - promise.reset(new QPromise<QApplicationPermission::PermissionResult>()); - QFuture<QApplicationPermission::PermissionResult> future = promise->future(); - promise->start(); - - // No mechanism to request permission for SDK version below 23, because - // permissions defined in the manifest are granted at install time. - if (QtAndroidPrivate::androidSdkVersion() < 23) { - for (int i = 0; i < permissions.size(); ++i) - promise->addResult(QCoreApplication::checkPermission(permissions.at(i)).result(), i); - promise->finish(); - return future; - } - - const int requestCode = nextRequestCode(); - QMutexLocker locker(&g_pendingPermissionRequestsMutex); - g_pendingPermissionRequests->insert(requestCode, promise); - - QNativeInterface::QAndroidApplication::runOnAndroidMainThread([permissions, requestCode] { - QJniEnvironment env; - jclass clazz = env.findClass("java/lang/String"); - auto array = env->NewObjectArray(permissions.size(), clazz, nullptr); - int index = 0; - - for (auto &perm : permissions) - env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object()); - - QJniObject(QtAndroidPrivate::activity()).callMethod<void>("requestPermissions", - "([Ljava/lang/String;I)V", - array, - requestCode); - env->DeleteLocalRef(array); - }); - - return future; -} - -QFuture<QApplicationPermission::PermissionResult> -QCoreApplicationPrivate::requestPermission(const QString &permission) -{ - // avoid the uneccessary call and response to an empty permission string - if (permission.size() > 0) - return requestPermissionsInternal({permission}); - - QPromise<QApplicationPermission::PermissionResult> promise; - QFuture<QApplicationPermission::PermissionResult> future = promise.future(); - promise.start(); - promise.addResult(QApplicationPermission::Denied); - promise.finish(); - return future; -} - -static bool isBackgroundLocationApi29(QApplicationPermission::PermissionType permission) -{ - return QNativeInterface::QAndroidApplication::sdkVersion() >= 29 - && (permission == QApplicationPermission::BackgroundLocation - || permission == QApplicationPermission::PreciseBackgroundLocation); -} - -QFuture<QApplicationPermission::PermissionResult> -QCoreApplicationPrivate::requestPermission(QApplicationPermission::PermissionType permission) -{ - QSharedPointer<QPromise<QApplicationPermission::PermissionResult>> promise; - promise.reset(new QPromise<QApplicationPermission::PermissionResult>()); - QFuture<QApplicationPermission::PermissionResult> future = promise->future(); - promise->start(); - const auto nativePermissions = nativeStringsFromPermission(permission); - - if (nativePermissions.size() > 0) { - requestPermissionsInternal(nativePermissions).then( - [promise, permission](QFuture<QApplicationPermission::PermissionResult> future) { - auto AuthorizedCount = future.results().count(QApplicationPermission::Authorized); - if (AuthorizedCount > 0) { - if (isBackgroundLocationApi29(permission)) - promise->addResult(future.resultAt(0), 0); - else - promise->addResult(QApplicationPermission::Authorized, 0); - } else { - promise->addResult(QApplicationPermission::Denied, 0); - } - promise->finish(); - }); - - return future; - } - - promise->addResult(QApplicationPermission::Denied); - promise->finish(); - return future; -} - -QFuture<QApplicationPermission::PermissionResult> -QCoreApplicationPrivate::checkPermission(const QString &permission) -{ - QPromise<QApplicationPermission::PermissionResult> promise; - QFuture<QApplicationPermission::PermissionResult> future = promise.future(); - promise.start(); - - if (permission.size() > 0) { - auto res = QJniObject::callStaticMethod<jint>(qtNativeClassName, - "checkSelfPermission", - "(Ljava/lang/String;)I", - QJniObject::fromString(permission).object()); - promise.addResult(resultFromAndroid(res)); - } else { - promise.addResult(QApplicationPermission::Denied); - } - - promise.finish(); - return future; -} - -QFuture<QApplicationPermission::PermissionResult> -QCoreApplicationPrivate::checkPermission(QApplicationPermission::PermissionType permission) -{ - const auto nativePermissions = nativeStringsFromPermission(permission); - - if (nativePermissions.size() > 0) - return checkPermission(nativePermissions.first()); - - QPromise<QApplicationPermission::PermissionResult> promise; - QFuture<QApplicationPermission::PermissionResult> future = promise.future(); - promise.start(); - promise.addResult(QApplicationPermission::Denied); - promise.finish(); - return future; -} - -bool QtAndroidPrivate::registerPermissionNatives() -{ - if (QtAndroidPrivate::androidSdkVersion() < 23) - return true; - - JNINativeMethod methods[] = { - {"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", - reinterpret_cast<void *>(sendRequestPermissionsResult) - }}; - - QJniEnvironment env; - return env.registerNativeMethods(qtNativeClassName, methods, 1); -} - -QT_END_NAMESPACE diff --git a/src/corelib/platform/android/qandroidextras.cpp b/src/corelib/platform/android/qandroidextras.cpp index 6d79e6c1e9..e43800e27c 100644 --- a/src/corelib/platform/android/qandroidextras.cpp +++ b/src/corelib/platform/android/qandroidextras.cpp @@ -47,6 +47,10 @@ #include <QtCore/qtimer.h> #include <QtCore/qset.h> +#if QT_CONFIG(future) +#include <QtCore/qpromise.h> +#endif + QT_BEGIN_NAMESPACE class QAndroidParcelPrivate @@ -1031,4 +1035,252 @@ void QAndroidActivityCallbackResultReceiver::registerCallback( callbackMap.insert(receiverRequestCode, callbackFunc); } +// Permissions API + +static const char qtNativeClassName[] = "org/qtproject/qt/android/QtNative"; + +QtAndroidPrivate::PermissionResult resultFromAndroid(jint value) +{ + return value == 0 ? QtAndroidPrivate::Authorized : QtAndroidPrivate::Denied; +} + +using PendingPermissionRequestsHash + = QHash<int, QSharedPointer<QPromise<QtAndroidPrivate::PermissionResult>>>; +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); +} + +static QStringList nativeStringsFromPermission(QtAndroidPrivate::PermissionType permission) +{ + static const auto precisePerm = QStringLiteral("android.permission.ACCESS_FINE_LOCATION"); + static const auto coarsePerm = QStringLiteral("android.permission.ACCESS_COARSE_LOCATION"); + static const auto backgroundPerm = + QStringLiteral("android.permission.ACCESS_BACKGROUND_LOCATION"); + + switch (permission) { + case QtAndroidPrivate::Location: + return {coarsePerm}; + case QtAndroidPrivate::PreciseLocation: + return {precisePerm}; + case QtAndroidPrivate::BackgroundLocation: + // Keep the background permission first to be able to use .first() + // in checkPermission because it takes single permission + if (QtAndroidPrivate::androidSdkVersion() >= 29) + return {backgroundPerm, coarsePerm}; + return {coarsePerm}; + case QtAndroidPrivate::PreciseBackgroundLocation: + // Keep the background permission first to be able to use .first() + // in checkPermission because it takes single permission + if (QtAndroidPrivate::androidSdkVersion() >= 29) + return {backgroundPerm, precisePerm}; + return {precisePerm}; + case QtAndroidPrivate::Camera: + return {QStringLiteral("android.permission.CAMERA")}; + case QtAndroidPrivate::Microphone: + return {QStringLiteral("android.permission.RECORD_AUDIO")}; + case QtAndroidPrivate::Bluetooth: + return { QStringLiteral("android.permission.BLUETOOTH") }; + case QtAndroidPrivate::BodySensors: + return {QStringLiteral("android.permission.BODY_SENSORS")}; + case QtAndroidPrivate::PhysicalActivity: + return {QStringLiteral("android.permission.ACTIVITY_RECOGNITION")}; + case QtAndroidPrivate::Contacts: + return {QStringLiteral("android.permission.READ_CONTACTS"), + QStringLiteral("android.permission.WRITE_CONTACTS")}; + case QtAndroidPrivate::Storage: + return {QStringLiteral("android.permission.READ_EXTERNAL_STORAGE"), + QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE")}; + case QtAndroidPrivate::Calendar: + return {QStringLiteral("android.permission.READ_CALENDAR"), + QStringLiteral("android.permission.WRITE_CALENDAR")}; + } + + return {}; +} + +/*! + \internal + + This function is called when the result of the permission request is available. + Once a permission is requested, the result is braodcast by the OS and listened + to by QtActivity which passes it to C++ through a native JNI method call. + */ +static void sendRequestPermissionsResult(JNIEnv *env, jobject *obj, jint requestCode, + jobjectArray permissions, jintArray grantResults) +{ + Q_UNUSED(obj); + + QMutexLocker locker(&g_pendingPermissionRequestsMutex); + auto it = g_pendingPermissionRequests->constFind(requestCode); + if (it == g_pendingPermissionRequests->constEnd()) { + qWarning() << "Found no valid pending permission request for request code" << requestCode; + return; + } + + auto request = *it; + g_pendingPermissionRequests->erase(it); + locker.unlock(); + + 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) { + QtAndroidPrivate::PermissionResult result = resultFromAndroid(results[i]); + request->addResult(result, i); + } + + request->finish(); +} + +QFuture<QtAndroidPrivate::PermissionResult> +requestPermissionsInternal(const QStringList &permissions) +{ + QSharedPointer<QPromise<QtAndroidPrivate::PermissionResult>> promise; + promise.reset(new QPromise<QtAndroidPrivate::PermissionResult>()); + QFuture<QtAndroidPrivate::PermissionResult> future = promise->future(); + promise->start(); + + // No mechanism to request permission for SDK version below 23, because + // permissions defined in the manifest are granted at install time. + if (QtAndroidPrivate::androidSdkVersion() < 23) { + for (int i = 0; i < permissions.size(); ++i) + promise->addResult(QtAndroidPrivate::checkPermission(permissions.at(i)).result(), i); + promise->finish(); + return future; + } + + const int requestCode = nextRequestCode(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); + g_pendingPermissionRequests->insert(requestCode, promise); + + QNativeInterface::QAndroidApplication::runOnAndroidMainThread([permissions, requestCode] { + QJniEnvironment env; + jclass clazz = env.findClass("java/lang/String"); + auto array = env->NewObjectArray(permissions.size(), clazz, nullptr); + int index = 0; + + for (auto &perm : permissions) + env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object()); + + QJniObject(QtAndroidPrivate::activity()).callMethod<void>("requestPermissions", + "([Ljava/lang/String;I)V", + array, + requestCode); + env->DeleteLocalRef(array); + }); + + return future; +} + +QFuture<QtAndroidPrivate::PermissionResult> +QtAndroidPrivate::requestPermission(const QString &permission) +{ + // avoid the uneccessary call and response to an empty permission string + if (permission.size() > 0) + return requestPermissionsInternal({permission}); + + QPromise<QtAndroidPrivate::PermissionResult> promise; + QFuture<QtAndroidPrivate::PermissionResult> future = promise.future(); + promise.start(); + promise.addResult(QtAndroidPrivate::Denied); + promise.finish(); + return future; +} + +static bool isBackgroundLocationApi29(QtAndroidPrivate::PermissionType permission) +{ + return QNativeInterface::QAndroidApplication::sdkVersion() >= 29 + && (permission == QtAndroidPrivate::BackgroundLocation + || permission == QtAndroidPrivate::PreciseBackgroundLocation); +} + +QFuture<QtAndroidPrivate::PermissionResult> +QtAndroidPrivate::requestPermission(QtAndroidPrivate::PermissionType permission) +{ + QSharedPointer<QPromise<QtAndroidPrivate::PermissionResult>> promise; + promise.reset(new QPromise<QtAndroidPrivate::PermissionResult>()); + QFuture<QtAndroidPrivate::PermissionResult> future = promise->future(); + promise->start(); + const auto nativePermissions = nativeStringsFromPermission(permission); + + if (nativePermissions.size() > 0) { + requestPermissionsInternal(nativePermissions).then( + [promise, permission](QFuture<QtAndroidPrivate::PermissionResult> future) { + auto AuthorizedCount = future.results().count(QtAndroidPrivate::Authorized); + if (AuthorizedCount > 0) { + if (isBackgroundLocationApi29(permission)) + promise->addResult(future.resultAt(0), 0); + else + promise->addResult(QtAndroidPrivate::Authorized, 0); + } else { + promise->addResult(QtAndroidPrivate::Denied, 0); + } + promise->finish(); + }); + + return future; + } + + promise->addResult(QtAndroidPrivate::Denied); + promise->finish(); + return future; +} + +QFuture<QtAndroidPrivate::PermissionResult> +QtAndroidPrivate::checkPermission(const QString &permission) +{ + QPromise<QtAndroidPrivate::PermissionResult> promise; + QFuture<QtAndroidPrivate::PermissionResult> future = promise.future(); + promise.start(); + + if (permission.size() > 0) { + auto res = QJniObject::callStaticMethod<jint>(qtNativeClassName, + "checkSelfPermission", + "(Ljava/lang/String;)I", + QJniObject::fromString(permission).object()); + promise.addResult(resultFromAndroid(res)); + } else { + promise.addResult(QtAndroidPrivate::Denied); + } + + promise.finish(); + return future; +} + +QFuture<QtAndroidPrivate::PermissionResult> +QtAndroidPrivate::checkPermission(QtAndroidPrivate::PermissionType permission) +{ + const auto nativePermissions = nativeStringsFromPermission(permission); + + if (nativePermissions.size() > 0) + return checkPermission(nativePermissions.first()); + + QPromise<QtAndroidPrivate::PermissionResult> promise; + QFuture<QtAndroidPrivate::PermissionResult> future = promise.future(); + promise.start(); + promise.addResult(QtAndroidPrivate::Denied); + promise.finish(); + return future; +} + +bool QtAndroidPrivate::registerPermissionNatives() +{ + if (QtAndroidPrivate::androidSdkVersion() < 23) + return true; + + JNINativeMethod methods[] = { + {"sendRequestPermissionsResult", "(I[Ljava/lang/String;[I)V", + reinterpret_cast<void *>(sendRequestPermissionsResult) + }}; + + QJniEnvironment env; + return env.registerNativeMethods(qtNativeClassName, methods, 1); +} + QT_END_NAMESPACE diff --git a/src/corelib/platform/android/qandroidextras_p.h b/src/corelib/platform/android/qandroidextras_p.h index 464c7f8aea..587c8661d6 100644 --- a/src/corelib/platform/android/qandroidextras_p.h +++ b/src/corelib/platform/android/qandroidextras_p.h @@ -60,6 +60,10 @@ #include <QtCore/qcoreapplication.h> #include <QtCore/qmap.h> +#if QT_CONFIG(future) +#include <QtCore/qfuture.h> +#endif + QT_BEGIN_NAMESPACE class QAndroidParcel; @@ -255,6 +259,42 @@ namespace QtAndroidPrivate Q_CORE_EXPORT bool bindService(const QAndroidIntent &serviceIntent, const QAndroidServiceConnection &serviceConnection, BindFlags flags = BindFlag::None); + +#if QT_CONFIG(future) + enum PermissionType { + Camera, + Microphone, + Bluetooth, + Location, + PreciseLocation, + BackgroundLocation, + PreciseBackgroundLocation, + BodySensors, + PhysicalActivity, + Contacts, + Storage, + // TODO: remove after usages in other modules are renamed. + WriteStorage, + Calendar + }; + + enum PermissionResult { + Undetermined, + Authorized, + Denied + }; + + Q_CORE_EXPORT QFuture<QtAndroidPrivate::PermissionResult> + requestPermission(QtAndroidPrivate::PermissionType permission); + Q_CORE_EXPORT QFuture<QtAndroidPrivate::PermissionResult> + requestPermission(const QString &permission); + + Q_CORE_EXPORT QFuture<QtAndroidPrivate::PermissionResult> + checkPermission(QtAndroidPrivate::PermissionType permission); + Q_CORE_EXPORT QFuture<QtAndroidPrivate::PermissionResult> + checkPermission(const QString &permission); +#endif + } QT_END_NAMESPACE |