6#include <QtHarmonyExtras/private/qohosenums_p.h>
7#include <QtHarmonyExtras/private/qohosjsenv_p.h>
9#include <QtCore/qbytearray.h>
10#include <QtCore/qjsonobject.h>
11#include <QtCore/qlist.h>
12#include <QtCore/qstring.h>
13#include <QtCore/qvariant.h>
14#include <QtCore/private/qcore_ohos_p.h>
15#include <QtCore/private/qnapi_p.h>
16#include <QtCore/private/qohoscommon_p.h>
17#include <QtCore/private/qohoslogger_p.h>
26#include <database/udmf/udmf_meta.h>
27#include <database/udmf/utd.h>
39std::optional<T> getOptionalProperty(
const QNapi::Object &object,
const std::string &propName)
41 auto optPropValue = QNapi::getOptionalPropOrEmpty<T>(object, propName);
42 return !optPropValue.IsEmpty()
43 ?
std::make_optional(optPropValue)
47std::optional<
std::string> tryMapUtdTypeIdToMimeType(
const std::string &utdTypeId)
49 std::shared_ptr<::OH_Utd> utd(
50 ::OH_Utd_Create(utdTypeId.c_str()),
53 ::OH_Utd_Destroy(utd);
56 std::vector<std::string> mimeTypes;
58 unsigned int typesCount = 0;
59 const char **rawMimeTypes = ::OH_Utd_GetMimeTypes(utd.get(), &typesCount);
60 if (rawMimeTypes ==
nullptr && typesCount != 0) {
61 qOhosReportFatalErrorAndAbort(
62 "%s: got inconsistent result from OH_Utd_GetMimeTypes() call: array is null, size is %u",
63 Q_FUNC_INFO, typesCount);
65 if (rawMimeTypes !=
nullptr)
66 mimeTypes = std::vector<std::string>(rawMimeTypes, rawMimeTypes + typesCount);
69 return !mimeTypes.empty()
70 ?
std::make_optional(mimeTypes.front())
76 auto tryGetOptionalStringProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QString> {
77 auto optProp = getOptionalProperty<QNapi::String>(object, propName);
78 return optProp.has_value()
79 ? std::make_optional(QString::fromStdString(optProp.value()))
83 auto tryGetOptionalByteArrayProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QByteArray> {
84 auto optProp = getOptionalProperty<QNapi::TypedArrayOf<std::uint8_t>>(object, propName);
85 return optProp.has_value()
86 ? std::make_optional(QByteArray(
87 reinterpret_cast<
const char *>(optProp.value().Data()),
88 optProp.value().ByteLength()))
92 auto tryGetOptionalJsonObjectProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QJsonObject> {
93 auto optProp = getOptionalProperty<QNapi::Object>(object, propName);
94 return optProp.has_value()
95 ? std::make_optional(QOhosJsEnv::fromNapiValue<QJsonObject>(optProp.value()))
99 std::string utd = record.get<QNapi::String>(
"utd");
100 auto optMimeType = utd != UDMF_META_HYPERLINK
101 ? tryMapUtdTypeIdToMimeType(utd)
102 : std::optional<std::string>(
"text/uri-list");
103 if (!optMimeType.has_value()) {
105 "%s: can't map utd '%s' to mimetype, not mapping the record",
106 Q_FUNC_INFO, utd.c_str());
110 auto content = tryGetOptionalStringProp(record,
"content");
111 auto uri = tryGetOptionalStringProp(record,
"uri");
112 if (!content.has_value() && !uri.has_value()) {
114 "%s: cannot create Shared Record, content and uri properties are empty", Q_FUNC_INFO);
118 auto optExtraDataJson = tryGetOptionalJsonObjectProp(record,
"extraData");
120 return std::make_optional(
121 detail::SharedRecord{
122 .mimeType = QString::fromStdString(optMimeType.value()),
125 .title = tryGetOptionalStringProp(record,
"title"),
126 .label = tryGetOptionalStringProp(record,
"label"),
127 .description = tryGetOptionalStringProp(record,
"description"),
128 .thumbnail = tryGetOptionalByteArrayProp(record,
"thumbnail"),
129 .thumbnailFilePath = tryGetOptionalStringProp(record,
"thumbnailUri"),
130 .extraData = optExtraDataJson.has_value()
131 ? std::make_optional(optExtraDataJson.value().toVariantMap())
137 QtOhos::enums::ohos::app::ability::AbilityConstant::LaunchReason ohosLaunchReason)
139 using OhosLaunchReason = QtOhos::enums::ohos::app::ability::AbilityConstant::LaunchReason;
142 switch (ohosLaunchReason) {
143 case OhosLaunchReason::START_ABILITY:
145 case OhosLaunchReason::CONTINUATION:
147 case OhosLaunchReason::PREPARE_CONTINUATION:
149 case OhosLaunchReason::PRELOAD:
151 case OhosLaunchReason::UNKNOWN:
152 case OhosLaunchReason::CALL:
153 case OhosLaunchReason::APP_RECOVERY:
154 case OhosLaunchReason::SHARE:
155 case OhosLaunchReason::AUTO_STARTUP:
156 case OhosLaunchReason::INSIGHT_INTENT:
164 QOhosJsState &jsState, QNapi::Number jsLaunchReason)
166 auto optLaunchReasonJsEnum =
167 jsState.tryMapOhosEnumFromJs<QtOhos::enums::ohos::app::ability::AbilityConstant::LaunchReason>(jsLaunchReason);
168 auto optLaunchReason =
169 optLaunchReasonJsEnum.has_value()
170 ? tryMapOhosLaunchReasonToWantInfoEnum(optLaunchReasonJsEnum.value())
178 WantInfoImpl(QNapi::Object want,
LaunchReason launchReason);
180 QJsonObject jsonObject()
const override;
182 std::optional<QList<detail::SharedRecord>> tryGetSharedDataRecords()
const override;
191 QNapi::Reference<QNapi::Object> want;
194 std::shared_ptr<JsScopeData> m_jsScopeData;
195 QJsonObject m_jsonObject;
199WantInfoImpl::WantInfoImpl(QNapi::Object want,
LaunchReason launchReason)
202 QtOhos::makeProxyWithJsThreadDeleter(
203 QtOhos::moveToSharedPtr(
205 .want = QNapi::Reference<>::makePersistentFrom(want),
207 , m_jsonObject(QOhosJsEnv::fromNapiValue<QJsonObject>(want))
208 , m_launchReason(launchReason)
212QJsonObject WantInfoImpl::jsonObject()
const
217std::optional<QList<detail::SharedRecord>> WantInfoImpl::tryGetSharedDataRecords()
const
221 return QOhosJsThreadGateway::evalWithPromise<std::optional<QList<SharedRecord>>>(
222 [&](QOhosJsState &jsState, QOhosTaskPromise<std::optional<QList<SharedRecord>>> evalPromise) {
223 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
224 jsState.evalToPromiseOrRejectOnThrow(
225 "@kit.ShareKit.systemShare.getSharedData(*)", {m_jsScopeData->want.Value()})
227 [thenPromise = std::move(thenCatchPromises.first)](
const QOhosCallbackInfo &cbInfo) {
228 QNapi::Object sharedData = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
230 auto optRecords = QNapi::getArrayElements<QList<std::optional<SharedRecord>>, QNapi::Object>(
231 sharedData.eval<QNapi::Array>(
"getRecords()"), &tryConvertNapiObjectToSharedRecord);
233 QList<SharedRecord> records;
234 for (
const auto &optRecord : optRecords) {
235 if (optRecord.has_value())
236 records.append(optRecord.value());
239 std::size_t unconvertedRecordsCount = optRecords.size() - records.size();
240 if (unconvertedRecordsCount != 0) {
242 "%s: can't convert %zu Shared Records, ignoring them",
243 Q_FUNC_INFO, unconvertedRecordsCount);
246 thenPromise(std::make_optional(records));
249 [catchPromise = std::move(thenCatchPromises.second)](
const QOhosCallbackInfo &cbInfo) {
250 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getSharedData() failed");
251 catchPromise(std::nullopt);
261 return QOhosJsThreadGateway::evalWithPromise<std::optional<ContactInfo>>(
262 [&](QOhosJsState &jsState, QOhosTaskPromise<std::optional<ContactInfo>> evalPromise) {
263 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
264 jsState.evalToPromiseOrRejectOnThrow(
265 "@kit.ShareKit.systemShare.getContactInfo(*)", {m_jsScopeData->want.Value()})
267 [thenPromise = std::move(thenCatchPromises.first)](
const QOhosCallbackInfo &cbInfo) {
268 auto contactInfoObj = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
269 ContactInfo contactInfo = {
270 .contactType = QString::fromStdString(
271 contactInfoObj.get<QNapi::String>(
"contactType")),
272 .contactId = QString::fromStdString(
273 contactInfoObj.get<QNapi::String>(
"contactId")),
275 thenPromise(std::make_optional(contactInfo));
278 [catchPromise = std::move(thenCatchPromises.second)](
const QOhosCallbackInfo &cbInfo) {
279 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getContactInfo() failed");
280 catchPromise(std::nullopt);
288 return m_launchReason;
295 return QOhosJsThreadGateway::eval(
296 [](QOhosJsState &jsState) {
297 auto optAppLaunchParam = jsState.optAppLaunchParam();
298 auto optAppLaunchReason = optAppLaunchParam.has_value()
299 ? std::make_optional(mapJsLaunchReasonToWantInfoEnumWithFallback(
300 jsState, optAppLaunchParam.value().get<QNapi::Number>(
"launchReason")))
302 auto appLaunchReason = optAppLaunchReason.value_or(detail::WantInfoPriv::LaunchReason::UNKNOWN);
303 return QSharedPointer<WantInfoImpl>::create(jsState.appLaunchWant(), appLaunchReason);
310 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
313 [sharedWantConsumer](QSharedPointer<detail::WantInfoPriv> wantInfo) {
314 (*sharedWantConsumer)(wantInfo->jsonObject());
319 QObject *context, QOhosConsumer<QSharedPointer<detail::WantInfoPriv>> wantConsumer)
321 auto contextRef = QtOhos::makeQThreadSafeRef(context);
322 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
323 QOhosJsThreadGateway::runAndWait(
324 [&](QOhosJsState &jsState) {
325 jsState.addNewWantConsumer(
326 [contextRef, sharedWantConsumer](QOhosJsState &jsState, QNapi::Object napiWant, QNapi::Object launchParam) {
327 auto launchReason = mapJsLaunchReasonToWantInfoEnumWithFallback(
328 jsState, launchParam.get<QNapi::Number>(
"launchReason"));
329 auto wantInfo = QSharedPointer<WantInfoImpl>::create(napiWant, launchReason);
330 contextRef.visitInQtThreadIfAlive(
331 [sharedWantConsumer, wantInfo](
auto &) {
332 (*sharedWantConsumer)(wantInfo);