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
qpermissions_plugin.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 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
4#include "qpermissions.h"
6
7#include <QtCore/private/qfactoryloader_p.h>
8#include <QtCore/private/qcoreapplication_p.h>
9#include <QtCore/qcborarray.h>
10
12
13using namespace Qt::StringLiterals;
14
15namespace {
16
17Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, pluginLoader,
18 (QPermissionPluginInterface_iid, QLatin1String("/permissions"), Qt::CaseInsensitive))
19
20QPermissionPlugin *permissionPlugin(const QPermission &permission)
21{
22 static QMutex mutex;
23 QMutexLocker locker(&mutex);
24
25 const char *permissionType = permission.type().name();
26 qCDebug(lcPermissions, "Looking for permission plugin for %s", permissionType);
27
28 if (Q_UNLIKELY(!pluginLoader)) {
29 qCWarning(lcPermissions, "Cannot check or request permissions during application shutdown");
30 return nullptr;
31 }
32
33 auto metaDataList = pluginLoader()->metaData();
34 for (int i = 0; i < metaDataList.size(); ++i) {
35 auto metaData = metaDataList.at(i).value(QtPluginMetaDataKeys::MetaData).toMap();
36 auto permissions = metaData.value("Permissions"_L1).toArray();
37 if (permissions.contains(QString::fromUtf8(permissionType))) {
38 auto className = metaDataList.at(i).value(QtPluginMetaDataKeys::ClassName).toString();
39 qCDebug(lcPermissions) << "Found matching plugin" << qUtf8Printable(className);
40 auto *plugin = static_cast<QPermissionPlugin*>(pluginLoader()->instance(i));
41 return plugin;
42 }
43 }
44
45 qCWarning(lcPermissions).nospace() << "Could not find permission plugin for "
46 << permission.type().name() <<
47#ifdef Q_OS_DARWIN
48 ". Please make sure you have included the required usage description in your Info.plist"
49#endif
50 ".";
51
52 return nullptr;
53}
54
55} // Unnamed namespace
56
57namespace QPermissions::Private
58{
59 static constexpr auto FallbackPermission =
60#ifdef Q_OS_DARWIN
61 // On Apple systems, we always have a plugin to get permissions
62 // with. If it is missing, we fail-closed because something is
63 // wrong and likely to fail anyway.
65#else
66 // On other systems, the plugin may be missing. In that case,
67 // we optimistically grant access.
69#endif
70
72 {
73 if (auto *plugin = permissionPlugin(permission))
74 return plugin->checkPermission(permission);
75 else
76 return FallbackPermission;
77 }
78
79 void requestPermission(const QPermission &permission, const QPermissions::Private::PermissionCallback &callback)
80 {
81 if (auto *plugin = permissionPlugin(permission))
82 plugin->requestPermission(permission, callback);
83 else
84 callback(FallbackPermission);
85 }
86}
87
88QT_END_NAMESPACE
\inmodule QtCore \inheaderfile QPermissions
void requestPermission(const QPermission &permission, const PermissionCallback &callback)
static constexpr auto FallbackPermission
Qt::PermissionStatus checkPermission(const QPermission &permission)
Combined button and popup list for selecting options.
#define QPermissionPluginInterface_iid