7#include <QtCore/private/qcore_ohos_p.h>
8#include <QtCore/private/qnapi_p.h>
9#include <QtCore/private/qohoscommon_p.h>
10#include <QtCore/private/qohoslogger_p.h>
11#include <QtCore/qbytearray.h>
12#include <QtCore/qjsonobject.h>
13#include <QtCore/qlist.h>
14#include <QtCore/qstring.h>
15#include <QtCore/qvariant.h>
22#include <database/udmf/udmf_meta.h>
23#include <database/udmf/utd.h>
35std::optional<T> getOptionalProperty(
const QNapi::Object &object,
const std::string &propName)
37 auto optPropValue = QNapi::getOptionalPropOrEmpty<T>(object, propName);
38 return !optPropValue.IsEmpty()
39 ?
std::make_optional(optPropValue)
43std::optional<
std::string> tryMapUtdTypeIdToMimeType(
const std::string &utdTypeId)
45 std::shared_ptr<::OH_Utd> utd(
46 ::OH_Utd_Create(utdTypeId.c_str()),
49 ::OH_Utd_Destroy(utd);
52 std::vector<std::string> mimeTypes;
54 unsigned int typesCount = 0;
55 const char **rawMimeTypes = ::OH_Utd_GetMimeTypes(utd.get(), &typesCount);
56 if (rawMimeTypes ==
nullptr && typesCount != 0) {
57 qOhosReportFatalErrorAndAbort(
58 "%s: got inconsistent result from OH_Utd_GetMimeTypes() call: array is null, size is %u",
59 Q_FUNC_INFO, typesCount);
61 if (rawMimeTypes !=
nullptr)
62 mimeTypes = std::vector<std::string>(rawMimeTypes, rawMimeTypes + typesCount);
65 return !mimeTypes.empty()
66 ?
std::make_optional(mimeTypes.front())
72 auto tryGetOptionalStringProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QString> {
73 auto optProp = getOptionalProperty<QNapi::String>(object, propName);
74 return optProp.has_value()
75 ? std::make_optional(QString::fromStdString(optProp.value()))
79 auto tryGetOptionalByteArrayProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QByteArray> {
80 auto optProp = getOptionalProperty<QNapi::TypedArrayOf<std::uint8_t>>(object, propName);
81 return optProp.has_value()
82 ? std::make_optional(QByteArray(
83 reinterpret_cast<
const char *>(optProp.value().Data()),
84 optProp.value().ByteLength()))
88 auto tryGetOptionalJsonObjectProp = [](
const QNapi::Object &object,
const std::string &propName) -> std::optional<QJsonObject> {
89 auto optProp = getOptionalProperty<QNapi::Object>(object, propName);
90 return optProp.has_value()
91 ? std::make_optional(QOhosJsEnv::fromNapiValue<QJsonObject>(optProp.value()))
95 std::string utd = record.get<QNapi::String>(
"utd");
96 auto optMimeType = utd != UDMF_META_HYPERLINK
97 ? tryMapUtdTypeIdToMimeType(utd)
98 : std::optional<std::string>(
"text/uri-list");
99 if (!optMimeType.has_value()) {
101 "%s: can't map utd '%s' to mimetype, not mapping the record",
102 Q_FUNC_INFO, utd.c_str());
106 auto content = tryGetOptionalStringProp(record,
"content");
107 auto uri = tryGetOptionalStringProp(record,
"uri");
108 if (!content.has_value() && !uri.has_value()) {
110 "%s: cannot create Shared Record, content and uri properties are empty", Q_FUNC_INFO);
114 auto optExtraDataJson = tryGetOptionalJsonObjectProp(record,
"extraData");
116 return std::make_optional(
117 detail::SharedRecord{
118 .mimeType = QString::fromStdString(optMimeType.value()),
121 .title = tryGetOptionalStringProp(record,
"title"),
122 .label = tryGetOptionalStringProp(record,
"label"),
123 .description = tryGetOptionalStringProp(record,
"description"),
124 .thumbnail = tryGetOptionalByteArrayProp(record,
"thumbnail"),
125 .thumbnailFilePath = tryGetOptionalStringProp(record,
"thumbnailUri"),
126 .extraData = optExtraDataJson.has_value()
127 ? std::make_optional(optExtraDataJson.value().toVariantMap())
138 switch (ohosLaunchReason) {
148 case OhosLaunchReason
::CALL:
160 QOhosJsState &jsState, QNapi::Number jsLaunchReason)
162 auto optLaunchReasonJsEnum =
164 auto optLaunchReason =
165 optLaunchReasonJsEnum.has_value()
166 ? tryMapOhosLaunchReasonToWantInfoEnum(optLaunchReasonJsEnum.value())
174 WantInfoImpl(QNapi::Object want,
LaunchReason launchReason);
176 QJsonObject jsonObject()
const override;
178 std::optional<QList<detail::SharedRecord>> tryGetSharedDataRecords()
const override;
187 QNapi::Reference<QNapi::Object> want;
190 std::shared_ptr<JsScopeData> m_jsScopeData;
191 QJsonObject m_jsonObject;
195WantInfoImpl::WantInfoImpl(QNapi::Object want,
LaunchReason launchReason)
198 QtOhos::makeProxyWithJsThreadDeleter(
199 QtOhos::moveToSharedPtr(
201 .want = QNapi::Reference<>::makePersistentFrom(want),
203 , m_jsonObject(QOhosJsEnv::fromNapiValue<QJsonObject>(want))
204 , m_launchReason(launchReason)
208QJsonObject WantInfoImpl::jsonObject()
const
213std::optional<QList<detail::SharedRecord>> WantInfoImpl::tryGetSharedDataRecords()
const
217 return QOhosJsThreadGateway::evalWithPromise<std::optional<QList<SharedRecord>>>(
218 [&](QOhosJsState &jsState, QOhosTaskPromise<std::optional<QList<SharedRecord>>> evalPromise) {
219 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
220 jsState.evalToPromiseOrRejectOnThrow(
221 "@kit.ShareKit.systemShare.getSharedData(*)", {m_jsScopeData->want.Value()})
223 [thenPromise = std::move(thenCatchPromises.first)](
const QOhosCallbackInfo &cbInfo) {
224 QNapi::Object sharedData = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
226 auto optRecords = QNapi::getArrayElements<QList<std::optional<SharedRecord>>, QNapi::Object>(
227 sharedData.eval<QNapi::Array>(
"getRecords()"), &tryConvertNapiObjectToSharedRecord);
229 QList<SharedRecord> records;
230 for (
const auto &optRecord : optRecords) {
231 if (optRecord.has_value())
232 records.append(optRecord.value());
235 std::size_t unconvertedRecordsCount = optRecords.size() - records.size();
236 if (unconvertedRecordsCount != 0) {
238 "%s: can't convert %zu Shared Records, ignoring them",
239 Q_FUNC_INFO, unconvertedRecordsCount);
242 thenPromise(std::make_optional(records));
245 [catchPromise = std::move(thenCatchPromises.second)](
const QOhosCallbackInfo &cbInfo) {
246 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getSharedData() failed");
247 catchPromise(std::nullopt);
257 return QOhosJsThreadGateway::evalWithPromise<std::optional<ContactInfo>>(
258 [&](QOhosJsState &jsState, QOhosTaskPromise<std::optional<ContactInfo>> evalPromise) {
259 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
260 jsState.evalToPromiseOrRejectOnThrow(
261 "@kit.ShareKit.systemShare.getContactInfo(*)", {m_jsScopeData->want.Value()})
263 [thenPromise = std::move(thenCatchPromises.first)](
const QOhosCallbackInfo &cbInfo) {
264 auto contactInfoObj = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
265 ContactInfo contactInfo = {
266 .contactType = QString::fromStdString(
267 contactInfoObj.get<QNapi::String>(
"contactType")),
268 .contactId = QString::fromStdString(
269 contactInfoObj.get<QNapi::String>(
"contactId")),
271 thenPromise(std::make_optional(contactInfo));
274 [catchPromise = std::move(thenCatchPromises.second)](
const QOhosCallbackInfo &cbInfo) {
275 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getContactInfo() failed");
276 catchPromise(std::nullopt);
284 return m_launchReason;
291 return QOhosJsThreadGateway::eval(
292 [](QOhosJsState &jsState) {
293 auto optAppLaunchParam = jsState.optAppLaunchParam();
294 auto optAppLaunchReason = optAppLaunchParam.has_value()
295 ? std::make_optional(mapJsLaunchReasonToWantInfoEnumWithFallback(
296 jsState, optAppLaunchParam.value().get<QNapi::Number>(
"launchReason")))
298 auto appLaunchReason = optAppLaunchReason.value_or(detail::WantInfoPriv::LaunchReason::UNKNOWN);
299 return QSharedPointer<WantInfoImpl>::create(jsState.appLaunchWant(), appLaunchReason);
306 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
309 [sharedWantConsumer](QSharedPointer<detail::WantInfoPriv> wantInfo) {
310 (*sharedWantConsumer)(wantInfo->jsonObject());
315 QObject *context, QOhosConsumer<QSharedPointer<detail::WantInfoPriv>> wantConsumer)
317 auto contextRef = QtOhos::makeQThreadSafeRef(context);
318 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
319 QOhosJsThreadGateway::runAndWait(
320 [&](QOhosJsState &jsState) {
321 jsState.addNewWantConsumer(
322 [contextRef, sharedWantConsumer](QOhosJsState &jsState, QNapi::Object napiWant, QNapi::Object launchParam) {
323 auto launchReason = mapJsLaunchReasonToWantInfoEnumWithFallback(
324 jsState, launchParam.get<QNapi::Number>(
"launchReason"));
325 auto wantInfo = QSharedPointer<WantInfoImpl>::create(napiWant, launchReason);
326 contextRef.visitInQtThreadIfAlive(
327 [sharedWantConsumer, wantInfo](
auto &) {
328 (*sharedWantConsumer)(wantInfo);
QSharedPointer< detail::WantInfoPriv > makeAppLaunchWantInfo()
void addNewWantConsumer(QObject *context, QOhosConsumer< QJsonObject > wantConsumer)