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 "display_info.h"
22 #include "display_manager.h"
23 #include "singleton_container.h"
24
25 #include "session/host/include/extension_session.h"
26
27 namespace OHOS::Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "ExtensionSessionManager" };
30 const std::string EXTENSION_SESSION_MANAGER_THREAD = "OS_ExtensionSessionManager";
31 } // namespace
32
ExtensionSessionManager()33 ExtensionSessionManager::ExtensionSessionManager()
34 {
35 taskScheduler_ = std::make_shared<TaskScheduler>(EXTENSION_SESSION_MANAGER_THREAD);
36 }
37
38 WM_IMPLEMENT_SINGLE_INSTANCE(ExtensionSessionManager)
39
SetAbilitySessionInfo(const sptr<ExtensionSession>& extSession)40 sptr<AAFwk::SessionInfo> ExtensionSessionManager::SetAbilitySessionInfo(const sptr<ExtensionSession>& extSession)
41 {
42 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
43 if (!abilitySessionInfo) {
44 WLOGFE("abilitySessionInfo is nullptr");
45 return nullptr;
46 }
47 auto sessionInfo = extSession->GetSessionInfo();
48 sptr<ISession> iSession(extSession);
49 abilitySessionInfo->sessionToken = iSession->AsObject();
50 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
51 abilitySessionInfo->parentToken = sessionInfo.rootToken_;
52 abilitySessionInfo->persistentId = extSession->GetPersistentId();
53 abilitySessionInfo->realHostWindowId = sessionInfo.realParentId_;
54 abilitySessionInfo->isAsyncModalBinding = sessionInfo.isAsyncModalBinding_;
55 abilitySessionInfo->uiExtensionUsage = static_cast<AAFwk::UIExtensionUsage>(sessionInfo.uiExtensionUsage_);
56 abilitySessionInfo->parentWindowType = sessionInfo.parentWindowType_;
57 abilitySessionInfo->displayId = sessionInfo.config_.displayId_;
58 abilitySessionInfo->density = sessionInfo.config_.density_;
59 abilitySessionInfo->orientation = sessionInfo.config_.orientation_;
60 if (sessionInfo.want != nullptr) {
61 abilitySessionInfo->want = *sessionInfo.want;
62 }
63 return abilitySessionInfo;
64 }
65
GetSystemDensity(uint64_t displayId)66 float ExtensionSessionManager::GetSystemDensity(uint64_t displayId)
67 {
68 float vpr = 1.0f;
69 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
70 if (display == nullptr) {
71 TLOGE(WmsLogTag::WMS_UIEXT, "display is null");
72 return vpr;
73 }
74 auto displayInfo = display->GetDisplayInfo();
75 if (displayInfo == nullptr) {
76 TLOGE(WmsLogTag::WMS_UIEXT, "displayInfo is null");
77 return vpr;
78 }
79 return displayInfo->GetVirtualPixelRatio();
80 }
81
RequestExtensionSession(const SessionInfo& sessionInfo)82 sptr<ExtensionSession> ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo)
83 {
84 auto task = [this, sessionInfo]() {
85 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "RequestExtensionSession");
86 SessionInfo tempSessionInfo = sessionInfo;
87 if (!tempSessionInfo.config_.isDensityFollowHost_) {
88 tempSessionInfo.config_.density_ = GetSystemDensity(tempSessionInfo.config_.displayId_);
89 }
90 sptr<ExtensionSession> extensionSession = new ExtensionSession(tempSessionInfo);
91 extensionSession->SetEventHandler(taskScheduler_->GetEventHandler(), nullptr);
92 auto persistentId = extensionSession->GetPersistentId();
93 TLOGI(WmsLogTag::WMS_UIEXT,
94 "persistentId: %{public}d, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, "
95 "isDensityFollowHost_: %{public}d, density_: %{public}f",
96 persistentId, tempSessionInfo.bundleName_.c_str(), tempSessionInfo.moduleName_.c_str(),
97 tempSessionInfo.abilityName_.c_str(), tempSessionInfo.config_.isDensityFollowHost_,
98 tempSessionInfo.config_.density_);
99 extensionSessionMap_.insert({ persistentId, extensionSession });
100 return extensionSession;
101 };
102
103 return taskScheduler_->PostSyncTask(task, "RequestExtensionSession");
104 }
105
RequestExtensionSessionActivation(const sptr<ExtensionSession>& extensionSession, uint32_t hostWindowId, const std::function<void(WSError)>&& resultCallback)106 WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr<ExtensionSession>& extensionSession,
107 uint32_t hostWindowId, const std::function<void(WSError)>&& resultCallback)
108 {
109 wptr<ExtensionSession> weakExtSession(extensionSession);
110 auto task = [this, weakExtSession, hostWindowId, callback = std::move(resultCallback)]() {
111 auto extSession = weakExtSession.promote();
112 if (extSession == nullptr) {
113 WLOGFE("session is nullptr");
114 return WSError::WS_ERROR_NULLPTR;
115 }
116 auto persistentId = extSession->GetPersistentId();
117 WLOGFI("Activate session with persistentId: %{public}d", persistentId);
118 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionActivation");
119 if (extensionSessionMap_.count(persistentId) == 0) {
120 WLOGFE("RequestExtensionSessionActivation Session is invalid! persistentId:%{public}d", persistentId);
121 return WSError::WS_ERROR_INVALID_SESSION;
122 }
123 auto extSessionInfo = SetAbilitySessionInfo(extSession);
124 if (extSessionInfo == nullptr) {
125 return WSError::WS_ERROR_NULLPTR;
126 }
127 extSessionInfo->hostWindowId = hostWindowId;
128 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(extSessionInfo,
129 AAFwk::DEFAULT_INVAL_VALUE);
130 if (callback) {
131 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED;
132 callback(ret);
133 return ret;
134 }
135 return WSError::WS_OK;
136 };
137 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation");
138 return WSError::WS_OK;
139 }
140
RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession, const std::function<void(WSError)>&& resultCallback)141 WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession,
142 const std::function<void(WSError)>&& resultCallback)
143 {
144 wptr<ExtensionSession> weakExtSession(extensionSession);
145 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
146 auto extSession = weakExtSession.promote();
147 if (extSession == nullptr) {
148 WLOGFE("session is nullptr");
149 return WSError::WS_ERROR_NULLPTR;
150 }
151 auto persistentId = extSession->GetPersistentId();
152 WLOGFI("Background session with persistentId: %{public}d", persistentId);
153 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground");
154 extSession->SetActive(false);
155 extSession->Background();
156 if (extensionSessionMap_.count(persistentId) == 0) {
157 WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId);
158 return WSError::WS_ERROR_INVALID_SESSION;
159 }
160 auto extSessionInfo = SetAbilitySessionInfo(extSession);
161 if (!extSessionInfo) {
162 return WSError::WS_ERROR_NULLPTR;
163 }
164 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo);
165 if (callback) {
166 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED;
167 callback(ret);
168 return ret;
169 }
170 return WSError::WS_OK;
171 };
172 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground");
173 return WSError::WS_OK;
174 }
175
RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession, const std::function<void(WSError)>&& resultCallback)176 WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession,
177 const std::function<void(WSError)>&& resultCallback)
178 {
179 wptr<ExtensionSession> weakExtSession(extensionSession);
180 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
181 auto extSession = weakExtSession.promote();
182 if (extSession == nullptr) {
183 WLOGFE("session is nullptr");
184 return WSError::WS_ERROR_NULLPTR;
185 }
186 auto persistentId = extSession->GetPersistentId();
187 WLOGFI("Destroy session with persistentId: %{public}d", persistentId);
188 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction");
189 extSession->Disconnect();
190 if (extensionSessionMap_.count(persistentId) == 0) {
191 WLOGFE("RequestExtensionSessionDestruction Session is invalid! persistentId:%{public}d", persistentId);
192 return WSError::WS_ERROR_INVALID_SESSION;
193 }
194 auto extSessionInfo = SetAbilitySessionInfo(extSession);
195 if (!extSessionInfo) {
196 return WSError::WS_ERROR_NULLPTR;
197 }
198 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
199 extensionSessionMap_.erase(persistentId);
200 if (callback) {
201 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED;
202 callback(ret);
203 return ret;
204 }
205 return WSError::WS_OK;
206 };
207 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction");
208 return WSError::WS_OK;
209 }
210
RequestExtensionSessionDestructionDone(const sptr<ExtensionSession>& extensionSession)211 WSError ExtensionSessionManager::RequestExtensionSessionDestructionDone(const sptr<ExtensionSession>& extensionSession)
212 {
213 const char* const where = __func__;
214 auto task = [this, where, weakExtSession = wptr<ExtensionSession>(extensionSession)] {
215 auto extSession = weakExtSession.promote();
216 if (extSession == nullptr) {
217 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is nullptr", where);
218 return;
219 }
220 auto persistentId = extSession->GetPersistentId();
221 TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session done with persistentId: %{public}d", persistentId);
222 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:%{public}s", where);
223 if (extensionSessionMap_.count(persistentId) == 0) {
224 TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is invalid! persistentId: %{public}d",
225 where, persistentId);
226 return;
227 }
228 auto extSessionInfo = SetAbilitySessionInfo(extSession);
229 if (!extSessionInfo) {
230 return;
231 }
232 AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
233 extensionSessionMap_.erase(persistentId);
234 };
235 taskScheduler_->PostAsyncTask(task, __func__);
236 return WSError::WS_OK;
237 }
238 } // namespace OHOS::Rosen
239