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
qohosapppermissions.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 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
5#include <QtCore/private/qohoscommon_p.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include <optional>
8#include <qohosplugincore.h>
9
11
13
14namespace {
15
16void tryGetBundleAccessTokenIdWithConsumer(
17 QtOhos::JsState &jsState, QOhosConsumer<QtOhos::JsState &, std::optional<int>> resultConsumer)
18{
19 auto bundleFlags = jsState.eval<QNapi::Number>(
20 "@ohos.bundle.bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION");
21
22 jsState.evalToPromiseOrRejectOnThrow(
23 "@ohos.bundle.bundleManager.getBundleInfoForSelf(*)", {bundleFlags})
24 .withContext(std::move(resultConsumer))
25 .onThenWithContext([](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
26 QNapi::Object bundleInfo = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
27 resultConsumer(
28 cbInfo.jsState(),
29 std::optional<int>(bundleInfo.eval<QNapi::Number>("appInfo.accessTokenId")));
30 })
31 .onCatchWithContext([](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
32 QtOhos::logJsCallbackError(cbInfo, "Got error from getBundleInfoForSelf()");
33 resultConsumer(cbInfo.jsState(), {});
34 });
35}
36
37void checkAppPermissionStatusGrantedWithConsumer(
38 QtOhos::JsState &jsState, int bundleAccessToken, const std::string &permissionName,
39 QOhosConsumer<QtOhos::JsState &, bool> resultConsumer)
40{
41 jsState.evalToPromiseOrRejectOnThrow(
42 "@ohos.abilityAccessCtrl.createAtManager().checkAccessToken(*)",
43 {bundleAccessToken, permissionName})
44 .withContext(std::move(resultConsumer))
45 .onThenWithContext([](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
46 auto status = cbInfo.getFirstArg<QNapi::Number>(Q_FUNC_INFO);
47 auto permissionGrantedStatus = cbInfo.jsState().eval<QNapi::Number>(
48 "@ohos.abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED");
49 resultConsumer(cbInfo.jsState(), status == permissionGrantedStatus);
50 })
51 .onCatchWithContext([](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
52 QtOhos::logJsCallbackError(cbInfo, "Got error from checkAccessToken()");
53 resultConsumer(cbInfo.jsState(), false);
54 });
55}
56
57}
58
60 QtOhos::JsState &jsState, const std::string &permissionName,
61 QOhosConsumer<QtOhos::JsState &, bool> resultConsumer)
62{
63 tryGetBundleAccessTokenIdWithConsumer(
64 jsState,
65 [permissionName, resultConsumer = std::move(resultConsumer)](
66 QtOhos::JsState &jsState, std::optional<int> bundleAccessTokenId) mutable {
67 if (bundleAccessTokenId.has_value()) {
68 checkAppPermissionStatusGrantedWithConsumer(
69 jsState, bundleAccessTokenId.value(), permissionName,
70 std::move(resultConsumer));
71 } else {
72 qOhosPrintfError(
73 "Cannot check permission: '%s': cannot get bundle access token id.",
74 permissionName.c_str());
75 resultConsumer(jsState, false);
76 }
77 });
78}
79
81 QtOhos::JsState &jsState, const std::string &permissionName,
82 QOhosConsumer<QtOhos::JsState &, bool> resultConsumer)
83{
84 auto optQAbility = jsState.defaultQAbility();
85 if (!optQAbility) {
86 qOhosPrintfError(
87 "Cannot request permission: '%s': no default QAbility.", permissionName.c_str());
88 resultConsumer(jsState, false);
89 return;
90 }
91
92 requestAppPermissionFromUser(
93 jsState, optQAbility.value(), permissionName, std::move(resultConsumer));
94}
95
97 QtOhos::JsState &jsState, QNapi::Object qAbility, const std::string &permissionName,
98 QOhosConsumer<QtOhos::JsState &, bool> resultConsumer)
99{
100 requestAppPermissionsFromUserWithResult(
101 jsState, qAbility, {permissionName},
102 [resultConsumer = std::move(resultConsumer)](QtOhos::JsState &jsState, std::vector<QOhosAppPermissions::AppPermissionResult> result) {
103 resultConsumer(jsState, result.size() == 1 && result.front().permissionGranted);
104 });
105}
106
108 QtOhos::JsState &jsState, const std::vector<std::string> &permissionNames,
109 QOhosConsumer<QtOhos::JsState &, std::vector<AppPermissionResult>> resultConsumer)
110{
111 auto optQAbility = jsState.defaultQAbility();
112 if (!optQAbility) {
113 qOhosPrintfError("Cannot request permissions from user: no default QAbility.");
114 resultConsumer(
115 jsState,
116 std::vector<AppPermissionResult>(
117 permissionNames.size(),
118 AppPermissionResult {
119 .permissionGranted = false,
120 .dialogShown = false
121 }));
122 return;
123 }
124
125 requestAppPermissionsFromUserWithResult(
126 jsState, optQAbility.value(), permissionNames, std::move(resultConsumer));
127}
128
130 QtOhos::JsState &jsState, QNapi::Object qAbility,
131 const std::vector<std::string> &permissionNames,
132 QOhosConsumer<QtOhos::JsState &, std::vector<AppPermissionResult>> resultConsumer)
133{
134 jsState.evalToPromiseOrRejectOnThrow(
135 "@ohos.abilityAccessCtrl.createAtManager().requestPermissionsFromUser(*)",
136 {
137 qAbility.eval<QNapi::Object>("context"),
138 QNapi::makeArray(
139 jsState.env(),
140 std::vector<QNapi::ValueWrapper>(permissionNames.begin(), permissionNames.end()))
141 })
142 .withContext(std::move(resultConsumer))
143 .onThenWithContext(
144 [permissionNames](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
145 QNapi::Object resultObj = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
146
147 auto resultPermissionsNames =
148 QNapi::getArrayElements<std::vector<std::string>, QNapi::String>(
149 resultObj.get<QNapi::Array>("permissions"));
150 auto resultAuthResults =
151 QNapi::getArrayElements<std::vector<int>, QNapi::Number>(
152 resultObj.get<QNapi::Array>("authResults"));
153
154 auto dialogShownResultsOrEmpty = QNapi::getOptionalPropOrEmpty<QNapi::Array>(resultObj, "dialogShownResults");
155 auto dialogShownResultsVector =
156 !dialogShownResultsOrEmpty.IsEmpty()
157 ? QNapi::getArrayElements<std::vector<bool>, QNapi::Boolean>(dialogShownResultsOrEmpty)
158 : std::vector<bool>();
159
160 int permissionGrantedStatus = cbInfo.jsState().eval<QNapi::Number>(
161 "@ohos.abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED");
162
163 const std::size_t totalPermissions = permissionNames.size();
164 std::vector<AppPermissionResult> appPermissionResults(
165 totalPermissions,
166 AppPermissionResult {
167 .permissionGranted = false,
168 .dialogShown = false
169 });
170 if (resultPermissionsNames.size() == totalPermissions && resultAuthResults.size() == totalPermissions
171 && dialogShownResultsVector.size() == totalPermissions) {
172 for (const auto &permissionName : permissionNames) {
173 const auto it = std::find(resultPermissionsNames.begin(), resultPermissionsNames.end(), permissionName);
174 if (it != resultPermissionsNames.end()) {
175 const int index = std::distance(resultPermissionsNames.begin(), it);
176 appPermissionResults[index].permissionGranted = (resultAuthResults[index] == permissionGrantedStatus);
177 appPermissionResults[index].dialogShown = dialogShownResultsVector[index];
178 }
179 }
180 }
181 resultConsumer(cbInfo.jsState(), appPermissionResults);
182 })
183 .onCatchWithContext(
184 [permissionNames](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
185 QtOhos::logJsCallbackError(cbInfo, "Got error from requestPermissionsFromUser()");
186 const std::size_t totalPermissions = permissionNames.size();
187 std::vector<AppPermissionResult> appPermissionResults(
188 totalPermissions,
189 AppPermissionResult {
190 .permissionGranted = false,
191 .dialogShown = false
192 });
193 resultConsumer(cbInfo.jsState(), appPermissionResults);
194 });
195}
196
198 QtOhos::JsState &jsState, const std::vector<std::string> &permissionNames,
199 QOhosConsumer<QtOhos::JsState &, std::vector<bool>> resultConsumer)
200{
201 auto optQAbility = jsState.defaultQAbility();
202 if (!optQAbility) {
203 qOhosPrintfError("Cannot request permissions on setting: no default QAbility.");
204 resultConsumer(jsState, std::vector<bool>(permissionNames.size(), false));
205 return;
206 }
207
208 requestAppPermissionsOnSetting(
209 jsState, optQAbility.value(), permissionNames, std::move(resultConsumer));
210}
211
213 QtOhos::JsState &jsState, QNapi::Object qAbility,
214 const std::vector<std::string> &permissionNames,
215 QOhosConsumer<QtOhos::JsState &, std::vector<bool>> resultConsumer)
216{
217 jsState.evalToPromiseOrRejectOnThrow(
218 "@ohos.abilityAccessCtrl.createAtManager().requestPermissionOnSetting(*)",
219 {
220 qAbility.eval<QNapi::Object>("context"),
221 QNapi::makeArray(
222 jsState.env(),
223 std::vector<QNapi::ValueWrapper>(permissionNames.begin(), permissionNames.end()))
224 })
225 .withContext(std::move(resultConsumer))
226 .onThenWithContext(
227 [permissionNames](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
228 QNapi::Array resultArray = cbInfo.getFirstArg<QNapi::Array>(Q_FUNC_INFO);
229
230 auto resultAuthResults = QNapi::getArrayElements<std::vector<int>, QNapi::Number>(resultArray);
231
232 int permissionGrantedStatus = cbInfo.jsState().eval<QNapi::Number>(
233 "@ohos.abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED");
234
235 const std::size_t totalPermissions = permissionNames.size();
236 std::vector<bool> settingsPermissionResults(totalPermissions, false);
237 if (resultAuthResults.size() == totalPermissions) {
238 for (std::size_t permIndex = 0; permIndex < totalPermissions; permIndex++)
239 settingsPermissionResults[permIndex] = (resultAuthResults[permIndex] == permissionGrantedStatus);
240 }
241
242 resultConsumer(cbInfo.jsState(), settingsPermissionResults);
243 })
244 .onCatchWithContext(
245 [permissionNames](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
246 QtOhos::logJsCallbackError(cbInfo, "Got error from requestPermissionOnSetting()");
247 std::vector<bool> settingsPermissionResults(permissionNames.size(), false);
248 resultConsumer(cbInfo.jsState(), settingsPermissionResults);
249 });
250}
251
252}
253
254QT_END_NAMESPACE
JsState & jsState() const
void requestAppPermissionsFromUserWithResult(QtOhos::JsState &jsState, const std::vector< std::string > &permissionNames, QOhosConsumer< QtOhos::JsState &, std::vector< AppPermissionResult > > resultConsumer)
void requestAppPermissionFromUser(QtOhos::JsState &jsState, QNapi::Object qAbility, const std::string &permissionName, QOhosConsumer< QtOhos::JsState &, bool > resultConsumer)
void requestAppPermissionsOnSetting(QtOhos::JsState &jsState, const std::vector< std::string > &permissionNames, QOhosConsumer< QtOhos::JsState &, std::vector< bool > > resultConsumer)
void checkAppPermissionGrantedWithConsumer(QtOhos::JsState &jsState, const std::string &permissionName, QOhosConsumer< QtOhos::JsState &, bool > resultConsumer)
void requestAppPermissionsOnSetting(QtOhos::JsState &jsState, QNapi::Object qAbility, const std::vector< std::string > &permissionNames, QOhosConsumer< QtOhos::JsState &, std::vector< bool > > resultConsumer)
void requestAppPermissionsFromUserWithResult(QtOhos::JsState &jsState, QNapi::Object qAbility, const std::vector< std::string > &permissionNames, QOhosConsumer< QtOhos::JsState &, std::vector< AppPermissionResult > > resultConsumer)
void requestAppPermissionFromUser(QtOhos::JsState &jsState, const std::string &permissionName, QOhosConsumer< QtOhos::JsState &, bool > resultConsumer)
Combined button and popup list for selecting options.