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
qohoswantutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 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/qohoslogger_p.h>
6#include <QtCore/qjsonarray.h>
7#include <QtCore/qmimedatabase.h>
8#include <array>
9#include <utility>
10
11QT_BEGIN_NAMESPACE
12
13namespace QtOhosAppKit::Private {
14
15namespace {
16
17namespace WantProps {
18 constexpr auto deviceId = "deviceId";
19 constexpr auto bundleName = "bundleName";
20 constexpr auto moduleName = "moduleName";
21 constexpr auto abilityName = "abilityName";
22 constexpr auto uri = "uri";
23 constexpr auto type = "type";
24 constexpr auto action = "action";
25 constexpr auto entities = "entities";
26 constexpr auto flags = "flags";
27 constexpr auto parameters = "parameters";
28 constexpr auto fds = "fds";
29}
30
31static const std::array<std::pair<WantFlag, int>, 3> qtToOhosFlagsMappings {
32 std::make_pair(WantFlag::AuthReadUriPermission, 0x00000001),
33 std::make_pair(WantFlag::AuthWriteUriPermission, 0x00000002),
34 std::make_pair(WantFlag::InstallOnDemand, 0x00000800),
35};
36
37int convertToOhosFlags(const WantFlags &flags)
38{
39 int result = 0;
40 for (const auto &flagsMapping : qtToOhosFlagsMappings) {
41 if (flags.testFlag(flagsMapping.first))
42 result |= flagsMapping.second;
43 }
44
45 return result;
46}
47
48WantFlags convertFromOhosFlags(int intFlags)
49{
50 WantFlags flags = {};
51 for (const auto &flagsMapping : qtToOhosFlagsMappings) {
52 if ((intFlags & flagsMapping.second) != 0)
53 flags |= flagsMapping.first;
54 }
55
56 return flags;
57}
58
59QString getWantOptionalStringProp(const QJsonObject &jsonWant, const char *propName)
60{
61 auto propIter = jsonWant.find(QLatin1String(propName));
62 return propIter != jsonWant.end() && propIter->isString()
63 ? propIter->toString()
64 : QString();
65}
66
67WantInfo::LaunchReason mapLaunchReasonFromQpaFunctions(
68 detail::WantInfoPriv::LaunchReason reason)
69{
70 using WantInfoPriv = detail::WantInfoPriv;
71
72 switch (reason) {
73 case WantInfoPriv::LaunchReason::UNKNOWN:
74 return WantInfo::LaunchReason::Unknown;
75 case WantInfoPriv::LaunchReason::START_ABILITY:
76 return WantInfo::LaunchReason::StartAbility;
77 case WantInfoPriv::LaunchReason::CONTINUATION:
78 return WantInfo::LaunchReason::Continuation;
79 case WantInfoPriv::LaunchReason::PREPARE_CONTINUATION:
80 return WantInfo::LaunchReason::PrepareContinuation;
81 case WantInfoPriv::LaunchReason::PRELOAD:
82 return WantInfo::LaunchReason::Preload;
83 }
84
85 return WantInfo::LaunchReason::Unknown;
86}
87
88class QOhosWantInfoImpl : public WantInfo
89{
90public:
91 QOhosWantInfoImpl(QSharedPointer<detail::WantInfoPriv> want);
92
93 Want want() const override;
94
95 std::optional<QList<std::shared_ptr<ShareKit::SharedRecord>>> tryGetSharedRecordsFromShareKit() const override;
96
97 std::optional<ContactInfo> tryGetContactInfo() const override;
98
99 LaunchReason launchReason() const override;
100
101 QSharedPointer<detail::WantInfoPriv> qpaWantInfo() const;
102
103private:
104 QSharedPointer<detail::WantInfoPriv> m_qpaWantInfo;
105};
106
107QOhosWantInfoImpl::QOhosWantInfoImpl(QSharedPointer<detail::WantInfoPriv> want)
108 : WantInfo()
109 , m_qpaWantInfo(want)
110{
111}
112
113Want QOhosWantInfoImpl::want() const
114{
115 return convertWantFromJsonObject(m_qpaWantInfo->jsonObject());
116}
117
118std::optional<QList<std::shared_ptr<ShareKit::SharedRecord>>> QOhosWantInfoImpl::tryGetSharedRecordsFromShareKit() const
119{
120 auto records = qpaWantInfo()->tryGetSharedDataRecords();
121 if (!records.has_value())
122 return {};
123
124 QList<std::shared_ptr<ShareKit::SharedRecord>> result;
125 for (auto &record : records.value()) {
126 std::shared_ptr<ShareKit::SharedRecord> extrasRecord;
127 if (record.content.has_value()) {
128 extrasRecord = ShareKit::createContentRecord(
129 QMimeDatabase().mimeTypeForName(record.mimeType), record.content.value());
130 } else if (record.filePath.has_value()) {
131 extrasRecord = ShareKit::createFileRecord(QFileInfo(record.filePath.value()));
132 } else {
133 qOhosPrintfWarning("%s: record has no content nor file path, skip it", Q_FUNC_INFO);
134 continue;
135 }
136
137 if (record.title.has_value())
138 extrasRecord->setTitle(record.title.value());
139 if (record.label.has_value())
140 extrasRecord->setLabel(record.label.value());
141 if (record.description.has_value())
142 extrasRecord->setDescription(record.description.value());
143 if (record.thumbnail.has_value())
144 extrasRecord->setThumbnail(record.thumbnail.value());
145 if (record.thumbnailFilePath.has_value())
146 extrasRecord->setThumbnailFilePath(record.thumbnailFilePath.value());
147 if (record.extraData.has_value())
148 extrasRecord->setExtraData(record.extraData.value());
149
150 result.push_back(extrasRecord);
151 }
152
153 return result;
154}
155
156std::optional<WantInfo::ContactInfo> QOhosWantInfoImpl::tryGetContactInfo() const
157{
158 auto optContactInfo = qpaWantInfo()->tryGetContactInfo();
159 if (!optContactInfo.has_value())
160 return {};
161
162 return ContactInfo{
163 .contactType = optContactInfo.value().contactType,
164 .contactId = optContactInfo.value().contactId,
165 };
166}
167
168WantInfo::LaunchReason QOhosWantInfoImpl::launchReason() const
169{
170 return mapLaunchReasonFromQpaFunctions(m_qpaWantInfo->launchReason());
171}
172
173QSharedPointer<detail::WantInfoPriv> QOhosWantInfoImpl::qpaWantInfo() const
174{
175 return m_qpaWantInfo;
176}
177
178}
179
181{
182 QJsonObject jsonWant;
183
184 if (!want.deviceId.isEmpty())
185 jsonWant.insert(QLatin1String(WantProps::deviceId), want.deviceId);
186 if (!want.bundleName.isEmpty())
187 jsonWant.insert(QLatin1String(WantProps::bundleName), want.bundleName);
188 if (!want.moduleName.isEmpty())
189 jsonWant.insert(QLatin1String(WantProps::moduleName), want.moduleName);
190 if (!want.abilityName.isEmpty())
191 jsonWant.insert(QLatin1String(WantProps::abilityName), want.abilityName);
192 if (!want.uri.isEmpty())
193 jsonWant.insert(QLatin1String(WantProps::uri), want.uri);
194 if (!want.type.isEmpty())
195 jsonWant.insert(QLatin1String(WantProps::type), want.type);
196 if (!want.action.isEmpty())
197 jsonWant.insert(QLatin1String(WantProps::action), want.action);
198 jsonWant.insert(QLatin1String(WantProps::flags), convertToOhosFlags(want.flags));
199 jsonWant.insert(QLatin1String(WantProps::entities), QJsonArray::fromStringList(want.entities));
200
201 QJsonObject parametersObject = want.parameters;
202 for (auto it = want.fds.cbegin(); it != want.fds.cend(); ++it) {
203 QJsonObject fdEntry = {
204 {QStringLiteral("type"), QStringLiteral("FD")},
205 {QStringLiteral("value"), it.value()},
206 };
207 parametersObject.insert(it.key(), fdEntry);
208 }
209 jsonWant.insert(QLatin1String(WantProps::parameters), parametersObject);
210
211 return jsonWant;
212}
213
214Want convertWantFromJsonObject(const QJsonObject &jsonWant)
215{
216 auto flagsIter = jsonWant.find(QLatin1String(WantProps::flags));
217 auto flagsInt = flagsIter != jsonWant.end() && flagsIter->isDouble()
218 ? flagsIter->toInt()
219 : 0;
220
221 auto entitiesIter = jsonWant.find(QLatin1String(WantProps::entities));
222 auto entitiesArray = entitiesIter != jsonWant.end() && entitiesIter->isArray()
223 ? entitiesIter->toArray()
224 : QJsonArray();
225
226 QStringList entities;
227 for (const auto &entityValue : entitiesArray) {
228 if (entityValue.isString())
229 entities.append(entityValue.toString());
230 }
231
232 auto parametersIter = jsonWant.find(QLatin1String(WantProps::parameters));
233 auto parametersObject = parametersIter != jsonWant.end() && parametersIter->isObject()
234 ? parametersIter->toObject()
235 : QJsonObject();
236
237 auto fdsIter = jsonWant.find(QLatin1String(WantProps::fds));
238 auto fdsObject = fdsIter != jsonWant.end() && fdsIter->isObject()
239 ? fdsIter->toObject()
240 : QJsonObject();
241 QHash<QString, int> fds;
242 for (auto it = fdsObject.constBegin(); it != fdsObject.constEnd(); ++it) {
243 if (it.value().isDouble())
244 fds.insert(it.key(), it.value().toInt());
245 }
246
247 Want want = {
248 .deviceId = getWantOptionalStringProp(jsonWant, WantProps::deviceId),
249 .bundleName = getWantOptionalStringProp(jsonWant, WantProps::bundleName),
250 .moduleName = getWantOptionalStringProp(jsonWant, WantProps::moduleName),
251 .abilityName = getWantOptionalStringProp(jsonWant, WantProps::abilityName),
252 .uri = getWantOptionalStringProp(jsonWant, WantProps::uri),
253 .type = getWantOptionalStringProp(jsonWant, WantProps::type),
254 .action = getWantOptionalStringProp(jsonWant, WantProps::action),
255 .entities = entities,
256 .flags = convertFromOhosFlags(flagsInt),
257 .parameters = parametersObject,
258 .fds = fds,
259 };
260
261 return want;
262}
263
265 QSharedPointer<detail::WantInfoPriv> wantInfo)
266{
267 return std::make_shared<QOhosWantInfoImpl>(wantInfo);
268}
269
271 std::shared_ptr<WantInfo> wantInfo)
272{
273 return std::static_pointer_cast<QOhosWantInfoImpl>(wantInfo)->qpaWantInfo();
274}
275
276}
277
278QT_END_NAMESPACE
Want convertWantFromJsonObject(const QJsonObject &jsonWant)
QSharedPointer< detail::WantInfoPriv > convertToQpaWantInfo(std::shared_ptr< WantInfo > wantInfo)
std::shared_ptr< WantInfo > convertToOhosAppKitWantInfo(QSharedPointer< detail::WantInfoPriv > wantInfo)
QJsonObject convertWantToJsonObject(const Want &want)