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, newSessionInfo = sessionInfo]() mutable -> sptr<ExtensionSession> {
62 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "RequestExtensionSession");
63 sptr<ExtensionSession> extensionSession = sptr<ExtensionSession>::MakeSptr(newSessionInfo);
64 extensionSession->SetEventHandler(taskScheduler_->GetEventHandler(), nullptr);
65 auto persistentId = extensionSession->GetPersistentId();
66 TLOGNI(WmsLogTag::WMS_UIEXT,
67 "persistentId: %{public}d, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
68 persistentId, newSessionInfo.bundleName_.c_str(), newSessionInfo.moduleName_.c_str(),
69 newSessionInfo.abilityName_.c_str());
70 if (persistentId == INVALID_SESSION_ID) {
71 return nullptr;
72 }
73 extensionSessionMap_.insert({ persistentId, extensionSession });
74 return extensionSession;
75 };
76
77 return taskScheduler_->PostSyncTask(task, "RequestExtensionSession");
78 }
79
RequestExtensionSessionActivation(const sptr<ExtensionSession> & extensionSession,uint32_t hostWindowId,const std::function<void (WSError)> && resultCallback)80 WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr<ExtensionSession>& extensionSession,
81 uint32_t hostWindowId, const std::function<void(WSError)>&& resultCallback)
82 {
83 wptr<ExtensionSession> weakExtSession(extensionSession);
84 auto task = [this, weakExtSession, hostWindowId, callback = std::move(resultCallback)]() {
85 auto extSession = weakExtSession.promote();
86 if (extSession == nullptr) {
87 WLOGFE("session is nullptr");
88 return WSError::WS_ERROR_NULLPTR;
89 }
90 auto persistentId = extSession->GetPersistentId();
91 WLOGFI("Activate session with persistentId: %{public}d", persistentId);
92 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionActivation");
93 if (extensionSessionMap_.count(persistentId) == 0) {
94 WLOGFE("RequestExtensionSessionActivation Session is invalid! persistentId:%{public}d", persistentId);
95 return WSError::WS_ERROR_INVALID_SESSION;
96 }
97 auto extSessionInfo = SetAbilitySessionInfo(extSession);
98 if (extSessionInfo == nullptr) {
99 return WSError::WS_ERROR_NULLPTR;
100 }
101 extSessionInfo->hostWindowId = hostWindowId;
102 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(extSessionInfo,
103 AAFwk::DEFAULT_INVAL_VALUE);
104 TLOGNI(WmsLogTag::WMS_UIEXT, "Activate ret:%{public}d, persistentId:%{public}d", errorCode, persistentId);
105 if (callback) {
106 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED;
107 callback(ret);
108 return ret;
109 }
110 return WSError::WS_OK;
111 };
112 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation");
113 return WSError::WS_OK;
114 }
115
RequestExtensionSessionBackground(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)116 WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession,
117 const std::function<void(WSError)>&& resultCallback)
118 {
119 wptr<ExtensionSession> weakExtSession(extensionSession);
120 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
121 auto extSession = weakExtSession.promote();
122 if (extSession == nullptr) {
123 WLOGFE("session is nullptr");
124 return WSError::WS_ERROR_NULLPTR;
125 }
126 auto persistentId = extSession->GetPersistentId();
127 WLOGFI("Background session with persistentId: %{public}d", persistentId);
128 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground");
129 extSession->SetActive(false);
130 extSession->Background();
131 if (extensionSessionMap_.count(persistentId) == 0) {
132 WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId);
133 return WSError::WS_ERROR_INVALID_SESSION;
134 }
135 auto extSessionInfo = SetAbilitySessionInfo(extSession);
136 if (!extSessionInfo) {
137 return WSError::WS_ERROR_NULLPTR;
138 }
139 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo);
140 if (callback) {
141 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED;
142 callback(ret);
143 return ret;
144 }
145 return WSError::WS_OK;
146 };
147 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground");
148 return WSError::WS_OK;
149 }
150
RequestExtensionSessionDestruction(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)151 WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession,
152 const std::function<void(WSError)>&& resultCallback)
153 {
154 wptr<ExtensionSession> weakExtSession(extensionSession);
155 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
156 auto extSession = weakExtSession.promote();
157 if (extSession == nullptr) {
158 WLOGFE("session is nullptr");
159 return WSError::WS_ERROR_NULLPTR;
160 }
161 auto persistentId = extSession->GetPersistentId();
162 WLOGFI("Destroy session with persistentId: %{public}d", persistentId);
163 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction");
164 extSession->Disconnect();
165 if (extensionSessionMap_.count(persistentId) == 0) {
166 WLOGFE("RequestExtensionSessionDestruction Session is invalid! persistentId:%{public}d", persistentId);
167 return WSError::WS_ERROR_INVALID_SESSION;
168 }
169 auto extSessionInfo = SetAbilitySessionInfo(extSession);
170 if (!extSessionInfo) {
171 return WSError::WS_ERROR_NULLPTR;
172 }
173 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
174 extensionSessionMap_.erase(persistentId);
175 if (callback) {
176 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED;
177 callback(ret);
178 return ret;
179 }
180 return WSError::WS_OK;
181 };
182 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction");
183 return WSError::WS_OK;
184 }
185
RequestExtensionSessionDestructionDone(const sptr<ExtensionSession> & extensionSession)186 WSError ExtensionSessionManager::RequestExtensionSessionDestructionDone(const sptr<ExtensionSession>& extensionSession)
187 {
188 const char* const where = __func__;
189 auto task = [this, where, weakExtSession = wptr<ExtensionSession>(extensionSession)] {
190 auto extSession = weakExtSession.promote();
191 if (extSession == nullptr) {
192 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is nullptr", where);
193 return;
194 }
195 auto persistentId = extSession->GetPersistentId();
196 TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session done with persistentId: %{public}d", persistentId);
197 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:%{public}s", where);
198 if (extensionSessionMap_.count(persistentId) == 0) {
199 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is invalid! persistentId: %{public}d",
200 where, persistentId);
201 return;
202 }
203 auto extSessionInfo = SetAbilitySessionInfo(extSession);
204 if (!extSessionInfo) {
205 return;
206 }
207 AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
208 extensionSessionMap_.erase(persistentId);
209 };
210 taskScheduler_->PostAsyncTask(task, __func__);
211 return WSError::WS_OK;
212 }
213 } // namespace OHOS::Rosen
214