4#include <QtCore/private/qnapi_p.h>
5#include <QtCore/private/qohoscommon_p.h>
6#include <qohosjsenv_p.h>
7#include <QtCore/qobject.h>
8#include <QtCore/qscopeguard.h>
9#include <QtGui/private/qguiapplication_p.h>
10#include <QtGui/qcolor.h>
11#include <QtGui/qimage.h>
12#include <QtGui/qscreen.h>
13#include <QtGui/qwindow.h>
16#include <filemanagement/file_uri/oh_file_uri.h>
17#include <filemanagement/fileshare/oh_file_share.h>
19#include <info/application_target_sdk_version.h>
21#include <qohosapppermissions_p.h>
22#include <qohosdeviceinfo_p.h>
23#include <qohosenums.h>
24#include <qohosjsmain.h>
25#include <qohosjsutils.h>
26#include <qohospixelmapconversions.h>
27#include <qohosplatformclipboard.h>
28#include <qohosplatformintegration.h>
29#include <qohosplatformservices.h>
30#include <qohosplatformwindow.h>
31#include <qohosplugincore.h>
32#include <qohosqpafunctions_p.h>
33#include <qohossettings.h>
34#include <qohossharekit.h>
35#include <qohosudmfconversions.h>
36#include <qohosutils.h>
37#include <qohoswindowmanager.h>
38#include <render/qwindowproxyregistry.h>
44using namespace std::chrono_literals;
58 switch (ohosLaunchReason) {
68 case OhosLaunchReason
::CALL:
82 auto optLaunchReasonJsEnum =
83 jsState.tryMapOhosEnumFromJs<enums::ohos::app::ability::AbilityConstant::LaunchReason>(jsLaunchReason);
84 auto optLaunchReason =
85 optLaunchReasonJsEnum.has_value()
86 ? tryMapOhosLaunchReasonToWantInfoEnum(optLaunchReasonJsEnum.value())
87 : makeEmptyQOhosOptional();
91Q_NORETURN
void killCurrentProcess()
93 ::kill(getpid(), SIGKILL);
103 case AbilityOnContinueResponseStatus
::Agree:
105 case AbilityOnContinueResponseStatus
::Reject:
107 case AbilityOnContinueResponseStatus
::Mismatch:
119 switch (windowMode) {
128 qCWarning(QtForOhos,
"%s: got illegal WindowMode: %d", Q_FUNC_INFO,
static_cast<
int>(windowMode));
139 switch (processMode) {
146 qCWarning(QtForOhos,
"%s: got illegal ProcessMode: %d", Q_FUNC_INFO,
static_cast<
int>(processMode));
157 switch (startupVisibility) {
164 qCWarning(QtForOhos,
"%s: got illegal StartupVisibility: %d", Q_FUNC_INFO,
static_cast<
int>(startupVisibility));
175 switch (supportWindowMode) {
184 qCWarning(QtForOhos,
"%s: got illegal SupportWindowMode: %d", Q_FUNC_INFO,
static_cast<
int>(supportWindowMode));
189QNapi::Array mapSupportWindowModesToJsEnumsArray(
190 QtOhos::
JsState &jsState,
const QList<QOhosQpaFunctions::StartOptions::SupportWindowMode> &supportWindowModes)
192 std::vector<QNapi::ValueWrapper> jsSupportWindowModes;
193 for (
auto supportWindowMode : supportWindowModes) {
194 auto optOhosSupportWindowMode = tryMapSupportWindowModeToOhosOrLogWarning(supportWindowMode);
195 if (optOhosSupportWindowMode.hasValue())
196 jsSupportWindowModes.push_back(jsState.mapOhosEnumToJs(optOhosSupportWindowMode.value()));
199 return QNapi::makeArray(jsState.env(), jsSupportWindowModes);
202QNapi::Object makeJsCompletionHandler(
203 QtOhos::
JsState &jsState, std::shared_ptr<QOhosConsumer<
bool, QJsonObject, QString>> qtThreadCompletionHandler)
205 auto makeCompletionCallback = [qtThreadCompletionHandler](
bool requestSuccess) {
206 return [qtThreadCompletionHandler, requestSuccess](
const QNapi::CallbackInfo &cbInfo) {
207 QNapi::Object elementNameObj;
208 QNapi::String messageValue;
209 cbInfo.getLeadingArgs(Q_FUNC_INFO, elementNameObj, messageValue);
211 const QJsonObject elementName = QOhosJsEnv::fromNapiValue<QJsonObject>(elementNameObj);
212 const QString message = QString::fromStdString(messageValue);
214 QtOhos::invokeInQtThread(
215 [qtThreadCompletionHandler, requestSuccess, elementName, message]() {
216 (*qtThreadCompletionHandler)(requestSuccess, elementName, message);
221 return QNapi::makeObject(
224 {
"onRequestSuccess", makeCompletionCallback(
true)},
225 {
"onRequestFailure", makeCompletionCallback(
false)},
231QNapi::Object convertStartOptionsToNapiObject(
234 auto *env = jsState.env();
235 auto napiOptions = QNapi::Object::New(env);
237 auto optOhosWindowMode = opts.windowMode.andThen(&tryMapWindowModeToOhosOrLogWarning);
238 if (optOhosWindowMode.hasValue())
239 napiOptions.set(
"windowMode", jsState.mapOhosEnumToJs(optOhosWindowMode.value()));
240 if (opts.displayId.hasValue())
241 napiOptions.set(
"displayId", opts.displayId.value());
242 if (opts.withAnimation.hasValue())
243 napiOptions.set(
"withAnimation", opts.withAnimation.value());
244 if (opts.windowLeft.hasValue())
245 napiOptions.set(
"windowLeft", opts.windowLeft.value());
246 if (opts.windowTop.hasValue())
247 napiOptions.set(
"windowTop", opts.windowTop.value());
248 if (opts.windowWidth.hasValue())
249 napiOptions.set(
"windowWidth", opts.windowWidth.value());
250 if (opts.windowHeight.hasValue())
251 napiOptions.set(
"windowHeight", opts.windowHeight.value());
252 auto optOhosProcessMode = opts.processMode.andThen(&tryMapProcessModeToOhosOrLogWarning);
253 if (optOhosProcessMode.hasValue())
254 napiOptions.set(
"processMode", jsState.mapOhosEnumToJs(optOhosProcessMode.value()));
255 auto optOhosStartupVisibility = opts.startupVisibility.andThen(&tryMapStartupVisibilityToOhosOrLogWarning);
256 if (optOhosStartupVisibility.hasValue())
257 napiOptions.set(
"startupVisibility", jsState.mapOhosEnumToJs(optOhosStartupVisibility.value()));
258 if (opts.windowFocused.hasValue())
259 napiOptions.set(
"windowFocused", opts.windowFocused.value());
260 if (opts.windowIcon.hasValue()) {
261 auto windowIcon = opts.windowIcon.value().value<QImage>();
262 if (!windowIcon.isNull())
263 napiOptions.set(
"startWindowIcon", createNapiPixelMapFromQImage(jsState, windowIcon));
265 if (opts.windowBackgroundColorHex.hasValue())
266 napiOptions.set(
"startWindowBackgroundColor", opts.windowBackgroundColorHex.value().toStdString());
267 if (opts.supportWindowModes.hasValue()) {
268 auto jsSupportWindowModes = mapSupportWindowModesToJsEnumsArray(jsState, opts.supportWindowModes.value());
269 if (jsSupportWindowModes.Length() != 0)
270 napiOptions.set(
"supportWindowModes", jsSupportWindowModes);
272 qCWarning(QtForOhos,
"%s: OHOS doesn't support empty supportWindowModes, skipping", Q_FUNC_INFO);
274 if (opts.minWindowWidth.hasValue())
275 napiOptions.set(
"minWindowWidth", opts.minWindowWidth.value());
276 if (opts.minWindowHeight.hasValue())
277 napiOptions.set(
"minWindowHeight", opts.minWindowHeight.value());
278 if (opts.maxWindowWidth.hasValue())
279 napiOptions.set(
"maxWindowWidth", opts.maxWindowWidth.value());
280 if (opts.maxWindowHeight.hasValue())
281 napiOptions.set(
"maxWindowHeight", opts.maxWindowHeight.value());
282 if (opts.optCompletionHandler) {
283 constexpr auto minSupportedSdkVersion = 20;
285 if (ohosSdkVersion >= minSupportedSdkVersion) {
286 napiOptions.set(
"completionHandler", makeJsCompletionHandler(jsState, opts.optCompletionHandler));
290 "%s: completionHandler ignored because sdkApi %d < required %d",
291 Q_FUNC_INFO, ohosSdkVersion, minSupportedSdkVersion);
294 if (opts.hideStartWindow.hasValue()) {
295 constexpr auto minSupportedSdkVersion = 20;
297 if (ohosSdkVersion >= minSupportedSdkVersion) {
298 napiOptions.set(
"hideStartWindow", opts.hideStartWindow.value());
302 "%s: hideStartWindow ignored because sdkApi %d < required %d",
303 Q_FUNC_INFO, ohosSdkVersion, minSupportedSdkVersion);
306 if (opts.windowCreateParams.hasValue()) {
307 constexpr auto minSupportedSdkVersion = 20;
309 if (ohosSdkVersion >= minSupportedSdkVersion) {
310 const auto &windowCreateParams = opts.windowCreateParams.value();
311 std::vector<std::pair<std::string, QNapi::ValueWrapper>> windowCreateParamsProps;
312 if (windowCreateParams.setWindowFadeInOutAnimation) {
313 windowCreateParamsProps.emplace_back(
320 jsState.mapOhosEnumToJs(
321 enums::ohos::window::WindowCreateParams::AnimationType::FADE_IN_OUT),
325 napiOptions.set(
"windowCreateParams", QNapi::makeObject(env, windowCreateParamsProps));
329 "%s: windowCreateParams ignored because sdkApi %d < required %d",
330 Q_FUNC_INFO, ohosSdkVersion, minSupportedSdkVersion);
337std::shared_ptr<
void> registerAppContextEnvironmentCallback(
340 auto appContextRefPtr = QtOhos::moveToSharedPtr(
341 QNapi::Reference<>::makePersistentFrom(
342 jsState.defaultQAbilityPeer()->qAbility().eval<QNapi::Object>(
343 "context.getApplicationContext()")));
345 double environmentCallbackId = appContextRefPtr->call<QNapi::Number>(
347 {
"environment", environmentCallback});
349 return std::shared_ptr<
void>(
351 [environmentCallbackId, appContextRefPtr](
auto) {
354 auto appContextRef =
std::move(*appContextRefPtr);
357 {
"environment", environmentCallbackId});
362std::shared_ptr<
void> registerAppConfigurationUpdateListener(
365 return registerAppContextEnvironmentCallback(
371 "onConfigurationUpdated",
372 [updateListener = std::move(updateListener)](
const QtOhos::CallbackInfo &cbInfo) {
373 auto config = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
374 updateListener(cbInfo.jsState(), config);
380OhosConfigurationColorMode mapOhosConfigurationColorModeFromJs(
QtOhos::
JsState &jsState, QNapi::Number colorModeJsEnum)
383 auto optColorMode = jsState.tryMapOhosEnumFromJs<OhosConfigurationColorMode>(colorModeJsEnum);
384 return optColorMode.value_or(fallbackColorMode);
387void setOhosConfigColorMode(OhosConfigurationColorMode colorMode)
390 qCWarning(QtForOhos,
"%s: cannot set a color mode in 'no UI child mode'", Q_FUNC_INFO);
396 auto qAbility = jsState.defaultQAbilityPeer()->qAbility();
397 const auto jsColorMode = jsState.mapOhosEnumToJs(colorMode);
398 qAbility.call(
"context.getApplicationContext().setColorMode", {jsColorMode});
402template<
typename ConfigValue>
403QOhosSupplier<ConfigValue> makeOhosConfigValueDataSource(
405 std::function<ConfigValue(
QtOhos::
JsState &,
const QNapi::Object &)> valueFetcher,
406 QOhosConsumer<ConfigValue> valueChangedHandler)
409 QOhosConsumer<ConfigValue> valueChangedHandler;
410 ConfigValue receivedValue;
411 std::shared_ptr<
void> updateListenerHandle;
414 auto context =
QtOhos::evalInJsThread(
416 auto context =
std::make_shared<Context>();
417 context->valueChangedHandler =
std::move(valueChangedHandler);
418 context->receivedValue = initValueSupplier(jsState);
419 context->updateListenerHandle = registerAppConfigurationUpdateListener(
421 [weakContext = QtOhos::makeWeakPtr(context), valueFetcher = std::move(valueFetcher)](QtOhos::JsState &jsState, QNapi::Object config) {
422 auto configValue = valueFetcher(jsState, config);
423 QtOhos::invokeInQtThread(
424 [weakContext, configValue]() {
425 auto context = weakContext.lock();
426 if (context && configValue != context->receivedValue) {
427 context->receivedValue = configValue;
428 context->valueChangedHandler(context->receivedValue);
436 return context->receivedValue;
440QOhosSupplier<OhosConfigurationColorMode> makeOhosConfigColorModeDataSource(
441 QOhosConsumer<OhosConfigurationColorMode> valueChangedHandler)
443 return makeOhosConfigValueDataSource<OhosConfigurationColorMode>(
445 return mapOhosConfigurationColorModeFromJs(
446 jsState, jsState.defaultQAbilityPeer()->qAbility().eval<QNapi::Number>(
"context.config.colorMode"));
449 return mapOhosConfigurationColorModeFromJs(jsState, config.get<QNapi::Number>(
"colorMode"));
451 std::move(valueChangedHandler));
454QOhosOptional<
bool> mapOhosConfigurationColorModeToDarkModeFlag(OhosConfigurationColorMode colorMode)
460 return makeQOhosOptional(
false);
462 return makeQOhosOptional(
true);
468std::shared_ptr<
char> makeSharedNullTerminatedString(
std::string str)
470 auto sharedStrData = QtOhos::moveToSharedPtr(std::move(str) +
'\0');
471 return std::shared_ptr<
char>(sharedStrData, &sharedStrData->front());
474std::shared_ptr<
char> makeSharedNullTerminatedString(
const char *str)
476 return makeSharedNullTerminatedString(std::string(str !=
nullptr ? str :
""));
479template<
typename ConvFunc>
480std::string callOhFileUriConversionFunc(
481 ConvFunc convFunc,
const std::string &input)
483 char *outputPtr =
nullptr;
484 auto outputPtrGuard = qScopeGuard(
std::bind(::free, outputPtr));
485 auto convFuncRetVal = convFunc(input.c_str(), input.size(), &outputPtr);
487 std::string outputString;
488 if (convFuncRetVal == ::FileManagement_ErrCode::ERR_OK && outputPtr !=
nullptr) {
489 outputString = outputPtr;
492 "OH FileUri conversion function '%s' failed for input '%s', retval: %d",
493 convFunc.name(), input.c_str(),
static_cast<
int>(convFuncRetVal));
499std::string mapPathToOhosUriInJsThread(
const std::string &path)
501 return callOhFileUriConversionFunc(Q_OHOS_NAMED_FUNC(::OH_FileUri_GetUriFromPath), path);
504std::string mapOhosFileUriToPathInJsThread(
const std::string &ohosFileUri)
506 return callOhFileUriConversionFunc(Q_OHOS_NAMED_FUNC(::OH_FileUri_GetPathFromUri), ohosFileUri);
509std::shared_ptr<::FileShare_PolicyInfo> makeFileSharePolicyInfo(
510 std::string uri,
unsigned operationMode)
512 auto sharedUri = makeSharedNullTerminatedString(std::move(uri));
514 auto policyInfo = QtOhos::moveToSharedPtr(
515 ::FileShare_PolicyInfo{
516 .uri = sharedUri.get(),
517 .length =
static_cast<
unsigned>(std::strlen(sharedUri.get())),
518 .operationMode = operationMode,
521 return QtOhos::makeSharedPtrWithAttachedExtraData(
522 policyInfo, sharedUri);
525std::vector<std::shared_ptr<::FileShare_PolicyInfo>> convertToFileSharePolicyInfos(
526 const QList<QOhosQpaFunctions::FileShare::PolicyInfo> &policyInfos)
528 std::vector<std::shared_ptr<::FileShare_PolicyInfo>> fileSharePolicies;
530 for (
const auto &policyInfo : policyInfos) {
531 unsigned ohosOperationModes = 0;
532 for (
auto operationMode : policyInfo.operationModes)
533 ohosOperationModes |=
static_cast<
unsigned>(operationMode);
534 fileSharePolicies.push_back(
535 makeFileSharePolicyInfo(
536 mapPathToOhosUriInJsThread(policyInfo.path.toStdString()),
537 ohosOperationModes));
540 return fileSharePolicies;
543std::shared_ptr<::FileShare_PolicyErrorResult> makeFileSharePolicyErrorResultFromRawStruct(
544 const ::FileShare_PolicyErrorResult &inputStruct)
546 auto sharedUri = makeSharedNullTerminatedString(inputStruct.uri);
547 auto sharedMessage = makeSharedNullTerminatedString(inputStruct.message);
549 auto policyErrorResult = QtOhos::moveToSharedPtr(
550 ::FileShare_PolicyErrorResult{
551 .uri = sharedUri.get(),
552 .code = inputStruct.code,
553 .message = sharedMessage.get(),
556 return QtOhos::makeSharedPtrWithAttachedExtraData(
558 QtOhos::moveToSharedPtr(std::make_tuple(sharedUri, sharedMessage)));
561std::vector<::FileShare_PolicyInfo> makePoliciesRawVectorView(
562 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies)
564 std::vector<::FileShare_PolicyInfo> rawVectorView;
565 for (
const auto &policyPtr : policies)
566 rawVectorView.push_back(*policyPtr);
568 return rawVectorView;
571template<
typename PermissionActionFunc>
572::FileManagement_ErrCode callFileSharePermissionActionFunc(
573 PermissionActionFunc permissionActionFunc,
574 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
575 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &outResult)
577 auto policiesRawVectorView = makePoliciesRawVectorView(policies);
578 ::FileShare_PolicyErrorResult *resultParam =
nullptr;
579 unsigned resultNumParam = 0;
580 auto resultParamReleaseGuard = qScopeGuard(
582 if (resultParam !=
nullptr && resultNumParam != 0)
583 ::OH_FileShare_ReleasePolicyErrorResult(resultParam, resultNumParam);
586 auto errCode = permissionActionFunc(
587 policiesRawVectorView.data(), policiesRawVectorView.size(),
588 &resultParam, &resultNumParam);
591 if (resultParam !=
nullptr) {
592 for (
unsigned i = 0; i < resultNumParam; ++i) {
594 makeFileSharePolicyErrorResultFromRawStruct(resultParam[i]));
601::FileManagement_ErrCode fileShareCheckPersistentPermission(
602 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
603 std::vector<
bool> &outResult)
605 auto policiesRawVectorView = makePoliciesRawVectorView(policies);
606 bool *resultParam =
nullptr;
607 auto resultParamReleaseGuard = qScopeGuard(
611 unsigned resultNumParam = 0;
613 auto errCode = ::OH_FileShare_CheckPersistentPermission(
614 policiesRawVectorView.data(), policiesRawVectorView.size(),
615 &resultParam, &resultNumParam);
618 if (resultParam !=
nullptr) {
619 for (
unsigned i = 0; i < resultNumParam; ++i)
620 outResult.push_back(resultParam[i]);
626::FileManagement_ErrCode fileSharePersistPermission(
627 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
628 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &outResult)
630 return callFileSharePermissionActionFunc(
631 Q_OHOS_NAMED_FUNC(::OH_FileShare_PersistPermission),
632 policies, outResult);
635::FileManagement_ErrCode fileShareRevokePermission(
636 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
637 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &outResult)
639 return callFileSharePermissionActionFunc(
640 Q_OHOS_NAMED_FUNC(::OH_FileShare_RevokePermission),
641 policies, outResult);
644::FileManagement_ErrCode fileShareActivatePermission(
645 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
646 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &outResult)
648 return callFileSharePermissionActionFunc(
649 Q_OHOS_NAMED_FUNC(::OH_FileShare_ActivatePermission),
650 policies, outResult);
653::FileManagement_ErrCode fileShareDeactivatePermission(
654 const std::vector<std::shared_ptr<::FileShare_PolicyInfo>> &policies,
655 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &outResult)
657 return callFileSharePermissionActionFunc(
658 Q_OHOS_NAMED_FUNC(::OH_FileShare_DeactivatePermission),
659 policies, outResult);
663 ::FileShare_PolicyErrorCode errorCode)
667 case ::FileShare_PolicyErrorCode::PERSISTENCE_FORBIDDEN:
669 case ::FileShare_PolicyErrorCode::INVALID_MODE:
671 case ::FileShare_PolicyErrorCode::INVALID_PATH:
673 case ::FileShare_PolicyErrorCode::PERMISSION_NOT_PERSISTED:
679QList<QOhosQpaFunctions::FileShare::PolicyErrorResult> convertToPolicyErrorResults(
680 const std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> &policyErrorResults)
682 QList<QOhosQpaFunctions::FileShare::PolicyErrorResult> result;
683 for (
const auto &policyErrorResult : policyErrorResults) {
685 .path = policyErrorResult->uri !=
nullptr
686 ? QString::fromStdString(mapOhosFileUriToPathInJsThread(policyErrorResult->uri))
689 tryMapFileSharePolicyErrorCode(policyErrorResult->code),
690 .errorMessage = QLatin1String(
691 policyErrorResult->message !=
nullptr ? policyErrorResult->message :
""),
698bool isSuccessErrorCode(::FileManagement_ErrCode errorCode)
700 return errorCode == ::FileManagement_ErrCode::ERR_OK;
705 auto tryGetOptionalStringProp = [](
const QNapi::Object &object,
const std::string &propName) {
706 return getOptionalProperty<QNapi::String>(object, propName).transform(&QString::fromStdString);
709 auto tryGetOptionalByteArrayProp = [](
const QNapi::Object &object,
const std::string &propName) {
710 return getOptionalProperty<QNapi::TypedArrayOf<std::uint8_t>>(object, propName).transform(
711 [](
const auto &napiArray) {
713 reinterpret_cast<
const char *>(napiArray.Data()),
714 napiArray.ByteLength());
718 auto tryGetOptionalJsonObjectProp = [](
const QNapi::Object &object,
const std::string &propName) {
719 return getOptionalProperty<QNapi::Object>(object, propName).transform(
720 [](
const auto &napiObject) {
721 return QOhosJsEnv::fromNapiValue<QJsonObject>(napiObject);
725 std::string utd = record.get<QNapi::String>(
"utd");
726 auto optMimeType = utd != QOhosUdsMeta<::OH_UdsHyperlink>::udmfMetaId
727 ? tryMapUtdTypeIdToMimeType(utd)
728 : QOhosOptional<std::string>(QOhosShareKit::mimeTextUriList);
729 if (!optMimeType.hasValue()) {
731 "%s: can't map utd '%s' to mimetype, not mapping the record",
732 Q_FUNC_INFO, utd.c_str());
736 auto content = tryGetOptionalStringProp(record,
"content");
737 auto uri = tryGetOptionalStringProp(record,
"uri");
738 if (!content.hasValue() && !uri.hasValue()) {
740 "%s: cannot create Shared Record, content and uri properties are empty", Q_FUNC_INFO);
744 return makeQOhosOptional(
745 QOhosQpaFunctions::ShareKit::SharedRecord{
746 .mimeType = QString::fromStdString(optMimeType.value()),
749 .title = tryGetOptionalStringProp(record,
"title"),
750 .label = tryGetOptionalStringProp(record,
"label"),
751 .description = tryGetOptionalStringProp(record,
"description"),
752 .thumbnail = tryGetOptionalByteArrayProp(record,
"thumbnail"),
753 .thumbnailFilePath = tryGetOptionalStringProp(record,
"thumbnailUri"),
754 .extraData = tryGetOptionalJsonObjectProp(record,
"extraData").transform(std::mem_fn(&QJsonObject::toVariantMap)),
761 switch (abilityType) {
774 qOhosReportFatalErrorAndAbort(
775 "%s: unsupported ShareAbilityType value: %d",
776 Q_FUNC_INFO,
static_cast<
int>(abilityType));
782 WantInfoImpl(QNapi::Object want,
LaunchReason launchReason);
784 QJsonObject jsonObject()
const override;
786 QOhosOptional<QList<QOhosQpaFunctions::ShareKit::SharedRecord>> tryGetSharedDataRecords()
const override;
795 QNapi::Reference<QNapi::Object> want;
798 std::shared_ptr<JsScopeData> m_jsScopeData;
799 QJsonObject m_jsonObject;
803WantInfoImpl::WantInfoImpl(QNapi::Object want,
LaunchReason launchReason)
806 QtOhos::makeProxyWithJsThreadDeleter(
807 QtOhos::moveToSharedPtr(
809 .want = QNapi::Reference<>::makePersistentFrom(want),
811 , m_jsonObject(QOhosJsEnv::fromNapiValue<QJsonObject>(want))
812 , m_launchReason(launchReason)
816QJsonObject WantInfoImpl::jsonObject()
const
821QOhosOptional<QList<QOhosQpaFunctions::ShareKit::SharedRecord>> WantInfoImpl::tryGetSharedDataRecords()
const
825 return QtOhos::evalInJsThreadWithConsumer<QOhosOptional<QList<SharedRecord>>>(
826 [&](QtOhos::JsState &jsState, QOhosConsumer<QOhosOptional<QList<SharedRecord>>> resultConsumer) {
827 jsState.eval<QNapi::Promise>(
828 "@kit.ShareKit.systemShare.getSharedData(*)", {m_jsScopeData->want.Value()})
829 .withContext(std::move(resultConsumer))
831 [](
const QtOhos::CallbackInfo &cbInfo,
auto &resultConsumer) {
832 QNapi::Object sharedData = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
834 auto optRecords = QNapi::getArrayElements<QList<QOhosOptional<SharedRecord>>, QNapi::Object>(
835 sharedData.call<QNapi::Array>(
"getRecords"), &tryConvertNapiObjectToSharedRecord);
837 QList<SharedRecord> records;
838 for (
const auto &optRecord : optRecords) {
839 if (optRecord.hasValue())
840 records.append(optRecord.value());
843 if (records.size() != optRecords.size()) {
845 "%s: can't convert %lld Shared Records, ignoring them",
846 Q_FUNC_INFO, records.size() - optRecords.size());
849 resultConsumer(makeQOhosOptional(records));
852 [](
const QtOhos::CallbackInfo &cbInfo,
auto &resultConsumer) {
853 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getSharedData() failed");
854 resultConsumer(makeEmptyQOhosOptional());
864 [&](
QtOhos::
JsState &jsState, QOhosConsumer<QOhosOptional<ContactInfo>> resultConsumer) {
865 jsState.eval<QNapi::Promise>(
866 "@kit.ShareKit.systemShare.getContactInfo(*)", {m_jsScopeData->want.Value()})
867 .withContext(std::move(resultConsumer))
869 [](
const QtOhos::CallbackInfo &cbInfo, QOhosConsumer<QOhosOptional<ContactInfo>> &resultConsumer) {
870 auto contactInfoObj = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
871 ContactInfo contactInfo = {
872 .contactType = QString::fromStdString(
873 contactInfoObj.get<QNapi::String>(
"contactType")),
874 .contactId = QString::fromStdString(
875 contactInfoObj.get<QNapi::String>(
"contactId")),
877 resultConsumer(makeQOhosOptional(contactInfo));
880 [](
const QtOhos::CallbackInfo &cbInfo,
auto &resultConsumer) {
881 QtOhos::logJsCallbackError(cbInfo,
"@kit.ShareKit.systemShare.getContactInfo() failed");
882 resultConsumer(makeEmptyQOhosOptional());
889 return m_launchReason;
895 std::shared_ptr<
void> startPickingColorFromScreenWithConsumer(
896 QOhosConsumer<QOhosOptional<quint32>> colorConsumer)
override;
898 void setWindowPrivacyMode(QObject *window,
bool privacyModeEnabled)
override;
899 double getFontSizeScale()
override;
900 void setWindowCornerRadius(QObject *window,
double radius)
override;
901 void tagWindowOrWidgetAsFloatWindow(QObject *windowOrWidget,
bool floatWindow)
override;
903 void setInAppOnlyPasteboardShareOption(
bool shareInAppOnly)
override;
904 QVariant getImageDataFromPasteboard()
const override;
905 QString getTextDataFromPasteboard()
const override;
907 ScreenChangeResult tryChangePlatformWindowScreenInternal(QObject *windowObject, QObject *screenObject)
override;
909 void setWindowOrWidgetNativeNodeRenderFitPolicyHint(QObject *windowOrWidget,
NativeNodeRenderFitPolicy renderFitPolicy)
override;
911 void setSurfaceBackgroundColor(QObject *windowOrWidget,
const QColor &color)
override;
915 void setWindowKeepScreenOn(QObject *windowOrWidget,
bool keepScreenOn)
override;
917 QOhosOptional<
double> tryGetNativeWindowId(QObject *window)
override;
918 QOhosOptional<
double> tryGetScreenDisplayId(QObject *screenObject)
override;
920 void setOnContinueRequestsHandlerForAbilityInstanceWindow(
921 QObject *windowObject,
std::function<
void(
AbilityOnContinueRequest, QOhosConsumer<AbilityOnContinueResponse>)> requestsHandler)
override;
923 void setAbilityContinuationActive(
924 QObject *optInstanceMainWindow,
bool continuationActive)
override;
926 Q_NORETURN
void restartApp(QOhosOptional<QJsonObject> want)
override;
928 QJsonObject getAppLaunchWant()
override;
929 QSharedPointer<WantInfo> getAppLaunchWantInfo()
const override;
931 void addNewWantConsumer(QObject *context, QOhosConsumer<QJsonObject> wantConsumer)
override;
932 void addNewWantConsumer(
933 QObject *context, QOhosConsumer<QSharedPointer<WantInfo>> wantConsumer)
override;
935 void startAppProcess(
936 const QString &processId,
const QJsonObject &requestWant,
941 bool startAbilityByType(
const QString &appType,
const QJsonObject &wantParameters)
override;
943 void startAbilityForResult(
945 QObject *optInstanceMainWindow, QObject *resultConsumerQtContext,
946 QOhosConsumer<QOhosOptional<AbilityResult>> resultConsumer)
override;
948 void setDestroyAllowedFlagForAbilityInstances(
949 std::vector<QObject *> instancesMainWindows,
bool destroyEnabled)
override;
951 void setOhosConfigDarkModeFlag(
QOhosOptional<
bool> darkModeFlag)
override;
953 QOhosSupplier<QOhosOptional<
bool>> makeOhosConfigDarkModeFlagDataSource(
954 QOhosConsumer<QOhosOptional<
bool>> darkModeFlagChangedHandler)
override;
956 QOhosSupplier<
double> makeOhosConfigFontSizeScaleDataSource(
957 QOhosConsumer<
double> valueChangedHandler)
override;
959 int getCurrentApplicationVersionCode()
override;
961 bool readOhosNoUiChildMode()
override;
963 void startNoUiChildProcess(QString libraryName, QStringList args)
override;
965 std::pair<
bool, QList<FileShare::PolicyErrorResult>> persistPermission(
966 const QList<FileShare::PolicyInfo> &policyInfos)
override;
968 std::pair<
bool, QList<FileShare::PolicyErrorResult>> revokePermission(
969 const QList<FileShare::PolicyInfo> &policyInfos)
override;
971 std::pair<
bool, QList<FileShare::PolicyErrorResult>> activatePermission(
972 const QList<FileShare::PolicyInfo> &policyInfos)
override;
974 std::pair<
bool, QList<FileShare::PolicyErrorResult>> deactivatePermission(
975 const QList<FileShare::PolicyInfo> &policyInfos)
override;
977 std::pair<
bool, std::vector<
bool>> checkPersistent(
const QList<FileShare::PolicyInfo> &policyInfos)
override;
979 bool showFileDialogToAuthorizeFilePath(QObject *parentWindow,
const QString &filePath)
override;
981 void setWindowBrightness(QObject *window,
int brightness)
override;
982 void setWindowContrast(QObject *window,
int contrast)
override;
983 void setWindowSaturation(QObject *window,
int saturation)
override;
985 bool shareDataUsingShareKit(
986 QObject *windowObject,
const QList<ShareKit::SharedRecord> &recordsToShare,
989 std::shared_ptr<
void> shareDataUsingShareKit(
990 QObject *optWindowObject,
const QList<ShareKit::SharedRecord> &recordsToShare,
992 std::function<
void()> panelClosedCallback)
override;
994 bool tryOpenLink(QObject *optInstanceMainWindow,
const QString &link,
QOhosOptional<
bool> appLinkingOnly)
override;
996 QObject *getActiveWindowOrNull()
const override;
999std::shared_ptr<
void> QOhosQpaFunctionsImpl::startPickingColorFromScreenWithConsumer(
1000 QOhosConsumer<QOhosOptional<quint32>> colorConsumer)
1004 std::unique_ptr<QObject> colorConsumerQtContext;
1005 QOhosConsumer<QOhosOptional<quint32>> colorConsumer;
1008 auto sharedContext = QtOhos::moveToSharedPtr(
1010 .colorConsumerQtContext = std::make_unique<QObject>(),
1011 .colorConsumer = std::move(colorConsumer),
1014 auto colorConsumerProxy = QtOhos::moveToSharedPtr(
1015 [weakContext = QtOhos::makeWeakPtr(sharedContext)](QOhosOptional<quint32> rgbaColor) {
1016 auto sharedContext = weakContext.lock();
1017 if (sharedContext) {
1018 QMetaObject::invokeMethod(
1019 sharedContext->colorConsumerQtContext.get(),
1020 [weakContext, rgbaColor]() {
1021 auto sharedContext = weakContext.lock();
1023 sharedContext->colorConsumer(rgbaColor);
1025 Qt::QueuedConnection);
1031 jsState.eval<QNapi::Promise>(
"@kit.Penkit.imageFeaturePicker.pickForResult()")
1033 [colorConsumerProxy](
const QtOhos::CallbackInfo &cbInfo) {
1034 auto pickedColorInfo = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
1035 auto color = pickedColorInfo.get<QNapi::Object>(
"color");
1037 color.get<QNapi::Number>(
"red"),
1038 color.get<QNapi::Number>(
"green"),
1039 color.get<QNapi::Number>(
"blue"),
1040 color.get<QNapi::Number>(
"alpha"));
1041 (*colorConsumerProxy)(makeQOhosOptional(qColor.rgba()));
1044 [colorConsumerProxy](
const QtOhos::CallbackInfo &cbInfo) {
1045 QtOhos::logJsCallbackError(cbInfo,
"@kit.Penkit.imageFeaturePicker.pickForResult() failed");
1046 (*colorConsumerProxy)(makeEmptyQOhosOptional());
1050 return sharedContext;
1053void QOhosQpaFunctionsImpl::setWindowPrivacyMode(QObject *window,
bool privacyModeEnabled)
1055 QOhosPlatformWindow::setWindowPrivacyMode(window, privacyModeEnabled);
1058double QOhosQpaFunctionsImpl::getFontSizeScale()
1063void QOhosQpaFunctionsImpl::setInAppOnlyPasteboardShareOption(
bool shareInAppOnly)
1068QVariant QOhosQpaFunctionsImpl::getImageDataFromPasteboard()
const
1070 return QOhosPlatformIntegration::instance()->clipboard()->getPasteboardDataWithLazyFetchOrLocalIfOwner()->imageData();
1073QString QOhosQpaFunctionsImpl::getTextDataFromPasteboard()
const
1075 return QOhosPlatformIntegration::instance()->clipboard()->getPasteboardDataWithLazyFetchOrLocalIfOwner()->text();
1078void QOhosQpaFunctionsImpl::setWindowCornerRadius(QObject *windowOrWidget,
double radius)
1080 QOhosPlatformWindow::setWindowCornerRadius(windowOrWidget, radius);
1083void QOhosQpaFunctionsImpl::tagWindowOrWidgetAsFloatWindow(
1084 QObject *windowOrWidget,
bool floatWindow)
1086 QOhosPlatformWindow::tagWindowOrWidgetAsFloatWindow(windowOrWidget, floatWindow);
1091 auto *qWindow = qobject_cast<QWindow *>(windowObject);
1092 auto *qScreen = qobject_cast<QScreen *>(screenObject);
1094 if (qWindow ==
nullptr)
1095 qOhosReportFatalErrorAndAbort(
"%s: windowObject argument is null or not a QWindow", Q_FUNC_INFO);
1097 if (screenObject !=
nullptr && qScreen ==
nullptr)
1098 qOhosReportFatalErrorAndAbort(
"%s: screenObject argument is not a QScreen", Q_FUNC_INFO);
1100 auto *ohosPlatformWindow = QOhosPlatformWindow::fromQWindowOrNull(qWindow);
1101 auto *platformScreen = qScreen !=
nullptr ? qScreen->handle() :
nullptr;
1103 if (ohosPlatformWindow ==
nullptr)
1104 qOhosReportFatalErrorAndAbort(
"%s: platformWindow argument is null", Q_FUNC_INFO);
1106 auto tryChangeScreenResult = ohosPlatformWindow->tryChangeScreen(
static_cast<
QOhosPlatformScreen *>(platformScreen));
1108 switch (tryChangeScreenResult) {
1119void QOhosQpaFunctionsImpl::setWindowOrWidgetNativeNodeRenderFitPolicyHint(
1123 switch (renderFitPolicyHint) {
1132 if (policy.hasValue()) {
1133 QOhosPlatformWindow::setWindowOrWidgetNativeNodeRenderFitPolicyHint(windowOrWidget, policy.value());
1135 qOhosReportFatalErrorAndAbort(
1136 "%s: Failed to convert render fit policy hint to QOhosPlatformWindow enum",
1141void QOhosQpaFunctionsImpl::setSurfaceBackgroundColor(QObject *windowOrWidget,
const QColor &color)
1143 QOhosPlatformWindow::setSurfaceBackgroundColor(windowOrWidget, color);
1146void QOhosQpaFunctionsImpl::setMainWindowGeometryPersistencePolicy(
1150 switch (geometryPolicyHint) {
1162 if (policy.hasValue()) {
1165 qOhosReportFatalErrorAndAbort(
1166 "%s: Failed to convert persistence geometry policy hint to QOhosPlatformIntegration enum",
1171void QOhosQpaFunctionsImpl::setWindowKeepScreenOn(QObject *windowOrWidget,
bool keepScreenOn)
1173 QOhosPlatformWindow::setWindowKeepScreenOn(windowOrWidget, keepScreenOn);
1176QOhosOptional<
double> QOhosQpaFunctionsImpl::tryGetNativeWindowId(QObject *window)
1178 auto *qWindow = qobject_cast<QWindow *>(window);
1179 if (qWindow ==
nullptr)
1182 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(qWindow);
1183 if (platformWindow ==
nullptr)
1186 auto internalId = platformWindow->internalWindowId();
1188 if (!jsWinId.hasValue())
1192 "PlatformWindow WIID: %s is returning JsWindowId: %f to the user",
1193 qPrintable(internalId.toString()), jsWinId.value().value());
1195 return makeQOhosOptional(jsWinId.value().value());
1198QOhosOptional<
double> QOhosQpaFunctionsImpl::tryGetScreenDisplayId(QObject *screenObject)
1200 auto *qScreen = qobject_cast<QScreen *>(screenObject);
1201 if (qScreen ==
nullptr) {
1202 qOhosPrintfWarning(
"%s: screenObject argument is not a QScreen", Q_FUNC_INFO);
1207 return ohosPlatformScreen !=
nullptr
1208 ? makeQOhosOptional(ohosPlatformScreen->displayInfo().id.value())
1212void QOhosQpaFunctionsImpl::setOnContinueRequestsHandlerForAbilityInstanceWindow(
1215 auto *qWindow = qobject_cast<QWindow *>(windowObject);
1216 if (qWindow ==
nullptr)
1217 qOhosReportFatalErrorAndAbort(
"%s: windowObject argument is null or not a QWindow", Q_FUNC_INFO);
1219 auto qWindowRef = QObjectThreadSafeRef(qWindow);
1220 auto sharedRequestsHandler = moveToSharedPtr(
std::move(requestsHandler));
1222 struct JsResultContext
1224 QNapi::Reference<QNapi::Object> wantParamsReference;
1225 QOhosConsumer<JsState &, QOhosAbilityOnContinueResult> resultConsumer;
1231 jsState.tryGetQAbilityPeerByQWindow(qWindowRef)
);
1232 if (!uiAbilityPeer) {
1234 "%s: no QUiAbilityPeer for window %s, handler not set",
1235 Q_FUNC_INFO, qWindowRef.refName().c_str());
1239 uiAbilityPeer->setOnContinueRequestsHandler(
1240 [sharedRequestsHandler](
JsState &, QNapi::Object wantParamsObj,
auto resultConsumer) {
1241 int sourceVersionCode = wantParamsObj.get<QNapi::Number>(
"version");
1242 auto jsResultContext = makeProxyWithJsThreadDeleter(
std::make_shared<JsResultContext>());
1243 jsResultContext->wantParamsReference = QNapi::Reference<>::makePersistentFrom(wantParamsObj);
1244 jsResultContext->resultConsumer =
std::move(resultConsumer);
1245 QtOhos::invokeInQtThread(
1246 [sharedRequestsHandler, sourceVersionCode, jsResultContext]() {
1247 (*sharedRequestsHandler)(
1248 AbilityOnContinueRequest{
1249 .sourceApplicationVersionCode = sourceVersionCode,
1251 [jsResultContext](AbilityOnContinueResponse qtResponse) {
1252 QtOhos::invokeInJsThread(
1253 [jsResultContext, qtResponse](JsState &jsState) {
1254 if (qtResponse.status == AbilityOnContinueResponseStatus::Agree) {
1255 auto wantParamsObj = jsResultContext->wantParamsReference.Value();
1256 auto newWantParamsIter = qtResponse.wantObjectParams.constKeyValueBegin();
1257 while (newWantParamsIter != qtResponse.wantObjectParams.constKeyValueEnd()) {
1259 newWantParamsIter->first.toStdString(),
1260 newWantParamsIter->second.toStdString());
1261 ++newWantParamsIter;
1263 if (qtResponse.exitAppOnSourceDeviceAfterMigration.hasValue()) {
1265 jsState.eval<QNapi::String>(
1266 "@ohos.app.ability.wantConstant.Params.SUPPORT_CONTINUE_SOURCE_EXIT_KEY"),
1267 qtResponse.exitAppOnSourceDeviceAfterMigration.value());
1270 auto ohosResult = tryMapAbilityOnContinueResponseStatusToOhos(qtResponse.status);
1271 if (!ohosResult.hasValue()) {
1273 "%s: got illegal status (%d) from request handler, rejecting",
1274 Q_FUNC_INFO,
static_cast<
int>(qtResponse.status));
1276 jsResultContext->resultConsumer(
1277 jsState, ohosResult.valueOr(QOhosAbilityOnContinueResult::REJECT));
1285void QOhosQpaFunctionsImpl::setAbilityContinuationActive(
1286 QObject *optInstanceMainWindow,
bool continuationActive)
1290 auto optInstanceMainWindowRef =
1291 optInstanceMainWindow !=
nullptr
1292 ? makeQOhosOptional(QtOhos::QObjectThreadSafeRef(optInstanceMainWindow))
1296 [&](
JsState &jsState,
std::function<
void()> continueFunc) {
1297 auto optAbilityPeer = tryMapOptMainWindowToAbilityPeer(jsState, optInstanceMainWindowRef);
1298 if (!optAbilityPeer) {
1303 auto continueState = continuationActive ? ContinueState
::ACTIVE : ContinueState
::INACTIVE;
1304 optAbilityPeer->qAbility().call<QNapi::Promise>(
1305 "context.setMissionContinueState", {jsState.mapOhosEnumToJs(continueState)})
1306 .onCatch(QtOhos::makeErrorLoggingJsCallback(
"setMissionContinueState()"))
1307 .onFinally(std::move(continueFunc));
1311Q_NORETURN
void QOhosQpaFunctionsImpl::restartApp(QOhosOptional<QJsonObject> want)
1315 auto napiWant = want.hasValue()
1316 ? QNapi::checkedCast<QNapi::Object>(QOhosJsEnv::toNapiValue(jsState.env(), want.value()))
1317 : jsState.appLaunchWant();
1319 constexpr auto sleepTimeBeforeRetry = 3s;
1321 unsigned remainingTries = 3;
1327 "%s: calling restartApp() using Want: %s",
1328 Q_FUNC_INFO, QNapi::toJsonString(napiWant).c_str());
1331 jsState.defaultQAbilityPeer()->qAbility().call(
1332 "context.getApplicationContext().restartApp", {napiWant});
1334 qOhosPrintfWarning(
"%s: restartApp() call unexpectedly returned, killing self", Q_FUNC_INFO);
1335 killCurrentProcess();
1336 }
catch (
const Napi::Error &error) {
1337 constexpr std::uint32_t restartTooFrequentlyErrorCode = 16000064;
1339 auto errorCode = QtOhos::tryGetCodeFromJsBusinessError(error);
1341 if (errorCode == restartTooFrequentlyErrorCode && remainingTries != 0) {
1343 "%s: restartApp() returned with error %u, sleeping before retry",
1344 Q_FUNC_INFO, restartTooFrequentlyErrorCode);
1346 std::this_thread::sleep_for(sleepTimeBeforeRetry);
1348 auto errorCodeStr = errorCode.hasValue()
1349 ?
std::to_string(errorCode.value())
1352 "%s: restartApp() returned with error %s, killing self",
1353 Q_FUNC_INFO, errorCodeStr.c_str());
1355 killCurrentProcess();
1361 qOhosReportFatalErrorAndAbort(
"%s: unexpected return from the JS thread call", Q_FUNC_INFO);
1364QJsonObject QOhosQpaFunctionsImpl::getAppLaunchWant()
1366 return getAppLaunchWantInfo()->jsonObject();
1369QSharedPointer<QOhosQpaFunctions::WantInfo> QOhosQpaFunctionsImpl::getAppLaunchWantInfo()
const
1371 return QtOhos::evalInJsThread(
1373 auto optAppLaunchReason = jsState.optAppLaunchParam().transform(
1374 [&](QNapi::Object appLaunchParam) {
1375 return mapJsLaunchReasonToWantInfoEnumWithFallback(
1376 jsState, appLaunchParam.get<QNapi::Number>(
"launchReason"));
1379 return QSharedPointer<WantInfoImpl>::create(jsState.appLaunchWant(), appLaunchReason);
1383void QOhosQpaFunctionsImpl::addNewWantConsumer(QObject *context, QOhosConsumer<QJsonObject> wantConsumer)
1385 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
1388 [sharedWantConsumer](QSharedPointer<WantInfo> wantInfo) {
1389 (*sharedWantConsumer)(wantInfo->jsonObject());
1393void QOhosQpaFunctionsImpl::addNewWantConsumer(
1394 QObject *context, QOhosConsumer<QSharedPointer<WantInfo>> wantConsumer)
1396 auto contextRef = QtOhos::makeQThreadSafeRef(context);
1397 auto sharedWantConsumer = QtOhos::moveToSharedPtr(std::move(wantConsumer));
1399 [&](
auto &jsState) {
1400 jsState.addNewWantConsumer(
1401 [contextRef, sharedWantConsumer](
QtOhos::
JsState &jsState, QNapi::Object napiWant, QNapi::Object launchParam) {
1402 auto launchReason = mapJsLaunchReasonToWantInfoEnumWithFallback(
1403 jsState, launchParam.get<QNapi::Number>(
"launchReason"));
1404 auto wantInfo = QSharedPointer<WantInfoImpl>::create(napiWant, launchReason);
1405 contextRef.visitInQtThreadIfAlive(
1406 [sharedWantConsumer, wantInfo](
auto &) {
1407 (*sharedWantConsumer)(wantInfo);
1413void QOhosQpaFunctionsImpl::startAppProcess(
1414 const QString &processId,
const QJsonObject &requestWant,
1418 [&](
auto &jsState,
std::function<
void()> continueFunc) {
1419 auto startOptions = optStartOptions.hasValue()
1420 ? convertStartOptionsToNapiObject(jsState, optStartOptions.value())
1423 jsState.startAppProcess(
1424 processId.toStdString(),
1425 QNapi::checkedCast<QNapi::Object>(
1426 QOhosJsEnv::toNapiValue(jsState.env(), requestWant)),
1428 [continueFunc = std::move(continueFunc)](
QtOhos::
JsState &) {
1436 return QtOhos::evalInJsThread(
1437 [&](
auto &jsState) {
1438 auto mainUiAbility = jsState.defaultQAbilityPeer()->qAbility();
1439 if (mainUiAbility.IsEmpty())
1442 auto arguments = std::vector<QNapi::ValueWrapper>{QOhosJsEnv::toNapiValue(jsState.env(), want)};
1443 if (options.hasValue())
1444 arguments.push_back(convertStartOptionsToNapiObject(jsState, options.value()));
1446 mainUiAbility.call(
"context.startAbility", arguments);
1455bool QOhosQpaFunctionsImpl::startAbilityByType(
const QString &appType,
const QJsonObject &wantParameters)
1459 return QtOhos::evalInJsThreadWithConsumer<
bool>(
1460 [&](
QtOhos::
JsState &jsState, QOhosConsumer<
bool> resultConsumer) {
1461 auto qAbility = jsState.defaultQAbilityPeer()->qAbility();
1462 if (qAbility.IsEmpty()) {
1463 resultConsumer(
false);
1467 qAbility.call<QNapi::Promise>(
1468 "context.startAbilityByType",
1470 appType.toStdString(),
1471 QOhosJsEnv::toNapiValue(jsState.env(), wantParameters),
1477 [](
const QtOhos::CallbackInfo&) {
1478 qOhosPrintfDebug(
"startAbilityByType: onResult called");
1483 [](
const QtOhos::CallbackInfo &cbInfo) {
1484 QtOhos::logJsCallbackError(cbInfo,
"startAbilityByType: onError called");
1489 .withContext(std::move(resultConsumer))
1491 [](QOhosConsumer<
bool> &resultConsumer) {
1492 resultConsumer(
true);
1494 .onCatchWithContext(
1495 [](
const QtOhos::CallbackInfo &cbInfo, QOhosConsumer<
bool> &resultConsumer) {
1496 QtOhos::logJsCallbackError(cbInfo,
"startAbilityByType: failed");
1497 resultConsumer(
false);
1502void QOhosQpaFunctionsImpl::startAbilityForResult(
1504 QObject *optInstanceMainWindow, QObject *resultConsumerQtContext,
1505 QOhosConsumer<QOhosOptional<AbilityResult>> resultConsumer)
1509 QtOhos::QObjectThreadSafeRef resultConsumerQtContextRef;
1510 QOhosConsumer<QOhosOptional<AbilityResult>> resultConsumer;
1513 auto context = QtOhos::moveToSharedPtr(
1515 .resultConsumerQtContextRef = QtOhos::QObjectThreadSafeRef(resultConsumerQtContext),
1516 .resultConsumer = std::move(resultConsumer),
1519 auto optInstanceMainWindowRef =
1520 optInstanceMainWindow !=
nullptr
1521 ? makeQOhosOptional(QtOhos::QObjectThreadSafeRef(optInstanceMainWindow))
1525 [context, want, options, optInstanceMainWindowRef](QtOhos::JsState &jsState) {
1526 auto optAbilityPeer = tryMapOptMainWindowToAbilityPeer(jsState, optInstanceMainWindowRef);
1527 if (!optAbilityPeer) {
1528 context->resultConsumerQtContextRef.visitInQtThreadIfAlive(
1530 context->resultConsumer({});
1535 auto arguments = std::vector<QNapi::ValueWrapper>{QOhosJsEnv::toNapiValue(jsState.env(), want)};
1536 if (options.hasValue())
1537 arguments.push_back(convertStartOptionsToNapiObject(jsState, options.value()));
1539 optAbilityPeer->qAbility().call<QNapi::Promise>(
"context.startAbilityForResult", arguments)
1541 [context](
const QtOhos::CallbackInfo &cbInfo) {
1542 QNapi::Object abilityResult = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
1543 int resultCode = abilityResult.get<QNapi::Number>(
"resultCode");
1545 auto wantOrEmpty = QNapi::getOptionalPropOrEmpty<QNapi::Object>(abilityResult,
"want");
1546 auto jsonWant = !wantOrEmpty.IsEmpty()
1547 ? QOhosOptional<QJsonObject>(QOhosJsEnv::fromNapiValue<QJsonObject>(wantOrEmpty))
1548 : makeEmptyQOhosOptional();
1550 context->resultConsumerQtContextRef.visitInQtThreadIfAlive(
1551 [context, resultCode, jsonWant](
auto &) {
1552 constexpr int startedAbilityErrorResultCode = -1;
1553 context->resultConsumer(
1554 resultCode != startedAbilityErrorResultCode
1555 ? QOhosOptional<AbilityResult>({resultCode, jsonWant})
1556 : makeEmptyQOhosOptional());
1560 [context](
const QtOhos::CallbackInfo &cbInfo) {
1561 QtOhos::logJsCallbackError(cbInfo,
"Got error from startAbilityForResult()");
1562 context->resultConsumerQtContextRef.visitInQtThreadIfAlive(
1564 context->resultConsumer({});
1570void QOhosQpaFunctionsImpl::setDestroyAllowedFlagForAbilityInstances(
1571 std::vector<QObject *> instancesMainWindows,
bool destroyEnabled)
1573 std::vector<QtOhos::QObjectThreadSafeRef> instancesMainWindowsRefs;
1574 for (
auto *instanceMainWindow : instancesMainWindows)
1575 instancesMainWindowsRefs.emplace_back(instanceMainWindow);
1578 [&](
auto &jsState) {
1579 for (
const auto &instanceMainWindowRef : instancesMainWindowsRefs) {
1580 auto abilityPeer = jsState.tryGetQAbilityPeerByQWindow(instanceMainWindowRef);
1582 abilityPeer->destroyAllowedFlag()->store(destroyEnabled);
1587void QOhosQpaFunctionsImpl::setOhosConfigDarkModeFlag(
QOhosOptional<
bool> darkModeFlag)
1589 setOhosConfigColorMode(
1590 darkModeFlag.hasValue()
1591 ? darkModeFlag.value()
1597QOhosSupplier<QOhosOptional<
bool>> QOhosQpaFunctionsImpl::makeOhosConfigDarkModeFlagDataSource(
1598 QOhosConsumer<QOhosOptional<
bool>> darkModeFlagChangedHandler)
1600 auto colorModeDataSource = makeOhosConfigColorModeDataSource(
1601 [darkModeFlagChangedHandler = std::move(darkModeFlagChangedHandler)](OhosConfigurationColorMode newColorMode) {
1602 darkModeFlagChangedHandler(
1603 mapOhosConfigurationColorModeToDarkModeFlag(newColorMode));
1605 return [colorModeDataSource = std::move(colorModeDataSource)]() {
1606 return mapOhosConfigurationColorModeToDarkModeFlag(colorModeDataSource());
1610QOhosSupplier<
double> QOhosQpaFunctionsImpl::makeOhosConfigFontSizeScaleDataSource(
1611 QOhosConsumer<
double> valueChangedHandler)
1614 return makeOhosConfigValueDataSource<
double>(
1616 return initFontSizeScale;
1619 return config.get<QNapi::Number>(
"fontSizeScale").DoubleValue();
1621 std::move(valueChangedHandler));
1624int QOhosQpaFunctionsImpl::getCurrentApplicationVersionCode()
1626 return QtOhos::evalInJsThread(
1628 auto applicationInfoFlag = jsState.eval<QNapi::Number>(
1629 "@ohos.bundle.bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION");
1630 auto bundleInfo = jsState.eval<QNapi::Object>(
1631 "@ohos.bundle.bundleManager.getBundleInfoForSelfSync(*)", {applicationInfoFlag});
1632 int versionCode = bundleInfo.get<QNapi::Number>(
"versionCode");
1638bool QOhosQpaFunctionsImpl::readOhosNoUiChildMode()
1640 return QtOhos::evalInJsThread(
1641 [&](
auto &jsState) {
1642 return jsState.defaultQAbilityPeer()->instanceId().empty();
1646void QOhosQpaFunctionsImpl::startNoUiChildProcess(QString libraryName, QStringList args)
1649 [&](
auto &jsState) {
1650 std::vector<std::string> argsVector;
1652 args.begin(), args.end(),
std::back_inserter(argsVector),
1653 std::mem_fn(&QString::toStdString));
1654 jsState.startNoUiChildProcess(libraryName.toStdString(), argsVector);
1658std::pair<
bool, QList<QOhosQpaFunctions::FileShare::PolicyErrorResult>> QOhosQpaFunctionsImpl::persistPermission(
1659 const QList<FileShare::PolicyInfo> &policyInfos)
1661 return QtOhos::evalInJsThread(
1663 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> outResults;
1664 auto retCode = fileSharePersistPermission(
1665 convertToFileSharePolicyInfos(policyInfos), outResults);
1667 return std::make_pair(isSuccessErrorCode(retCode), convertToPolicyErrorResults(outResults));
1671std::pair<
bool, QList<QOhosQpaFunctions::FileShare::PolicyErrorResult>> QOhosQpaFunctionsImpl::revokePermission(
1672 const QList<FileShare::PolicyInfo> &policyInfos)
1674 return QtOhos::evalInJsThread(
1676 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> outResults;
1677 auto retCode = fileShareRevokePermission(
1678 convertToFileSharePolicyInfos(policyInfos), outResults);
1680 return std::make_pair(isSuccessErrorCode(retCode), convertToPolicyErrorResults(outResults));
1684std::pair<
bool, QList<QOhosQpaFunctions::FileShare::PolicyErrorResult>> QOhosQpaFunctionsImpl::activatePermission(
1685 const QList<FileShare::PolicyInfo> &policyInfos)
1687 return QtOhos::evalInJsThread(
1689 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> outResults;
1690 auto retCode = fileShareActivatePermission(
1691 convertToFileSharePolicyInfos(policyInfos), outResults);
1693 return std::make_pair(isSuccessErrorCode(retCode), convertToPolicyErrorResults(outResults));
1697std::pair<
bool, QList<QOhosQpaFunctions::FileShare::PolicyErrorResult>> QOhosQpaFunctionsImpl::deactivatePermission(
1698 const QList<FileShare::PolicyInfo> &policyInfos)
1700 return QtOhos::evalInJsThread(
1702 std::vector<std::shared_ptr<::FileShare_PolicyErrorResult>> outResults;
1703 auto retCode = fileShareDeactivatePermission(
1704 convertToFileSharePolicyInfos(policyInfos), outResults);
1706 return std::make_pair(isSuccessErrorCode(retCode), convertToPolicyErrorResults(outResults));
1710std::pair<
bool, std::vector<
bool>> QOhosQpaFunctionsImpl::checkPersistent(
1711 const QList<FileShare::PolicyInfo> &policyInfos)
1713 return QtOhos::evalInJsThread(
1715 std::vector<
bool> outResults;
1716 auto retCode = fileShareCheckPersistentPermission(
1717 convertToFileSharePolicyInfos(policyInfos), outResults);
1719 return std::make_pair(isSuccessErrorCode(retCode), outResults);
1723bool QOhosQpaFunctionsImpl::showFileDialogToAuthorizeFilePath(QObject *parentWindow,
const QString &filePath)
1725 auto *qWindow = qobject_cast<QWindow *>(parentWindow);
1726 if (qWindow ==
nullptr)
1727 qOhosReportFatalErrorAndAbort(
"%s: window argument is null or not a QWindow", Q_FUNC_INFO);
1729 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(qWindow);
1730 if (platformWindow ==
nullptr)
1731 qOhosReportFatalErrorAndAbort(
"%s: failed to get platform window", Q_FUNC_INFO);
1733 auto eventLoop = std::make_shared<QEventLoop>();
1734 auto filePathAuthorized =
std::make_shared<
bool>(
false);
1737 platformWindow->internalWindowId(), filePath,
1738 [filePathAuthorized, eventLoop](
bool result) {
1739 *filePathAuthorized = result;
1745 return *filePathAuthorized;
1748void QOhosQpaFunctionsImpl::setWindowBrightness(QObject *window,
int brightness)
1750 auto *qWindow = qobject_cast<QWindow *>(window);
1751 if (qWindow ==
nullptr)
1752 qOhosReportFatalErrorAndAbort(
"%s: window argument is null or not a QWindow", Q_FUNC_INFO);
1754 QOhosPlatformWindow::setBrightness(qWindow, brightness);
1757void QOhosQpaFunctionsImpl::setWindowContrast(QObject *window,
int contrast)
1759 auto *qWindow = qobject_cast<QWindow *>(window);
1760 if (qWindow ==
nullptr)
1761 qOhosReportFatalErrorAndAbort(
"%s: window argument is null or not a QWindow", Q_FUNC_INFO);
1763 QOhosPlatformWindow::setContrast(qWindow, contrast);
1766void QOhosQpaFunctionsImpl::setWindowSaturation(QObject *window,
int saturation)
1768 auto *qWindow = qobject_cast<QWindow *>(window);
1769 if (qWindow ==
nullptr)
1770 qOhosReportFatalErrorAndAbort(
"%s: window argument is null or not a QWindow", Q_FUNC_INFO);
1772 QOhosPlatformWindow::setSaturation(qWindow, saturation);
1775bool QOhosQpaFunctionsImpl::shareDataUsingShareKit(
1776 QObject *optWindowObject,
const QList<ShareKit::SharedRecord> &recordsToShare,
1779 return !!shareDataUsingShareKit(
1780 optWindowObject, recordsToShare, controllerOptions, makeQOhosNoOpConsumer());
1783std::shared_ptr<
void> QOhosQpaFunctionsImpl::shareDataUsingShareKit(
1784 QObject *optWindowObject,
const QList<ShareKit::SharedRecord> &recordsToShare,
1786 std::function<
void()> panelClosedCallback)
1788 auto *optQWindow = qobject_cast<QWindow *>(optWindowObject);
1789 if (optWindowObject !=
nullptr && optQWindow ==
nullptr)
1790 qOhosReportFatalErrorAndAbort(
"%s: window argument is not a QWindow", Q_FUNC_INFO);
1792 std::vector<QOhosShareKit::SharedRecord> shareKitRecords;
1793 for (
const auto &record : recordsToShare) {
1794 shareKitRecords.push_back(
1795 QOhosShareKit::SharedRecord{
1796 .mimeType = record.mimeType.toStdString(),
1797 .content = record.content.transform(std::mem_fn(&QString::toStdString)),
1798 .filePath = record.filePath.transform(std::mem_fn(&QString::toStdString)),
1799 .title = record.title.transform(std::mem_fn(&QString::toStdString)),
1800 .label = record.label.transform(std::mem_fn(&QString::toStdString)),
1801 .description = record.description.transform(std::mem_fn(&QString::toStdString)),
1802 .thumbnail = record.thumbnail,
1803 .thumbnailFilePath = record.thumbnailFilePath.transform(std::mem_fn(&QString::toStdString)),
1804 .extraData = record.extraData,
1809 .anchor = controllerOptions.anchorOffset.transform(
1810 [&](
auto anchorOffset) {
1812 .windowOffset = anchorOffset,
1813 .size = controllerOptions.anchorSize,
1816 .selectionMode = controllerOptions.useSingleSelectionMode.transform(
1817 [](
auto singleSelectionMode) {
1818 return singleSelectionMode
1822 .previewMode = controllerOptions.useDefaultPreviewMode.transform(
1823 [](
auto defaultPreviewMode) {
1824 return defaultPreviewMode
1828 .excludedAbilities = controllerOptions.excludedAbilities.transform(
1829 [](
const auto &excludedAbilities) {
1830 std::vector<QOhosShareKit::ShareAbilityType> outExcludedAbilities;
1831 for (
auto excludedAbilityType : excludedAbilities) {
1832 outExcludedAbilities.push_back(
1833 mapShareAbilityTypeFromQpaFunctionsEnum(excludedAbilityType));
1835 return outExcludedAbilities;
1839 return QOhosShareKit::shareData(
1840 optQWindow, shareKitRecords, shareKitControllerOptions,
std::move(panelClosedCallback));
1843bool QOhosQpaFunctionsImpl::tryOpenLink(QObject *optInstanceMainWindow,
const QString &link,
QOhosOptional<
bool> appLinkingOnly)
1845 if (optInstanceMainWindow !=
nullptr && qobject_cast<QWindow *>(optInstanceMainWindow) ==
nullptr)
1846 qOhosReportFatalErrorAndAbort(
"%s: the main window argument is not a QWindow", Q_FUNC_INFO);
1848 auto optInstanceMainWindowRef = optInstanceMainWindow !=
nullptr
1849 ? makeQOhosOptional(QtOhos::QObjectThreadSafeRef(optInstanceMainWindow))
1852 return QtOhos::evalInJsThreadWithConsumer<
bool>(
1853 [&](
QtOhos::
JsState &jsState, QOhosConsumer<
bool> resultConsumer) {
1854 auto optAbilityPeer = tryMapOptMainWindowToAbilityPeer(jsState, optInstanceMainWindowRef);
1855 if (!optAbilityPeer) {
1856 resultConsumer(
false);
1860 std::vector<std::pair<std::string, QNapi::ValueWrapper>> openLinkOptions;
1861 if (appLinkingOnly.hasValue())
1862 openLinkOptions.emplace_back(
"appLinkingOnly", appLinkingOnly.value());
1864 optAbilityPeer->qAbility().call<QNapi::Promise>(
1868 QNapi::makeObject(jsState.env(), openLinkOptions),
1870 .withContext(std::move(resultConsumer))
1872 [](QOhosConsumer<
bool> &resultConsumer) {
1873 resultConsumer(
true);
1875 .onCatchWithContext(
1876 [](
const QtOhos::CallbackInfo &cbInfo, QOhosConsumer<
bool> &resultConsumer) {
1877 QtOhos::logJsCallbackError(cbInfo,
"Got error from openLink()");
1878 resultConsumer(
false);
1883QObject *QOhosQpaFunctionsImpl::getActiveWindowOrNull()
const
1886 return !focusedWindows.empty() ? focusedWindows.front() :
nullptr;
1901 static QOhosQpaFunctionsImpl qpaFunctions;
1902 return qpaFunctions;
std::enable_if_t< qohosplugincore_h_detail::isQOhosOptional< QOhosInvokeResult< Func, T > >, QOhosInvokeResult< Func, T > > andThen(Func &&func) const
static QWindowProxyRegistry & instance()
NativeNodeRenderFitPolicy
AbilityOnContinueResponseStatus
WindowGeometryPersistencePolicy
virtual double getFontSizeScale()=0
virtual ~QOhosQpaFunctions()
static std::shared_ptr< QUiAbilityPeer > tryCastFromQAbilityPeerOrNull(std::shared_ptr< QAbilityPeer > qAbilityPeer)
void showFileDialogAuthorization(QtOhos::InternalWindowId contextWinId, QString filePath, QOhosConsumer< bool > resultCallback)
@ WINDOW_MODE_SPLIT_PRIMARY
@ WINDOW_MODE_SPLIT_SECONDARY
@ NEW_PROCESS_ATTACH_TO_PARENT
@ NEW_PROCESS_ATTACH_TO_STATUS_BAR_ITEM
void invokeInJsThread(std::function< void(JsState &)> task)
QOhosQpaFunctions & getQOhosQpaFunctions()
bool isOhosNoUiChildMode()
QOhosAbilityOnContinueResult
void runInJsThreadAndWait(const std::function< void(JsState &)> &task)
void invokeInJsThreadAndWaitForContinue(std::function< void(JsState &, std::function< void()>)> &&task)
QOhosOptional< void > makeEmptyQOhosOptional()
@ PERMISSION_NOT_PERSISTED
@ NEW_PROCESS_ATTACH_TO_PARENT
@ NEW_PROCESS_ATTACH_TO_STATUS_BAR_ITEM
@ WINDOW_MODE_SPLIT_PRIMARY
@ WINDOW_MODE_SPLIT_SECONDARY