/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "session_manager/include/extension_session_manager.h" #include #include #include "session/host/include/extension_session.h" namespace OHOS::Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" }; const std::string EXTENSION_SESSION_MANAGER_THREAD = "OS_ExtensionSessionManager"; } // namespace ExtensionSessionManager::ExtensionSessionManager() { taskScheduler_ = std::make_shared(EXTENSION_SESSION_MANAGER_THREAD); } WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager) sptr ExtensionSessionManager::SetAbilitySessionInfo(const sptr& extSession) { sptr abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo(); if (!abilitySessionInfo) { WLOGFE("abilitySessionInfo is nullptr"); return nullptr; } auto sessionInfo = extSession->GetSessionInfo(); sptr iSession(extSession); abilitySessionInfo->sessionToken = iSession->AsObject(); abilitySessionInfo->callerToken = sessionInfo.callerToken_; abilitySessionInfo->parentToken = sessionInfo.rootToken_; abilitySessionInfo->persistentId = extSession->GetPersistentId(); abilitySessionInfo->realHostWindowId = sessionInfo.realParentId_; abilitySessionInfo->isAsyncModalBinding = sessionInfo.isAsyncModalBinding_; abilitySessionInfo->uiExtensionUsage = static_cast(sessionInfo.uiExtensionUsage_); abilitySessionInfo->parentWindowType = sessionInfo.parentWindowType_; if (sessionInfo.want != nullptr) { abilitySessionInfo->want = *sessionInfo.want; } return abilitySessionInfo; } sptr ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo) { auto task = [this, sessionInfo]() { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "RequestExtensionSession"); sptr extensionSession = new ExtensionSession(sessionInfo); extensionSession->SetEventHandler(taskScheduler_->GetEventHandler(), nullptr); auto persistentId = extensionSession->GetPersistentId(); WLOGFI("persistentId: %{public}d, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s", persistentId, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str()); extensionSessionMap_.insert({ persistentId, extensionSession }); return extensionSession; }; return taskScheduler_->PostSyncTask(task, "RequestExtensionSession"); } WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr& extensionSession, uint32_t hostWindowId, const std::function&& resultCallback) { wptr weakExtSession(extensionSession); auto task = [this, weakExtSession, hostWindowId, callback = std::move(resultCallback)]() { auto extSession = weakExtSession.promote(); if (extSession == nullptr) { WLOGFE("session is nullptr"); return WSError::WS_ERROR_NULLPTR; } auto persistentId = extSession->GetPersistentId(); WLOGFI("Activate session with persistentId: %{public}d", persistentId); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionActivation"); if (extensionSessionMap_.count(persistentId) == 0) { WLOGFE("RequestExtensionSessionActivation Session is invalid! persistentId:%{public}d", persistentId); return WSError::WS_ERROR_INVALID_SESSION; } auto extSessionInfo = SetAbilitySessionInfo(extSession); if (extSessionInfo == nullptr) { return WSError::WS_ERROR_NULLPTR; } extSessionInfo->hostWindowId = hostWindowId; auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(extSessionInfo, AAFwk::DEFAULT_INVAL_VALUE); if (callback) { auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED; callback(ret); return ret; } return WSError::WS_OK; }; taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation"); return WSError::WS_OK; } WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr& extensionSession, const std::function&& resultCallback) { wptr weakExtSession(extensionSession); auto task = [this, weakExtSession, callback = std::move(resultCallback)]() { auto extSession = weakExtSession.promote(); if (extSession == nullptr) { WLOGFE("session is nullptr"); return WSError::WS_ERROR_NULLPTR; } auto persistentId = extSession->GetPersistentId(); WLOGFI("Background session with persistentId: %{public}d", persistentId); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground"); extSession->SetActive(false); extSession->Background(); if (extensionSessionMap_.count(persistentId) == 0) { WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId); return WSError::WS_ERROR_INVALID_SESSION; } auto extSessionInfo = SetAbilitySessionInfo(extSession); if (!extSessionInfo) { return WSError::WS_ERROR_NULLPTR; } auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo); if (callback) { auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED; callback(ret); return ret; } return WSError::WS_OK; }; taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground"); return WSError::WS_OK; } WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr& extensionSession, const std::function&& resultCallback) { wptr weakExtSession(extensionSession); auto task = [this, weakExtSession, callback = std::move(resultCallback)]() { auto extSession = weakExtSession.promote(); if (extSession == nullptr) { WLOGFE("session is nullptr"); return WSError::WS_ERROR_NULLPTR; } auto persistentId = extSession->GetPersistentId(); WLOGFI("Destroy session with persistentId: %{public}d", persistentId); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction"); extSession->Disconnect(); if (extensionSessionMap_.count(persistentId) == 0) { WLOGFE("RequestExtensionSessionDestruction Session is invalid! persistentId:%{public}d", persistentId); return WSError::WS_ERROR_INVALID_SESSION; } auto extSessionInfo = SetAbilitySessionInfo(extSession); if (!extSessionInfo) { return WSError::WS_ERROR_NULLPTR; } auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo); extensionSessionMap_.erase(persistentId); if (callback) { auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED; callback(ret); return ret; } return WSError::WS_OK; }; taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction"); return WSError::WS_OK; } WSError ExtensionSessionManager::RequestExtensionSessionDestructionDone(const sptr& extensionSession) { const char* const where = __func__; auto task = [this, where, weakExtSession = wptr(extensionSession)] { auto extSession = weakExtSession.promote(); if (extSession == nullptr) { TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is nullptr", where); return; } auto persistentId = extSession->GetPersistentId(); TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session done with persistentId: %{public}d", persistentId); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:%{public}s", where); if (extensionSessionMap_.count(persistentId) == 0) { TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is invalid! persistentId: %{public}d", where, persistentId); return; } auto extSessionInfo = SetAbilitySessionInfo(extSession); if (!extSessionInfo) { return; } AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo); extensionSessionMap_.erase(persistentId); }; taskScheduler_->PostAsyncTask(task, __func__); return WSError::WS_OK; } } // namespace OHOS::Rosen