5#include <QtCore/private/qnapi_p.h>
6#include <qohosjsenv_p.h>
7#include <QtCore/private/qohoslogger_p.h>
8#include <QtCore/qcryptographichash.h>
9#include <QtGui/qwindow.h>
15#include <qohosdeviceinfo_p.h>
16#include <qohosjsutils.h>
17#include <qohosplatformwindow.h>
18#include <render/qohosview.h>
26using namespace std::chrono_literals;
32const auto qtInternalRequestIdWantParamKey =
"io.qt.private.internalRequestId";
33const auto qAbilityInstanceIdWantParamKey =
"io.qt.private.abilityInstanceId";
34const auto callerAbilityNameWantParamKey =
"ohos.aafwk.param.callerAbilityName";
35const auto callerBundleNameWantParamKey =
"ohos.aafwk.param.callerBundleName";
36const auto callerPidWantParamKey =
"ohos.aafwk.param.callerPid";
38std::string getUtf8QtInternalRequestIdForThisProcess()
40 static const auto internalRequestIdCommonData =
41 QByteArray::fromHex(
"eba08604c86e45ae3690621757b3f4e9");
43 std::int32_t thisProcessPid = ::getpid();
45 QCryptographicHash hash{QCryptographicHash::Sha1};
46 hash.addData(internalRequestIdCommonData);
47 hash.addData(QByteArray::number(thisProcessPid));
49 return hash.result().toHex().toStdString();
52QNapi::Symbol getAbilityLaunchParamPropSymbol(
JsState &jsState)
58 return jsState.getJsSymbolForType<SymbolTag>();
61void sendWantToSelfQAbility(
63 QNapi::Object baseQAbility, QNapi::Object optStartOptions,
const std::string &instanceId,
66 auto qAbilityInfo = abilityEngine->readAbilityInfo(baseQAbility);
68 std::vector<QNapi::ValueWrapper> startAbilityArgs = {
72 {
"bundleName", qAbilityInfo.bundleName},
73 {
"moduleName", qAbilityInfo.moduleName},
74 {
"abilityName", qAbilityInfo.name},
80 {qtInternalRequestIdWantParamKey, getUtf8QtInternalRequestIdForThisProcess()},
81 {qAbilityInstanceIdWantParamKey, instanceId},
87 if (!optStartOptions.IsEmpty())
88 startAbilityArgs.push_back(optStartOptions);
90 baseQAbility.evalToPromiseOrRejectOnThrow(
"context.startAbility(*)", startAbilityArgs)
93 logJsCallbackError(cbInfo,
"context.startAbility()");
94 qOhosReportFatalErrorAndAbort(
"Failed to start the Ability with instance id: %s", instanceId.c_str());
97 [continueFunc = std::move(continueFunc)](
const CallbackInfo &cbInfo) {
102QOhosSupplier<std::string> makeAbilityInstanceIdsGenerator()
104 return [idsCounter =
std::uint64_t(0)]()
mutable {
105 auto instanceId =
std::to_string(idsCounter);
116 std::string instanceId, QObjectThreadSafeRef qwindow,
117 QNapi::Object uiAbility);
119 ~QAbilityPeerImpl() =
default;
121 std::string instanceId()
final;
122 QNapi::Object qAbility()
final;
123 QObjectThreadSafeRef qWindowRef()
final;
124 QOhosOptional<QNapi::Promise> qWindowDestroyPromise()
final;
125 void forceResolveQWindowDestroyPromiseIfPresent(Napi::Env env)
final;
126 std::shared_ptr<
std::atomic_bool> destroyAllowedFlag()
final;
128 void setQWindow(Napi::Env env, QObjectThreadSafeRef qwindow)
final;
131 struct QWindowDestroyPromiseData
133 std::optional<QNapi::Promise::Deferred> deferred;
134 QNapi::Reference<QNapi::Promise> promise;
138 std::string m_instanceId;
139 QObjectThreadSafeRef m_qwindow;
140 std::shared_ptr<QWindowDestroyPromiseData> m_optQWindowDestroyPromiseData;
141 std::shared_ptr<
std::atomic_bool> m_destroyAllowedFlag;
142 QNapi::Reference<QNapi::Object> m_uiAbility;
145QAbilityPeerImpl::QAbilityPeerImpl(
147 std::string instanceId, QObjectThreadSafeRef qwindow,
148 QNapi::Object uiAbility)
149 : m_abilityEngine(abilityEngine)
150 , m_instanceId(
std::move(instanceId))
151 , m_destroyAllowedFlag(std::make_shared<std::atomic_bool>(
false))
152 , m_uiAbility(Napi::Persistent(uiAbility))
154 setQWindow(uiAbility.Env(), qwindow);
157std::string QAbilityPeerImpl::instanceId()
162QNapi::Object QAbilityPeerImpl::qAbility()
164 return m_uiAbility.Value();
167QObjectThreadSafeRef QAbilityPeerImpl::qWindowRef()
172QOhosOptional<QNapi::Promise> QAbilityPeerImpl::qWindowDestroyPromise()
174 if (!m_optQWindowDestroyPromiseData || m_optQWindowDestroyPromiseData->promise.IsEmpty())
177 auto promiseValue = m_optQWindowDestroyPromiseData->promise.Value();
178 m_optQWindowDestroyPromiseData->promise.Reset();
180 return makeQOhosOptional(promiseValue);
183void QAbilityPeerImpl::forceResolveQWindowDestroyPromiseIfPresent(Napi::Env env)
185 if (!m_optQWindowDestroyPromiseData || !m_optQWindowDestroyPromiseData->deferred)
189 "%s: force-resolving QWindow destroy Promise for id='%s'",
190 Q_FUNC_INFO, m_instanceId.c_str());
191 std::exchange(m_optQWindowDestroyPromiseData->deferred,
std::nullopt)->Resolve(env.Undefined());
194std::shared_ptr<
std::atomic_bool> QAbilityPeerImpl::destroyAllowedFlag()
196 return m_destroyAllowedFlag;
199void QAbilityPeerImpl::setQWindow(Napi::Env env, QObjectThreadSafeRef qwindow)
201 if (qwindow == m_qwindow)
205 "%s: setting QAbilityPeer's QWindow: %s / %s",
206 Q_FUNC_INFO, m_instanceId.c_str(), m_qwindow.refName().c_str());
208 if (m_qwindow != QObjectThreadSafeRef()) {
209 qOhosReportFatalErrorAndAbort(
210 "QAbilityPeerImpl: overwriting previously set qwindow: %s => %s",
211 m_qwindow.refName().c_str(), qwindow.refName().c_str());
216 auto qWindowDestroyPromiseDeferred = QNapi::Promise::Deferred::New(env);
217 m_optQWindowDestroyPromiseData = std::make_shared<QWindowDestroyPromiseData>(
218 QWindowDestroyPromiseData{
219 .deferred = qWindowDestroyPromiseDeferred,
220 .promise = QNapi::Reference<QNapi::Promise>::makePersistentFrom(
221 qWindowDestroyPromiseDeferred.Promise()),
224 auto resolveQWindowDestroyPromiseFunc =
225 [qWindowRef = qwindow, weakPromiseData = QtOhos::makeWeakPtr(m_optQWindowDestroyPromiseData)]() {
227 "%s: sending request to resolve QWindow destroy notify Promise if needed: %s",
228 Q_FUNC_INFO, qWindowRef.refName().c_str());
230 [qWindowRef, weakPromiseData](
JsState &jsState) {
231 auto promiseData = weakPromiseData.lock();
232 if (promiseData && promiseData->deferred) {
234 "%s: resolving QWindow destroy notify Promise: %s",
235 Q_FUNC_INFO, qWindowRef.refName().c_str());
236 auto napiUndefined = Napi::Env(jsState.env()).Undefined();
237 std::exchange(promiseData->deferred,
std::nullopt)->Resolve(napiUndefined);
240 "%s: QAbilityPeer already removed on QWindow's destroy notification: %s",
241 Q_FUNC_INFO, qWindowRef.refName().c_str());
246 QtOhos::invokeInQtThread(
247 [qWindowRef = qwindow, resolveQWindowDestroyPromiseFunc]() {
248 auto *qWindow =
static_cast<QWindow *>(qWindowRef.data().data());
249 auto *platformWindow = qWindow !=
nullptr ? QOhosPlatformWindow::fromQWindowOrNull(qWindow) :
nullptr;
250 auto *view = platformWindow !=
nullptr ? platformWindow->ownedViewOrNull() :
nullptr;
252 if (view !=
nullptr) {
254 QtForOhos,
"%s: connecting to QOhosView's 'destroyed', win: %s",
255 Q_FUNC_INFO, qWindowRef.refName().c_str());
257 view, &QObject::destroyed,
258 [qWindowRef, resolveQWindowDestroyPromiseFunc](QObject *) {
260 QtForOhos,
"%s: got QOhosView's 'destroyed' signal, win: %s",
261 Q_FUNC_INFO, qWindowRef.refName().c_str());
262 resolveQWindowDestroyPromiseFunc();
266 QtForOhos,
"%s: QOhosView already destroyed, win: %s",
267 Q_FUNC_INFO, qWindowRef.refName().c_str());
268 resolveQWindowDestroyPromiseFunc();
278 std::string instanceId, QObjectThreadSafeRef qwindow,
279 QNapi::Object uiAbility, QNapi::Object windowStage);
281 QNapi::Object uiContext()
override;
282 QNapi::Object launchWant()
override;
283 QNapi::Object launchParam()
override;
284 QNapi::Object windowStage()
override;
285 QNapi::Object window()
override;
286 bool isTerminating()
override;
288 QNapi::Promise handleCloseRequestFromSystem(
290 std::function<QNapi::Value(JsState &, CloseAbilityRequestResolution)> promiseValueFactory)
override;
292 void handleOnContinueRequestFromSystem(
293 JsState &jsState, QNapi::Object wantParamsObj,
294 QOhosConsumer<JsState &, QOhosAbilityOnContinueResult> resultConsumer)
override;
296 void setOnContinueRequestsHandler(
297 std::function<
void(
JsState &, QNapi::Object, QOhosConsumer<JsState &, QOhosAbilityOnContinueResult>)> requestsHandler)
override;
300 QNapi::Reference<QNapi::Object> m_windowStage;
301 QNapi::Reference<QNapi::Object> m_window;
302 QNapi::Reference<QNapi::Object> m_launchParam;
303 std::shared_ptr<
void> m_windowWillCloseCallbackHandle;
304 std::function<
void(
JsState &, QNapi::Object, QOhosConsumer<JsState &, QOhosAbilityOnContinueResult>)> m_onContinueRequestsHandler;
307QUiAbilityPeerImpl::QUiAbilityPeerImpl(
309 std::string instanceId, QObjectThreadSafeRef qwindow,
310 QNapi::Object uiAbility, QNapi::Object windowStage)
311 : QAbilityPeerImpl(jsState, abilityEngine, instanceId, qwindow, uiAbility)
312 , m_windowStage(Napi::Persistent(windowStage))
313 , m_window(Napi::Persistent(windowStage.call<QNapi::Object>(
"getMainWindowSync")))
315 auto optLaunchParam = QNapi::getOptionalPropOrEmpty<QNapi::Object>(
316 uiAbility, getAbilityLaunchParamPropSymbol(jsState));
317 if (optLaunchParam.IsEmpty()) {
318 qOhosReportFatalErrorAndAbort(
319 "Ability with instanceId='%s' doesn't have 'launchParam' set. It shouldn't happen!",
322 m_launchParam = QNapi::Reference<>::makePersistentFrom(optLaunchParam);
324 m_windowWillCloseCallbackHandle = registerOnOffMethodsBasedEventHandler(
325 window(),
"windowWillClose",
326 [
this](
const CallbackInfo &cbInfo) {
327 JsState &jsState = cbInfo.jsState();
328 return handleCloseRequestFromSystem(
329 jsState,
"Window.windowWillClose",
330 CloseAbilityRequestSource::WindowWillClose,
331 [](JsState &jsState, CloseAbilityRequestResolution ohosRequestResolution) {
332 return QNapi::Boolean::New(
334 ohosRequestResolution == CloseAbilityRequestResolution::DontClose);
338 .optEventSourceAliveCheckFunc =
339 [qAbilityWeakRef = moveToSharedPtr(Napi::Weak(uiAbility))](QNapi::Object window) {
340 bool isWindowClosing = evalInJsThread(
342 return JsWindowsTracker::isWindowClosing(window);
345 auto qAbilityValue = qAbilityWeakRef->Value();
348 && qAbilityValue.IsObject()
349 && !QNapi::checkedCast<QNapi::Object>(qAbilityValue).eval<QNapi::Boolean>(
"context.isTerminating()");
351 .optOnCallExceptionHandler = [](
const Napi::Error &error) {
352 constexpr auto capabilityNotSupportedErrorCode = 801;
353 QtOhos::rethrowUnlessJsBusinessErrorIs(
354 error, capabilityNotSupportedErrorCode,
"on('windowWillClose')");
359QNapi::Object QUiAbilityPeerImpl::uiContext()
361 return window().call<QNapi::Object>(
"getUIContext");
364QNapi::Object QUiAbilityPeerImpl::launchWant()
366 return qAbility().get<QNapi::Object>(
"launchWant");
369QNapi::Object QUiAbilityPeerImpl::launchParam()
371 return m_launchParam.Value();
374QNapi::Object QUiAbilityPeerImpl::windowStage()
376 return m_windowStage.Value();
379QNapi::Object QUiAbilityPeerImpl::window()
381 return m_window.Value();
384bool QUiAbilityPeerImpl::isTerminating()
386 return qAbility().call<QNapi::Boolean>(
"context.isTerminating");
389QOhosCloseEventContext::CloseRootCause mapCloseAbilityRequestSourceToRootCause(
393 using CloseRootCause = QOhosCloseEventContext::CloseRootCause;
395 switch (requestSource) {
397 return CloseRootCause::OnPrepareToTerminate;
399 return CloseRootCause::WindowStageClose;
402 qOhosReportFatalErrorAndAbort(
"Unsupported CloseAbilityRequestSource: %d",
static_cast<
int>(requestSource));
405QNapi::Promise QUiAbilityPeerImpl::handleCloseRequestFromSystem(
407 std::function<QNapi::Value(JsState &, CloseAbilityRequestResolution)> promiseValueFactory)
409 auto instanceId =
this->instanceId();
412 "%s: got close request from source %d, id: '%s'",
413 logContextStr.c_str(),
static_cast<
int>(requestSource), instanceId.c_str());
415 if (destroyAllowedFlag()->load()) {
417 "%s: resolving immediately with 'false', id: '%s'",
418 Q_FUNC_INFO, instanceId.c_str());
419 JsWindowsTracker::tagWindowAsClosing(
420 window(), printfToString(
"%s => false", logContextStr.c_str()).c_str());
421 return makeResolvedPromise(
425 struct PromiseResolveFuncContext
427 std::string logContextStr;
429 std::shared_ptr<QNapi::Promise::Deferred> promiseDeferred;
430 std::string instanceId;
431 std::function<QNapi::Value(JsState &, CloseAbilityRequestResolution)> promiseValueFactory;
434 auto promiseResolveFuncContext = moveToSharedPtr(
435 PromiseResolveFuncContext{
436 .logContextStr = logContextStr,
437 .weakQAbilityPeer = makeWeakPtr(shared_from_this()),
438 .promiseDeferred = std::make_shared<QNapi::Promise::Deferred>(jsState.env()),
439 .instanceId = instanceId,
440 .promiseValueFactory = std::move(promiseValueFactory),
443 auto promiseResolveFunc = moveToSharedPtr(
446 auto qAbilityPeer = context->weakQAbilityPeer.lock();
448 JsWindowsTracker::tagWindowAsClosing(
449 qAbilityPeer->window(), printfToString(
"%s => false", context->logContextStr.c_str()).c_str());
451 context->promiseDeferred->Resolve(
452 context->promiseValueFactory(jsState, ohosRequestResolution));
454 "%s: promise resolved as %d, id: '%s'",
455 context->logContextStr.c_str(),
static_cast<
int>(ohosRequestResolution), context->instanceId.c_str());
458 constexpr auto promiseAutoresolveTimeout = 9s;
461 [logContextStr, promiseResolveFunc, instanceId](
const CallbackInfo &cbInfo) {
464 "%s: promise resolved by timeout, id: '%s'",
465 logContextStr.c_str(), instanceId.c_str());
468 promiseAutoresolveTimeout);
470 qWindowRef().visitInQtThreadIfAlive(
471 [logContextStr, requestSource, promiseResolveFunc, instanceId](
auto &qWindowObj) {
473 "%s: calling close(), id: '%s'",
474 logContextStr.c_str(), instanceId.c_str());
475 QOhosCloseEventContext::runWithCloseRootCauseAndCloseResolutionConsumerSet(
476 mapCloseAbilityRequestSourceToRootCause(requestSource),
477 [logContextStr, promiseResolveFunc, instanceId](QOhosCloseEventContext::CloseResolution closeResolution) {
478 auto ohosRequestResolution =
479 closeResolution == QOhosCloseEventContext::CloseResolution::Close
480 ? CloseAbilityRequestResolution::Close
481 : CloseAbilityRequestResolution::DontClose;
483 "%s: requesting promise resolve to %d from Qt thread, id: '%s'",
484 logContextStr.c_str(),
static_cast<
int>(ohosRequestResolution), instanceId.c_str());
485 QtOhos::invokeInJsThread(
486 [logContextStr, promiseResolveFunc, ohosRequestResolution, instanceId](JsState &jsState) {
487 bool resolveCalled = (*promiseResolveFunc)(jsState, ohosRequestResolution);
489 "%s: promise resolve to %d, called: %s, id: '%s'",
490 logContextStr.c_str(),
static_cast<
int>(ohosRequestResolution),
491 mapBoolToTrueFalseStr(resolveCalled), instanceId.c_str());
495 static_cast<QWindow &>(qWindowObj).close();
499 qOhosPrintfInfo(
"%s: returning Promise, id: '%s'", logContextStr.c_str(), instanceId.c_str());
501 return promiseResolveFuncContext->promiseDeferred->Promise();
504void QUiAbilityPeerImpl::handleOnContinueRequestFromSystem(
505 JsState &jsState, QNapi::Object wantParamsObj, QOhosConsumer<JsState &, QOhosAbilityOnContinueResult> resultConsumer)
507 if (m_onContinueRequestsHandler) {
508 m_onContinueRequestsHandler(jsState, wantParamsObj, std::move(resultConsumer));
510 qOhosPrintfDebug(
"%s: no handler set, rejecting", Q_FUNC_INFO);
512 [resultConsumer = std::move(resultConsumer)](
JsState &jsState) {
518void QUiAbilityPeerImpl::setOnContinueRequestsHandler(
519 std::function<
void(
JsState &, QNapi::Object, QOhosConsumer<JsState &, QOhosAbilityOnContinueResult>)> requestsHandler)
521 if (m_onContinueRequestsHandler) {
522 qOhosReportFatalErrorAndAbort(
523 "%s: overwriting previously set requests handler, id='%s'",
524 Q_FUNC_INFO, instanceId().c_str());
527 m_onContinueRequestsHandler = std::move(requestsHandler);
533 explicit QAbilityInstancesManagerImpl(
539 bool isWantFromThisApp(QNapi::Object appQAbility, QNapi::Object want)
const override;
541 QOhosOptional<std::string> tryGetQAbilityInstanceIdFromWant(QNapi::Object appQAbility, QNapi::Object want)
const override;
542 std::string getQAbilityInstanceIdOrPendingAutoStartedId(QNapi::Object qAbility)
const override;
544 QOhosOptional<std::string> pendingAutoStartedInstanceId()
const override;
546 void registerPendingAutoStartedInstance()
override;
548 void startNewInstance(
549 QNapi::Object baseQAbility, QObjectThreadSafeRef qwindow,
550 QNapi::Object optStartOptions,
553 void handleStartedUiInstance(
JsState &jsState, QNapi::Object qAbility, QNapi::Object windowStage)
override;
558 struct InstanceStartParams
560 QObjectThreadSafeRef qwindow;
564 void handleStartedInstance(
565 JsState &jsState,
const std::string &abilityInstanceId,
566 const std::function<
std::shared_ptr<
QAbilityPeer>(
const std::string &,
const InstanceStartParams &)> &qAbilityPeerFactory);
570 std::shared_ptr<std::map<QUiAbilityPeer *, std::weak_ptr<QUiAbilityPeerImpl>>> m_ownedUiAbilityPeers;
571 QOhosSupplier<std::string> m_abilityInstanceIdsGenerator;
572 std::map<std::string, InstanceStartParams> m_pendingInstancesStartParams;
573 QOhosOptional<std::string> m_pendingAutoStartedInstanceId;
576QAbilityInstancesManagerImpl::QAbilityInstancesManagerImpl(
579 : m_abilityEngine(abilityEngine)
580 , m_autoStartedInstanceStartupNotifyFunc(moveToSharedPtr(std::move(autoStartedInstanceStartupNotifyFunc)))
581 , m_ownedUiAbilityPeers(std::make_shared<std::map<QUiAbilityPeer *, std::weak_ptr<QUiAbilityPeerImpl>>>())
582 , m_abilityInstanceIdsGenerator(makeAbilityInstanceIdsGenerator())
584 registerPendingAutoStartedInstance();
587QOhosOptional<std::string> QAbilityInstancesManagerImpl::tryGetQAbilityInstanceIdFromWant(
588 QNapi::Object appQAbility, QNapi::Object want)
const
590 auto wantParameters = QNapi::getPropOrUndefined(want,
"parameters");
591 if (wantParameters.IsUndefined())
594 auto instanceIdParam = QNapi::getPropOrUndefined(wantParameters, qAbilityInstanceIdWantParamKey);
596 bool validInstanceId = isWantFromThisApp(appQAbility, want) && instanceIdParam.IsString();
598 return validInstanceId
599 ? makeQOhosOptional(QNapi::checkedCast<QNapi::String>(instanceIdParam).Utf8Value())
603std::string QAbilityInstancesManagerImpl::getQAbilityInstanceIdOrPendingAutoStartedId(QNapi::Object qAbility)
const
605 auto optInstanceId = tryGetQAbilityInstanceIdFromWant(
606 qAbility, qAbility.get<QNapi::Object>(
"launchWant"));
608 if (!optInstanceId.has_value() && !m_pendingAutoStartedInstanceId.has_value()) {
609 qOhosReportFatalErrorAndAbort(
610 "Got Ability without '%s' param and no pending auto-started instance",
611 qAbilityInstanceIdWantParamKey);
614 return optInstanceId.has_value()
615 ? optInstanceId.value()
616 : m_pendingAutoStartedInstanceId.value();
621 return m_abilityEngine;
624bool QAbilityInstancesManagerImpl::isWantFromThisApp(QNapi::Object appQAbility, QNapi::Object want)
const
626 auto wantParameters = QNapi::getPropOrUndefined(want,
"parameters");
627 if (wantParameters.IsUndefined())
630 auto callerAbilityNameParam = QNapi::getPropOrUndefined(wantParameters, callerAbilityNameWantParamKey);
631 auto callerBundleNameParam = QNapi::getPropOrUndefined(wantParameters, callerBundleNameWantParamKey);
633 auto appAbilityInfo = m_abilityEngine->readAbilityInfo(appQAbility);
636 callerAbilityNameParam.IsString()
637 && QNapi::checkedCast<QNapi::String>(callerAbilityNameParam).Utf8Value() == appAbilityInfo.name
638 && callerBundleNameParam.IsString()
639 && QNapi::checkedCast<QNapi::String>(callerBundleNameParam).Utf8Value() == appAbilityInfo.bundleName;
642QOhosOptional<std::string> QAbilityInstancesManagerImpl::pendingAutoStartedInstanceId()
const
644 return m_pendingAutoStartedInstanceId;
647void QAbilityInstancesManagerImpl::registerPendingAutoStartedInstance()
649 if (m_pendingAutoStartedInstanceId.has_value()) {
650 qOhosReportFatalErrorAndAbort(
651 "%s: pending auto-started instance already registered (id='%s')",
652 Q_FUNC_INFO, m_pendingAutoStartedInstanceId.value().c_str());
655 m_pendingAutoStartedInstanceId = m_abilityInstanceIdsGenerator();
658 "Registered pending auto-started Ability instance, id='%s'",
659 m_pendingAutoStartedInstanceId.value().c_str());
662void QAbilityInstancesManagerImpl::startNewInstance(
663 QNapi::Object baseQAbility, QObjectThreadSafeRef qwindow,
664 QNapi::Object optStartOptions,
670 bool sendWantFinished =
false;
673 void callNotifyIfReady(
JsState &jsState)
676 "%s: sendWantFinished=%s, startedAbilityPeer=%s",
678 if (sendWantFinished && optAbilityPeer)
679 startupNotifyFunc(jsState, optAbilityPeer);
683 auto context =
std::make_shared<Context>();
684 context->startupNotifyFunc =
std::move(startupNotifyFunc);
686 auto instanceId = m_abilityInstanceIdsGenerator();
688 InstanceStartParams startParams;
689 startParams.qwindow = qwindow;
691 context->optAbilityPeer = abilityPeer;
692 context->callNotifyIfReady(jsState);
694 m_pendingInstancesStartParams.emplace(instanceId, std::move(startParams));
696 sendWantToSelfQAbility(
697 m_abilityEngine, baseQAbility, optStartOptions, instanceId,
699 context->sendWantFinished =
true;
700 context->callNotifyIfReady(jsState);
704void QAbilityInstancesManagerImpl::handleStartedUiInstance(
705 JsState &jsState, QNapi::Object qAbility, QNapi::Object windowStage)
707 handleStartedInstance(
708 jsState, getQAbilityInstanceIdOrPendingAutoStartedId(qAbility),
709 [&](
const std::string &instanceId,
const InstanceStartParams &startParams) {
710 auto uiAbilityPeer =
std::make_shared<QUiAbilityPeerImpl>(
711 jsState, m_abilityEngine, instanceId, startParams.qwindow, qAbility, windowStage);
713 m_ownedUiAbilityPeers->emplace(uiAbilityPeerKey, uiAbilityPeer);
714 return makeSharedPtrWithAttachedExtraData(
717 [ownedUiAbilityPeers = m_ownedUiAbilityPeers, uiAbilityPeerKey]() {
718 ownedUiAbilityPeers->erase(uiAbilityPeerKey);
726 auto ownedPeerEntryIter = m_ownedUiAbilityPeers->find(uiAbilityPeer.get());
728 ownedPeerEntryIter != m_ownedUiAbilityPeers->end()
729 ? ownedPeerEntryIter->second.lock()
732 if (!ownedPeerImpl) {
733 qOhosReportFatalErrorAndAbort(
734 "%s: got unknown QUiAbilityPeer %p with id='%s'",
735 Q_FUNC_INFO, uiAbilityPeer.get(), uiAbilityPeer->instanceId().c_str());
738 return ownedPeerImpl;
741void QAbilityInstancesManagerImpl::handleStartedInstance(
742 JsState &jsState,
const std::string &abilityInstanceId,
743 const std::function<
std::shared_ptr<
QAbilityPeer>(
const std::string &,
const InstanceStartParams &)> &qAbilityPeerFactory)
745 auto startParamsIter = m_pendingInstancesStartParams.find(abilityInstanceId);
746 if (startParamsIter != m_pendingInstancesStartParams.end()) {
747 auto startParams =
std::move(startParamsIter->second);
748 m_pendingInstancesStartParams.erase(startParamsIter);
750 auto qAbilityPeer = qAbilityPeerFactory(abilityInstanceId, startParams);
752 startParams.startupNotifyFunc(jsState, qAbilityPeer);
753 }
else if (abilityInstanceId == m_pendingAutoStartedInstanceId) {
754 m_pendingAutoStartedInstanceId.reset();
756 InstanceStartParams startParams = {
757 .qwindow = QObjectThreadSafeRef(),
758 .startupNotifyFunc = [startupNotifyFunc = m_autoStartedInstanceStartupNotifyFunc](
JsState &jsState,
std::shared_ptr<
QAbilityPeer> qAbilityPeer) {
759 (*startupNotifyFunc)(jsState, qAbilityPeer);
762 auto qAbilityPeer = qAbilityPeerFactory(abilityInstanceId, startParams);
764 startParams.startupNotifyFunc(jsState, qAbilityPeer);
767 "%s: got unexpected started instance notification with id='%s', ignoring",
768 Q_FUNC_INFO, abilityInstanceId.c_str());
782 auto optWantParameters = QNapi::getOptionalPropOrEmpty<QNapi::Object>(want,
"parameters");
784 auto optCallerPid = QNapi::getOptionalPropOrEmpty<QNapi::Number>(
785 optWantParameters, callerPidWantParamKey);
786 auto optQtInternalRequestId = QNapi::getOptionalPropOrEmpty<QNapi::String>(
787 optWantParameters, qtInternalRequestIdWantParamKey);
789 std::int32_t thisProcessPid = ::getpid();
792 !optCallerPid.IsEmpty() && optCallerPid.Int32Value() == thisProcessPid
793 && !optQtInternalRequestId.IsEmpty()
794 && optQtInternalRequestId.Utf8Value() == getUtf8QtInternalRequestIdForThisProcess();
798 JsState &jsState, QNapi::Object ability, QNapi::Object launchParam)
800 ability.set(getAbilityLaunchParamPropSymbol(jsState), launchParam);
807 return std::make_shared<QAbilityInstancesManagerImpl>(abilityEngine,
std::move(autoStartedInstanceStartupNotifyFunc));
JsState & jsState() const
CloseAbilityRequestSource
CloseAbilityRequestResolution
Combined button and popup list for selecting options.
std::string const char * mapBoolToTrueFalseStr(bool value)
void invokeInJsThread(std::function< void(JsState &)> task)
std::shared_ptr< QAbilityInstancesManager > makeQAbilityInstancesManager(std::shared_ptr< QAbilityEngine > abilityEngine, std::function< void(JsState &, std::shared_ptr< QAbilityPeer >)> autoStartedInstanceStartupNotifyFunc)
enums::ohos::app::ability::AbilityConstant::OnContinueResult QOhosAbilityOnContinueResult
void addJsQAbilityPeer(std::shared_ptr< QAbilityPeer > qAbilityPeer)
std::nullopt_t makeEmptyQOhosOptional()
QAbilityInstancesManager()
virtual ~QAbilityInstancesManager()