1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "session_manager/include/extension_session_manager.h"
17
18 #include <ability_manager_client.h>
19 #include <hitrace_meter.h>
20
21 #include "session/host/include/extension_session.h"
22
23 namespace OHOS::Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" };
26 const std::string EXTENSION_SESSION_MANAGER_THREAD = "OS_ExtensionSessionManager";
27 } // namespace
28
ExtensionSessionManager()29 ExtensionSessionManager::ExtensionSessionManager()
30 {
31 taskScheduler_ = std::make_shared<TaskScheduler>(EXTENSION_SESSION_MANAGER_THREAD);
32 }
33
WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager)34 WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager)
35
36 sptr<AAFwk::SessionInfo> ExtensionSessionManager::SetAbilitySessionInfo(const sptr<ExtensionSession>& extSession)
37 {
38 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
39 if (!abilitySessionInfo) {
40 WLOGFE("abilitySessionInfo is nullptr");
41 return nullptr;
42 }
43 auto sessionInfo = extSession->GetSessionInfo();
44 sptr<ISession> iSession(extSession);
45 abilitySessionInfo->sessionToken = iSession->AsObject();
46 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
47 abilitySessionInfo->parentToken = sessionInfo.rootToken_;
48 abilitySessionInfo->persistentId = extSession->GetPersistentId();
49 abilitySessionInfo->realHostWindowId = sessionInfo.realParentId_;
50 abilitySessionInfo->isAsyncModalBinding = sessionInfo.isAsyncModalBinding_;
51 abilitySessionInfo->uiExtensionUsage = static_cast<AAFwk::UIExtensionUsage>(sessionInfo.uiExtensionUsage_);
52 abilitySessionInfo->parentWindowType = sessionInfo.parentWindowType_;
53 if (sessionInfo.want != nullptr) {
54 abilitySessionInfo->want = *sessionInfo.want;
55 }
56 return abilitySessionInfo;
57 }
58
RequestExtensionSession(const SessionInfo & sessionInfo)59 sptr<ExtensionSession> ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo)
60 {
61 auto task = [this, sessionInfo]() {
62 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "RequestExtensionSession");
63 sptr<ExtensionSession> extensionSession = new ExtensionSession(sessionInfo);
64 extensionSession->SetEventHandler(taskScheduler_->GetEventHandler(), nullptr);
65 auto persistentId = extensionSession->GetPersistentId();
66 WLOGFI("persistentId: %{public}d, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
67 persistentId, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
68 sessionInfo.abilityName_.c_str());
69 extensionSessionMap_.insert({ persistentId, extensionSession });
70 return extensionSession;
71 };
72
73 return taskScheduler_->PostSyncTask(task, "RequestExtensionSession");
74 }
75
RequestExtensionSessionActivation(const sptr<ExtensionSession> & extensionSession,uint32_t hostWindowId,const std::function<void (WSError)> && resultCallback)76 WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr<ExtensionSession>& extensionSession,
77 uint32_t hostWindowId, const std::function<void(WSError)>&& resultCallback)
78 {
79 wptr<ExtensionSession> weakExtSession(extensionSession);
80 auto task = [this, weakExtSession, hostWindowId, callback = std::move(resultCallback)]() {
81 auto extSession = weakExtSession.promote();
82 if (extSession == nullptr) {
83 WLOGFE("session is nullptr");
84 return WSError::WS_ERROR_NULLPTR;
85 }
86 auto persistentId = extSession->GetPersistentId();
87 WLOGFI("Activate session with persistentId: %{public}d", persistentId);
88 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionActivation");
89 if (extensionSessionMap_.count(persistentId) == 0) {
90 WLOGFE("RequestExtensionSessionActivation Session is invalid! persistentId:%{public}d", persistentId);
91 return WSError::WS_ERROR_INVALID_SESSION;
92 }
93 auto extSessionInfo = SetAbilitySessionInfo(extSession);
94 if (extSessionInfo == nullptr) {
95 return WSError::WS_ERROR_NULLPTR;
96 }
97 extSessionInfo->hostWindowId = hostWindowId;
98 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(extSessionInfo,
99 AAFwk::DEFAULT_INVAL_VALUE);
100 if (callback) {
101 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED;
102 callback(ret);
103 return ret;
104 }
105 return WSError::WS_OK;
106 };
107 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation");
108 return WSError::WS_OK;
109 }
110
RequestExtensionSessionBackground(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)111 WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession,
112 const std::function<void(WSError)>&& resultCallback)
113 {
114 wptr<ExtensionSession> weakExtSession(extensionSession);
115 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
116 auto extSession = weakExtSession.promote();
117 if (extSession == nullptr) {
118 WLOGFE("session is nullptr");
119 return WSError::WS_ERROR_NULLPTR;
120 }
121 auto persistentId = extSession->GetPersistentId();
122 WLOGFI("Background session with persistentId: %{public}d", persistentId);
123 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground");
124 extSession->SetActive(false);
125 extSession->Background();
126 if (extensionSessionMap_.count(persistentId) == 0) {
127 WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId);
128 return WSError::WS_ERROR_INVALID_SESSION;
129 }
130 auto extSessionInfo = SetAbilitySessionInfo(extSession);
131 if (!extSessionInfo) {
132 return WSError::WS_ERROR_NULLPTR;
133 }
134 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo);
135 if (callback) {
136 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED;
137 callback(ret);
138 return ret;
139 }
140 return WSError::WS_OK;
141 };
142 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground");
143 return WSError::WS_OK;
144 }
145
RequestExtensionSessionDestruction(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)146 WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession,
147 const std::function<void(WSError)>&& resultCallback)
148 {
149 wptr<ExtensionSession> weakExtSession(extensionSession);
150 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
151 auto extSession = weakExtSession.promote();
152 if (extSession == nullptr) {
153 WLOGFE("session is nullptr");
154 return WSError::WS_ERROR_NULLPTR;
155 }
156 auto persistentId = extSession->GetPersistentId();
157 WLOGFI("Destroy session with persistentId: %{public}d", persistentId);
158 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction");
159 extSession->Disconnect();
160 if (extensionSessionMap_.count(persistentId) == 0) {
161 WLOGFE("RequestExtensionSessionDestruction Session is invalid! persistentId:%{public}d", persistentId);
162 return WSError::WS_ERROR_INVALID_SESSION;
163 }
164 auto extSessionInfo = SetAbilitySessionInfo(extSession);
165 if (!extSessionInfo) {
166 return WSError::WS_ERROR_NULLPTR;
167 }
168 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
169 extensionSessionMap_.erase(persistentId);
170 if (callback) {
171 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED;
172 callback(ret);
173 return ret;
174 }
175 return WSError::WS_OK;
176 };
177 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction");
178 return WSError::WS_OK;
179 }
180
RequestExtensionSessionDestructionDone(const sptr<ExtensionSession> & extensionSession)181 WSError ExtensionSessionManager::RequestExtensionSessionDestructionDone(const sptr<ExtensionSession>& extensionSession)
182 {
183 const char* const where = __func__;
184 auto task = [this, where, weakExtSession = wptr<ExtensionSession>(extensionSession)] {
185 auto extSession = weakExtSession.promote();
186 if (extSession == nullptr) {
187 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is nullptr", where);
188 return;
189 }
190 auto persistentId = extSession->GetPersistentId();
191 TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session done with persistentId: %{public}d", persistentId);
192 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:%{public}s", where);
193 if (extensionSessionMap_.count(persistentId) == 0) {
194 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is invalid! persistentId: %{public}d",
195 where, persistentId);
196 return;
197 }
198 auto extSessionInfo = SetAbilitySessionInfo(extSession);
199 if (!extSessionInfo) {
200 return;
201 }
202 AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
203 extensionSessionMap_.erase(persistentId);
204 };
205 taskScheduler_->PostAsyncTask(task, __func__);
206 return WSError::WS_OK;
207 }
208 } // namespace OHOS::Rosen
209