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