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