• 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 "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