• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.GetWantSafely();
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, id=%{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 bundleName: " << extSession->GetSessionInfo().bundleName_ << ",";
136             oss << " provider abilityName: " << extSession->GetSessionInfo().abilityName_ << ",";
137             oss << " errorCode: " << errorCode << ";";
138             int32_t ret = WindowInfoReporter::GetInstance().ReportUIExtensionException(
139                 static_cast<int32_t>(WindowDFXHelperType::WINDOW_UIEXTENSION_START_ABILITY_FAIL),
140                 getpid(), persistentId, oss.str()
141             );
142             if (ret != 0) {
143                 TLOGNE(WmsLogTag::WMS_UIEXT, "ReportUIExtensionException message failed, ret: %{public}d", ret);
144             }
145         }
146         if (callback) {
147             auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED;
148             callback(ret);
149             return ret;
150         }
151         return WSError::WS_OK;
152     };
153     taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation");
154     return WSError::WS_OK;
155 }
156 
RequestExtensionSessionBackground(const sptr<ExtensionSession> & extensionSession,std::function<void (WSError)> && resultCallback)157 WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession,
158     std::function<void(WSError)>&& resultCallback)
159 {
160     auto abilitySessionInfo = SetAbilitySessionInfo(extensionSession);
161     wptr<ExtensionSession> weakExtSession(extensionSession);
162     auto task = [this, weakExtSession, callback = std::move(resultCallback),
163         extSessionInfo = std::move(abilitySessionInfo)]() {
164         auto extSession = weakExtSession.promote();
165         if (extSession == nullptr) {
166             WLOGFE("session is nullptr");
167             return WSError::WS_ERROR_NULLPTR;
168         }
169         auto persistentId = extSession->GetPersistentId();
170         TLOGNI(WmsLogTag::WMS_UIEXT, "Background session, id=%{public}d", persistentId);
171         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground");
172         extSession->SetActive(false);
173         extSession->Background();
174         if (IsExtensionSessionInvalid(persistentId)) {
175             WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId);
176             return WSError::WS_ERROR_INVALID_SESSION;
177         }
178         auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo);
179         if (callback) {
180             auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED;
181             callback(ret);
182             return ret;
183         }
184         return WSError::WS_OK;
185     };
186     taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground");
187     return WSError::WS_OK;
188 }
189 
RequestExtensionSessionDestruction(const sptr<ExtensionSession> & extensionSession,std::function<void (WSError)> && resultCallback)190 WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession,
191     std::function<void(WSError)>&& resultCallback)
192 {
193     auto abilitySessionInfo = SetAbilitySessionInfo(extensionSession);
194     wptr<ExtensionSession> weakExtSession(extensionSession);
195     auto task = [this, weakExtSession, callback = std::move(resultCallback),
196         extSessionInfo = std::move(abilitySessionInfo), where = __func__]() NO_THREAD_SAFETY_ANALYSIS {
197         auto extSession = weakExtSession.promote();
198         if (extSession == nullptr) {
199             TLOGNE(WmsLogTag::WMS_UIEXT, "session is nullptr");
200             return WSError::WS_ERROR_NULLPTR;
201         }
202         auto persistentId = extSession->GetPersistentId();
203         TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session with persistentId: %{public}d", persistentId);
204         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction");
205         extSession->Disconnect();
206         if (IsExtensionSessionInvalid(persistentId)) {
207             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s Session is invalid! persistentId:%{public}d",
208                 where, persistentId);
209             return WSError::WS_ERROR_INVALID_SESSION;
210         }
211         auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
212         if (callback) {
213             auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED;
214             callback(ret);
215             return ret;
216         }
217         return WSError::WS_OK;
218     };
219     taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction");
220     return WSError::WS_OK;
221 }
222 
RequestExtensionSessionDestructionDone(const sptr<ExtensionSession> & extensionSession)223 WSError ExtensionSessionManager::RequestExtensionSessionDestructionDone(const sptr<ExtensionSession>& extensionSession)
224 {
225     const char* const where = __func__;
226     auto abilitySessionInfo = SetAbilitySessionInfo(extensionSession);
227     auto task = [this, where, weakExtSession = wptr<ExtensionSession>(extensionSession),
228         extSessionInfo = std::move(abilitySessionInfo)] {
229         auto extSession = weakExtSession.promote();
230         if (extSession == nullptr) {
231             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is nullptr", where);
232             return;
233         }
234         auto persistentId = extSession->GetPersistentId();
235         TLOGNI(WmsLogTag::WMS_UIEXT, "Destroy session done with persistentId: %{public}d", persistentId);
236         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:%{public}s", where);
237         if (IsExtensionSessionInvalid(persistentId)) {
238             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s session is invalid! persistentId: %{public}d",
239                 where, persistentId);
240             return;
241         }
242         AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
243     };
244     taskScheduler_->PostAsyncTask(task, __func__);
245     return WSError::WS_OK;
246 }
247 } // namespace OHOS::Rosen
248