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 "extension_record_manager.h"
17
18 #include "ability_util.h"
19 #include "hilog_wrapper.h"
20 #include "ui_extension_utils.h"
21 #include "ui_extension_record.h"
22
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26 constexpr const char* SEPARATOR = ":";
27 constexpr const char* DEFAULT_PROCESS_NAME = "UIExtension";
28 }
29 std::atomic_int32_t ExtensionRecordManager::extensionRecordId_ = INVALID_EXTENSION_RECORD_ID;
30
ExtensionRecordManager(const int32_t userId)31 ExtensionRecordManager::ExtensionRecordManager(const int32_t userId) : userId_(userId)
32 {
33 HILOG_DEBUG("constructor.");
34 }
35
~ExtensionRecordManager()36 ExtensionRecordManager::~ExtensionRecordManager()
37 {
38 HILOG_INFO("deconstructor.");
39 }
40
GenerateExtensionRecordId(const int32_t extensionRecordId)41 int32_t ExtensionRecordManager::GenerateExtensionRecordId(const int32_t extensionRecordId)
42 {
43 HILOG_DEBUG("Input id is %{public}d.", extensionRecordId);
44 std::lock_guard<std::mutex> lock(mutex_);
45 if (extensionRecordId != INVALID_EXTENSION_RECORD_ID &&
46 !extensionRecordIdSet_.count(extensionRecordId)) {
47 extensionRecordIdSet_.insert(extensionRecordId);
48 extensionRecordId_ = extensionRecordId;
49 return extensionRecordId_;
50 }
51
52 if (extensionRecordId == INVALID_EXTENSION_RECORD_ID) {
53 ++extensionRecordId_;
54 }
55
56 while (extensionRecordIdSet_.count(extensionRecordId_)) {
57 extensionRecordId_++;
58 }
59
60 return extensionRecordId_;
61 }
62
AddExtensionRecord(const int32_t extensionRecordId,const std::shared_ptr<ExtensionRecord> & record)63 void ExtensionRecordManager::AddExtensionRecord(const int32_t extensionRecordId,
64 const std::shared_ptr<ExtensionRecord> &record)
65 {
66 HILOG_DEBUG("extensionRecordId %{public}d.", extensionRecordId);
67 std::lock_guard<std::mutex> lock(mutex_);
68 extensionRecords_.emplace(extensionRecordId, record);
69 }
70
RemoveExtensionRecord(const int32_t extensionRecordId)71 void ExtensionRecordManager::RemoveExtensionRecord(const int32_t extensionRecordId)
72 {
73 HILOG_DEBUG("extensionRecordId %{public}d.", extensionRecordId);
74 std::lock_guard<std::mutex> lock(mutex_);
75 extensionRecords_.erase(extensionRecordId);
76 }
77
GetExtensionRecord(const int32_t extensionRecordId,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)78 int32_t ExtensionRecordManager::GetExtensionRecord(const int32_t extensionRecordId,
79 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
80 {
81 HILOG_DEBUG("extensionRecordId %{public}d.", extensionRecordId);
82 std::lock_guard<std::mutex> lock(mutex_);
83 // find target record firstly
84 auto it = extensionRecords_.find(extensionRecordId);
85 if (it != extensionRecords_.end() && it->second != nullptr) {
86 // check bundleName
87 HILOG_DEBUG("Stored host bundleName: %{public}s, input bundleName is %{public}s.",
88 it->second->hostBundleName_.c_str(), hostBundleName.c_str());
89 if (it->second->hostBundleName_ == hostBundleName) {
90 extensionRecord = it->second;
91 isLoaded = true;
92 return ERR_OK;
93 }
94 }
95 HILOG_DEBUG("Not found stored id %{public}d.", extensionRecordId);
96 extensionRecord = nullptr;
97 isLoaded = false;
98 return ERR_NULL_OBJECT;
99 }
100
IsBelongToManager(const AppExecFwk::AbilityInfo & abilityInfo)101 bool ExtensionRecordManager::IsBelongToManager(const AppExecFwk::AbilityInfo &abilityInfo)
102 {
103 // only support UIExtension now
104 return AAFwk::UIExtensionUtils::IsUIExtension(abilityInfo.extensionAbilityType);
105 }
106
GetOrCreateExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,bool & isLoaded)107 int32_t ExtensionRecordManager::GetOrCreateExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
108 const std::string &hostBundleName, std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, bool &isLoaded)
109 {
110 CHECK_POINTER_AND_RETURN(abilityRequest.sessionInfo, ERR_INVALID_VALUE);
111 abilityRecord = GetAbilityRecordBySessionInfo(abilityRequest.sessionInfo);
112 if (abilityRecord != nullptr) {
113 isLoaded = true;
114 return ERR_OK;
115 }
116 std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
117 int32_t ret = GetOrCreateExtensionRecordInner(abilityRequest, hostBundleName, extensionRecord, isLoaded);
118 if (ret != ERR_OK) {
119 return ret;
120 }
121 if (extensionRecord != nullptr) {
122 abilityRecord = extensionRecord->abilityRecord_;
123 }
124 return ERR_OK;
125 }
126
GetAbilityRecordBySessionInfo(const sptr<AAFwk::SessionInfo> & sessionInfo)127 std::shared_ptr<AAFwk::AbilityRecord> ExtensionRecordManager::GetAbilityRecordBySessionInfo(
128 const sptr<AAFwk::SessionInfo> &sessionInfo)
129 {
130 CHECK_POINTER_AND_RETURN(sessionInfo, nullptr);
131 if (sessionInfo->uiExtensionComponentId == INVALID_EXTENSION_RECORD_ID) {
132 HILOG_DEBUG("Extensionability id invalid or not configured.");
133 return nullptr;
134 }
135
136 std::lock_guard<std::mutex> lock(mutex_);
137 for (const auto& it : extensionRecords_) {
138 if (it.second == nullptr) {
139 continue;
140 }
141 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = it.second->abilityRecord_;
142 if (abilityRecord == nullptr) {
143 continue;
144 }
145 sptr<AAFwk::SessionInfo> recordSessionInfo = abilityRecord->GetSessionInfo();
146 if (recordSessionInfo == nullptr) {
147 continue;
148 }
149 if (recordSessionInfo->uiExtensionComponentId == sessionInfo->uiExtensionComponentId) {
150 HILOG_DEBUG("found record, uiExtensionComponentId: %{public}" PRIu64, sessionInfo->uiExtensionComponentId);
151 return abilityRecord;
152 }
153 }
154 return nullptr;
155 }
156
UpdateProcessName(const AAFwk::AbilityRequest & abilityRequest,std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord)157 void ExtensionRecordManager::UpdateProcessName(const AAFwk::AbilityRequest &abilityRequest,
158 std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord)
159 {
160 switch (abilityRequest.extensionProcessMode) {
161 case AppExecFwk::ExtensionProcessMode::INSTANCE: {
162 std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name
163 + SEPARATOR + std::to_string(abilityRecord->GetUIExtensionAbilityId());
164 abilityRecord->SetProcessName(process);
165 break;
166 }
167 case AppExecFwk::ExtensionProcessMode::TYPE: {
168 std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name;
169 abilityRecord->SetProcessName(process);
170 break;
171 }
172 default: // AppExecFwk::ExtensionProcessMode::UNDEFINED or AppExecFwk::ExtensionProcessMode::BUNDLE
173 // no need to update
174 break;
175 }
176 }
177
GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)178 int32_t ExtensionRecordManager::GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest &abilityRequest,
179 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
180 {
181 // factory pattern with ability request
182 if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
183 int32_t extensionRecordId = UIExtensionRecord::NeedReuse(abilityRequest);
184 if (extensionRecordId != INVALID_EXTENSION_RECORD_ID) {
185 HILOG_DEBUG("reuse record, id: %{public}d", extensionRecordId);
186 int32_t ret = GetExtensionRecord(extensionRecordId, hostBundleName, extensionRecord, isLoaded);
187 if (ret == ERR_OK) {
188 extensionRecord->Update(abilityRequest);
189 }
190 return ret;
191 }
192 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = AAFwk::AbilityRecord::CreateAbilityRecord(abilityRequest);
193 if (abilityRecord == nullptr) {
194 HILOG_ERROR("Failed to create ability record");
195 return ERR_NULL_OBJECT;
196 }
197 abilityRecord->SetOwnerMissionUserId(userId_);
198 int32_t ret = CreateExtensionRecord(abilityRecord, hostBundleName, extensionRecord, extensionRecordId);
199 if (ret != ERR_OK) {
200 HILOG_ERROR("Failed to create extension record, ret: %{public}d", ret);
201 return ret;
202 }
203 UpdateProcessName(abilityRequest, abilityRecord);
204 HILOG_DEBUG("extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
205 extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
206 isLoaded = false;
207 return ERR_OK;
208 }
209 return ERR_INVALID_VALUE;
210 }
211
StartAbility(const AAFwk::AbilityRequest & abilityRequest)212 int32_t ExtensionRecordManager::StartAbility(const AAFwk::AbilityRequest &abilityRequest)
213 {
214 return ERR_OK;
215 }
216
IsFocused(int32_t extensionRecordId,const sptr<IRemoteObject> & focusToken)217 bool ExtensionRecordManager::IsFocused(int32_t extensionRecordId, const sptr<IRemoteObject>& focusToken)
218 {
219 std::lock_guard<std::mutex> lock(mutex_);
220 sptr<IRemoteObject> rootCallerToken = GetRootCallerTokenLocked(extensionRecordId);
221 bool isFocused = rootCallerToken == focusToken;
222 HILOG_DEBUG("id: %{public}d isFocused: %{public}d.", extensionRecordId, isFocused);
223 return isFocused;
224 }
225
GetRootCallerTokenLocked(int32_t extensionRecordId)226 sptr<IRemoteObject> ExtensionRecordManager::GetRootCallerTokenLocked(int32_t extensionRecordId)
227 {
228 auto it = extensionRecords_.find(extensionRecordId);
229 if (it != extensionRecords_.end() && it->second != nullptr) {
230 sptr<IRemoteObject> rootCallerToken = it->second->GetRootCallerToken();
231 if (rootCallerToken != nullptr) {
232 return rootCallerToken;
233 }
234 if (!it->second->ContinueToGetCallerToken()) {
235 return it->second->GetCallToken();
236 }
237 auto callerToken = it->second->GetCallToken();
238 if (callerToken == nullptr) {
239 HILOG_ERROR("callerToken is null, id: %{public}d.", extensionRecordId);
240 return nullptr;
241 }
242 auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
243 if (callerAbilityRecord == nullptr) {
244 HILOG_ERROR("callerAbilityRecord is null, id: %{public}d.", extensionRecordId);
245 return nullptr;
246 }
247 if (callerAbilityRecord->GetUIExtensionAbilityId() == INVALID_EXTENSION_RECORD_ID) {
248 HILOG_DEBUG("update rootCallerToken, id: %{public}d.", extensionRecordId);
249 it->second->SetRootCallerToken(callerToken);
250 return callerToken;
251 }
252 rootCallerToken = GetRootCallerTokenLocked(callerAbilityRecord->GetUIExtensionAbilityId());
253 HILOG_DEBUG("update rootCallerToken, id: %{public}d.", extensionRecordId);
254 it->second->SetRootCallerToken(rootCallerToken);
255 return rootCallerToken;
256 }
257 HILOG_ERROR("Not found id %{public}d.", extensionRecordId);
258 return nullptr;
259 }
260
CreateExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,int32_t & extensionRecordId)261 int32_t ExtensionRecordManager::CreateExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord,
262 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, int32_t &extensionRecordId)
263 {
264 // factory pattern with ability request
265 if (abilityRecord == nullptr) {
266 HILOG_ERROR("abilityRecord is null");
267 return ERR_NULL_OBJECT;
268 }
269 extensionRecordId = GenerateExtensionRecordId(extensionRecordId);
270 if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
271 extensionRecord = std::make_shared<UIExtensionRecord>(abilityRecord, hostBundleName, extensionRecordId);
272 std::lock_guard<std::mutex> lock(mutex_);
273 HILOG_DEBUG("add UIExtension, id %{public}d.", extensionRecordId);
274 extensionRecords_[extensionRecordId] = extensionRecord;
275 abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
276 return ERR_OK;
277 }
278 return ERR_INVALID_VALUE;
279 }
280 } // namespace AbilityRuntime
281 } // namespace OHOS
282