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 <mutex>
19
20 #include <ability_manager_client.h>
21 #include <hitrace_meter.h>
22 #include <session_info.h>
23 #include <start_options.h>
24
25 #include "session/host/include/extension_session.h"
26 #include "window_manager_hilog.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 std::recursive_mutex g_instanceMutex;
33 } // namespace
34
GetInstance()35 ExtensionSessionManager& ExtensionSessionManager::GetInstance()
36 {
37 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
38 static ExtensionSessionManager* instance = nullptr;
39 if (instance == nullptr) {
40 instance = new ExtensionSessionManager();
41 instance->Init();
42 }
43 return *instance;
44 }
45
Init()46 void ExtensionSessionManager::Init()
47 {
48 taskScheduler_ = std::make_shared<TaskScheduler>(EXTENSION_SESSION_MANAGER_THREAD);
49 }
50
SetAbilitySessionInfo(const sptr<ExtensionSession> & extSession)51 sptr<AAFwk::SessionInfo> ExtensionSessionManager::SetAbilitySessionInfo(const sptr<ExtensionSession>& extSession)
52 {
53 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
54 if (!abilitySessionInfo) {
55 WLOGFE("abilitySessionInfo is nullptr");
56 return nullptr;
57 }
58 auto sessionInfo = extSession->GetSessionInfo();
59 sptr<ISession> iSession(extSession);
60 abilitySessionInfo->sessionToken = iSession->AsObject();
61 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
62 abilitySessionInfo->parentToken = sessionInfo.rootToken_;
63 abilitySessionInfo->persistentId = extSession->GetPersistentId();
64 abilitySessionInfo->isAsyncModalBinding = sessionInfo.isAsyncModalBinding_;
65 if (sessionInfo.want != nullptr) {
66 abilitySessionInfo->want = *sessionInfo.want;
67 }
68 return abilitySessionInfo;
69 }
70
RequestExtensionSession(const SessionInfo & sessionInfo)71 sptr<ExtensionSession> ExtensionSessionManager::RequestExtensionSession(const SessionInfo& sessionInfo)
72 {
73 auto task = [this, sessionInfo]() {
74 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "RequestExtensionSession");
75 sptr<ExtensionSession> extensionSession = new ExtensionSession(sessionInfo);
76 auto persistentId = extensionSession->GetPersistentId();
77 WLOGFI("persistentId: %{public}d, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
78 persistentId, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
79 sessionInfo.abilityName_.c_str());
80 extensionSessionMap_.insert({ persistentId, extensionSession });
81 return extensionSession;
82 };
83
84 return taskScheduler_->PostSyncTask(task, "RequestExtensionSession");
85 }
86
RequestExtensionSessionActivation(const sptr<ExtensionSession> & extensionSession,uint32_t hostWindowId,const std::function<void (WSError)> && resultCallback)87 WSError ExtensionSessionManager::RequestExtensionSessionActivation(const sptr<ExtensionSession>& extensionSession,
88 uint32_t hostWindowId, const std::function<void(WSError)>&& resultCallback)
89 {
90 wptr<ExtensionSession> weakExtSession(extensionSession);
91 auto task = [this, weakExtSession, hostWindowId, callback = std::move(resultCallback)]() {
92 auto extSession = weakExtSession.promote();
93 if (extSession == nullptr) {
94 WLOGFE("session is nullptr");
95 return WSError::WS_ERROR_NULLPTR;
96 }
97 auto persistentId = extSession->GetPersistentId();
98 WLOGFI("Activate session with persistentId: %{public}d", persistentId);
99 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionActivation");
100 if (extensionSessionMap_.count(persistentId) == 0) {
101 WLOGFE("RequestExtensionSessionActivation Session is invalid! persistentId:%{public}d", persistentId);
102 return WSError::WS_ERROR_INVALID_SESSION;
103 }
104 auto extSessionInfo = SetAbilitySessionInfo(extSession);
105 if (extSessionInfo == nullptr) {
106 return WSError::WS_ERROR_NULLPTR;
107 }
108 extSessionInfo->hostWindowId = hostWindowId;
109 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIExtensionAbility(extSessionInfo,
110 AAFwk::DEFAULT_INVAL_VALUE);
111 if (callback) {
112 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_START_UI_EXTENSION_ABILITY_FAILED;
113 callback(ret);
114 return ret;
115 }
116 return WSError::WS_OK;
117 };
118 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionActivation");
119 return WSError::WS_OK;
120 }
121
RequestExtensionSessionBackground(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)122 WSError ExtensionSessionManager::RequestExtensionSessionBackground(const sptr<ExtensionSession>& extensionSession,
123 const std::function<void(WSError)>&& resultCallback)
124 {
125 wptr<ExtensionSession> weakExtSession(extensionSession);
126 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
127 auto extSession = weakExtSession.promote();
128 if (extSession == nullptr) {
129 WLOGFE("session is nullptr");
130 return WSError::WS_ERROR_NULLPTR;
131 }
132 auto persistentId = extSession->GetPersistentId();
133 WLOGFI("Background session with persistentId: %{public}d", persistentId);
134 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionBackground");
135 extSession->SetActive(false);
136 extSession->Background();
137 if (extensionSessionMap_.count(persistentId) == 0) {
138 WLOGFE("RequestExtensionSessionBackground Session is invalid! persistentId:%{public}d", persistentId);
139 return WSError::WS_ERROR_INVALID_SESSION;
140 }
141 auto extSessionInfo = SetAbilitySessionInfo(extSession);
142 if (!extSessionInfo) {
143 return WSError::WS_ERROR_NULLPTR;
144 }
145 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIExtensionAbility(extSessionInfo);
146 if (callback) {
147 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_MIN_UI_EXTENSION_ABILITY_FAILED;
148 callback(ret);
149 return ret;
150 }
151 return WSError::WS_OK;
152 };
153 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionBackground");
154 return WSError::WS_OK;
155 }
156
RequestExtensionSessionDestruction(const sptr<ExtensionSession> & extensionSession,const std::function<void (WSError)> && resultCallback)157 WSError ExtensionSessionManager::RequestExtensionSessionDestruction(const sptr<ExtensionSession>& extensionSession,
158 const std::function<void(WSError)>&& resultCallback)
159 {
160 wptr<ExtensionSession> weakExtSession(extensionSession);
161 auto task = [this, weakExtSession, callback = std::move(resultCallback)]() {
162 auto extSession = weakExtSession.promote();
163 if (extSession == nullptr) {
164 WLOGFE("session is nullptr");
165 return WSError::WS_ERROR_NULLPTR;
166 }
167 auto persistentId = extSession->GetPersistentId();
168 WLOGFI("Destroy session with persistentId: %{public}d", persistentId);
169 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "esm:RequestExtensionSessionDestruction");
170 extSession->Disconnect();
171 if (extensionSessionMap_.count(persistentId) == 0) {
172 WLOGFE("RequestExtensionSessionDestruction Session is invalid! persistentId:%{public}d", persistentId);
173 return WSError::WS_ERROR_INVALID_SESSION;
174 }
175 auto extSessionInfo = SetAbilitySessionInfo(extSession);
176 if (!extSessionInfo) {
177 return WSError::WS_ERROR_NULLPTR;
178 }
179 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->TerminateUIExtensionAbility(extSessionInfo);
180 extensionSessionMap_.erase(persistentId);
181 if (callback) {
182 auto ret = errorCode == ERR_OK ? WSError::WS_OK : WSError::WS_ERROR_TERMINATE_UI_EXTENSION_ABILITY_FAILED;
183 callback(ret);
184 return ret;
185 }
186 return WSError::WS_OK;
187 };
188 taskScheduler_->PostAsyncTask(task, "RequestExtensionSessionDestruction");
189 return WSError::WS_OK;
190 }
191 } // namespace OHOS::Rosen
192