Simplify the application permission API

Remove read/write variants of the permission types to make the
API simpler and more versatile. If the user wishes to have more
control over the permission requests/checks, they can use more
platform-specific code.

Pick-to: 6.2
Task-number: QTBUG-94407
Change-Id: I2b72041aa3effaac7e7f7361237cf1146817b525
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Assam Boudjelthia 2021-06-30 14:48:10 +03:00
parent 1c547698ac
commit 1969a25cee
3 changed files with 66 additions and 66 deletions

View File

@ -51,25 +51,23 @@ enum PermissionType {
Camera,
Microphone,
Bluetooth,
CoarseLocation,
Location,
PreciseLocation,
CoarseBackgroundLocation,
BackgroundLocation,
PreciseBackgroundLocation,
BodySensors,
PhysicalActivity,
ReadContacts,
WriteContacts,
ReadStorage,
Contacts,
Storage,
// TODO: remove after usages in other modules are renamed.
WriteStorage,
ReadCalendar,
WriteCalendar
Calendar
};
enum PermissionResult {
Undetermined,
Authorized,
Denied,
Restricted,
Undetermined
Denied
};
} // QApplicationPermission

View File

@ -45,7 +45,7 @@
\value Microphone Access the microphone, receive the sound signal (e.g. to
analyze or record it). Maps to \c "android.permission.RECORD_AUDIO"
on Android.
\value CoarseLocation Access approximate location provider (wifi, cell tower).
\value Location Access approximate location provider (wifi, cell tower).
Maps to \c "android.permission.ACCESS_COARSE_LOCATION" on Android.
\value PreciseLocation Location Access accurate location provider (satellite).
Maps to \c "android.permission.ACCESS_FINE_LOCATION" on Android.
@ -53,27 +53,24 @@
the app is in the background. Maps to
\c "android.permission.ACCESS_BACKGROUND_LOCATION" on Android, and
implies \l PreciseLocation.
\value CoarseBackgroundLocation Access the approximate location services when
\value BackgroundLocation Access the approximate location services when
the app is in the background. Maps to
\c "android.permission.ACCESS_BACKGROUND_LOCATION" on Android, and
implies \l CoarseLocation.
implies \l Location.
\value BodySensors Access body sensors such as a heart rate sensor.
Maps to \c "android.permission.BODY_SENSORS" on Android.
\value PhysicalActivity Access to data about physical activity and body
movements. Maps to \c "android.permission.ACTIVITY_RECOGNITION"
on Android.
\value ReadContacts Read user contacts. Maps to
\c "android.permission.READ_CONTACTS" on Android.
\value WriteContacts Write user contacts. Maps to
\c "android.permission.WRITE_CONTACTS" on Android.
\value ReadStorage Access device storage with read permissions.
Maps to \c "android.permission.READ_EXTERNAL_STORAGE" on Android.
\value WriteStorage Access device storage with write permissions.
Maps to \c "android.permission.WRITE_EXTERNAL_STORAGE" on Android.
\value ReadCalendar Read the user's calendar.
Maps to \c "android.permission.READ_CALENDAR" on Android.
\value WriteCalendar Write to the user's calendar.
Maps to \c "android.permission.WRITE_CALENDAR" on Android.
\value Contacts Read and write user contacts. Maps to
\c "android.permission.READ_CONTACTS" and \c "android.permission.WRITE_CONTACTS"
on Android.
\value Storage Access device storage with read and write permissions.
Maps to \c "android.permission.READ_EXTERNAL_STORAGE" and
\c "android.permission.WRITE_EXTERNAL_STORAGE"on Android.
\value Calendar Read and write the user's calendar.
Maps to \c "android.permission.READ_CALENDAR" and
\c "android.permission.WRITE_CALENDAR" on Android.
\omitvalue Bluetooth

View File

@ -83,17 +83,19 @@ static QStringList nativeStringsFromPermission(QApplicationPermission::Permissio
QStringLiteral("android.permission.ACCESS_BACKGROUND_LOCATION");
switch (permission) {
case QApplicationPermission::CoarseLocation:
case QApplicationPermission::Location:
return {coarsePerm};
case QApplicationPermission::PreciseLocation:
return {precisePerm};
case QApplicationPermission::CoarseBackgroundLocation:
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};
@ -101,26 +103,24 @@ static QStringList nativeStringsFromPermission(QApplicationPermission::Permissio
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::ReadContacts:
return {QStringLiteral("android.permission.READ_CONTACTS")};
case QApplicationPermission::WriteContacts:
return {QStringLiteral("android.permission.WRITE_CONTACTS")};
case QApplicationPermission::ReadStorage:
return {QStringLiteral("android.permission.READ_EXTERNAL_STORAGE")};
case QApplicationPermission::WriteStorage:
return {QStringLiteral("android.permission.WRITE_EXTERNAL_STORAGE")};
case QApplicationPermission::ReadCalendar:
return {QStringLiteral("android.permission.READ_CALENDAR")};
case QApplicationPermission::WriteCalendar:
return {QStringLiteral("android.permission.WRITE_CALENDAR")};
default:
return {};
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 {};
}
/*!
@ -158,7 +158,8 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject *obj, jint request
request->finish();
}
QFuture<QApplicationPermission::PermissionResult> requestPermissionsInternal(const QStringList &permissions)
QFuture<QApplicationPermission::PermissionResult>
requestPermissionsInternal(const QStringList &permissions)
{
QSharedPointer<QPromise<QApplicationPermission::PermissionResult>> promise;
promise.reset(new QPromise<QApplicationPermission::PermissionResult>());
@ -216,43 +217,47 @@ QCoreApplicationPrivate::requestPermission(const QString &permission)
return future;
}
QFuture<QApplicationPermission::PermissionResult> groupRequestToSingleResult(const QStringList &permissions)
static bool isBackgroundLocationApi29(QApplicationPermission::PermissionType permission)
{
QSharedPointer<QPromise<QApplicationPermission::PermissionResult>> promise;
promise.reset(new QPromise<QApplicationPermission::PermissionResult>());
QFuture<QApplicationPermission::PermissionResult> future = promise->future();
promise->start();
requestPermissionsInternal(permissions).then(
[promise](QFuture<QApplicationPermission::PermissionResult> future) {
auto results = future.results();
if (results.count(QApplicationPermission::Authorized) == results.count())
promise->addResult(QApplicationPermission::Authorized, 0);
else
promise->addResult(QApplicationPermission::Denied, 0);
promise->finish();
});
return future;
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)
return groupRequestToSingleResult(nativePermissions);
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;
}
QPromise<QApplicationPermission::PermissionResult> promise;
QFuture<QApplicationPermission::PermissionResult> future = promise.future();
promise.start();
#ifndef QT_NO_EXCEPTIONS
promise.setException(std::make_exception_ptr(
promise->setException(std::make_exception_ptr(
std::runtime_error(invalidNativePermissionExcept)));
#else
promise.addResult(QApplicationPermission::Denied);
#endif
promise.finish();
promise->finish();
return future;
}