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