1 /*
2 * Copyright (c) 2023-2025 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 "ui_extension_utils.h"
20 #include "ui_extension_record.h"
21 #include "ui_extension_record_factory.h"
22
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26 constexpr const char *SEPARATOR = ":";
27 const std::string IS_PRELOAD_UIEXTENSION_ABILITY = "ability.want.params.is_preload_uiextension_ability";
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 TAG_LOGD(AAFwkTag::ABILITYMGR, "constructor.");
34 }
35
~ExtensionRecordManager()36 ExtensionRecordManager::~ExtensionRecordManager()
37 {
38 TAG_LOGI(AAFwkTag::ABILITYMGR, "deconstructor");
39 }
40
GenerateExtensionRecordId(const int32_t extensionRecordId)41 int32_t ExtensionRecordManager::GenerateExtensionRecordId(const int32_t extensionRecordId)
42 {
43 TAG_LOGD(AAFwkTag::ABILITYMGR, "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 TAG_LOGD(AAFwkTag::ABILITYMGR, "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 TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionRecordId %{public}d.", extensionRecordId);
74 std::lock_guard<std::mutex> lock(mutex_);
75 extensionRecords_.erase(extensionRecordId);
76 terminateRecords_.erase(extensionRecordId);
77 }
78
AddExtensionRecordToTerminatedList(const int32_t extensionRecordId)79 void ExtensionRecordManager::AddExtensionRecordToTerminatedList(const int32_t extensionRecordId)
80 {
81 TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionRecordId %{public}d.", extensionRecordId);
82 std::lock_guard<std::mutex> lock(mutex_);
83
84 auto findRecord = extensionRecords_.find(extensionRecordId);
85 if (findRecord == extensionRecords_.end()) {
86 TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionRecordId %{public}d not found", extensionRecordId);
87 return;
88 }
89 terminateRecords_.emplace(*findRecord);
90 }
91
GetExtensionRecord(const int32_t extensionRecordId,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)92 int32_t ExtensionRecordManager::GetExtensionRecord(const int32_t extensionRecordId,
93 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
94 {
95 TAG_LOGD(AAFwkTag::ABILITYMGR, "extensionRecordId %{public}d.", extensionRecordId);
96 std::lock_guard<std::mutex> lock(mutex_);
97 // find target record firstly
98 auto it = extensionRecords_.find(extensionRecordId);
99 if (it != extensionRecords_.end() && it->second != nullptr) {
100 // check bundleName
101 TAG_LOGD(AAFwkTag::ABILITYMGR, "Stored host bundleName: %{public}s, input bundleName is %{public}s.",
102 it->second->hostBundleName_.c_str(), hostBundleName.c_str());
103 if (it->second->hostBundleName_ == hostBundleName) {
104 extensionRecord = it->second;
105 isLoaded = true;
106 return ERR_OK;
107 }
108 }
109 TAG_LOGD(AAFwkTag::ABILITYMGR, "Not found stored id %{public}d.", extensionRecordId);
110 extensionRecord = nullptr;
111 isLoaded = false;
112 return ERR_NULL_OBJECT;
113 }
114
IsBelongToManager(const AppExecFwk::AbilityInfo & abilityInfo)115 bool ExtensionRecordManager::IsBelongToManager(const AppExecFwk::AbilityInfo &abilityInfo)
116 {
117 // only support UIExtension now
118 return AAFwk::UIExtensionUtils::IsUIExtension(abilityInfo.extensionAbilityType);
119 }
120
GetActiveUIExtensionList(const int32_t pid,std::vector<std::string> & extensionList)121 int32_t ExtensionRecordManager::GetActiveUIExtensionList(const int32_t pid, std::vector<std::string> &extensionList)
122 {
123 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
124 std::lock_guard<std::mutex> lock(mutex_);
125 for (const auto &it : extensionRecords_) {
126 if (it.second == nullptr || it.second->abilityRecord_ == nullptr ||
127 pid != it.second->abilityRecord_->GetPid()) {
128 continue;
129 }
130
131 extensionList.push_back(it.second->abilityRecord_->GetAbilityInfo().moduleName + SEPARATOR +
132 it.second->abilityRecord_->GetAbilityInfo().name);
133 }
134 return ERR_OK;
135 }
136
GetActiveUIExtensionList(const std::string & bundleName,std::vector<std::string> & extensionList)137 int32_t ExtensionRecordManager::GetActiveUIExtensionList(
138 const std::string &bundleName, std::vector<std::string> &extensionList)
139 {
140 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
141 std::lock_guard<std::mutex> lock(mutex_);
142 for (const auto &it : extensionRecords_) {
143 if (it.second == nullptr || it.second->abilityRecord_ == nullptr ||
144 bundleName != it.second->abilityRecord_->GetAbilityInfo().bundleName) {
145 continue;
146 }
147
148 extensionList.push_back(it.second->abilityRecord_->GetAbilityInfo().moduleName + SEPARATOR +
149 it.second->abilityRecord_->GetAbilityInfo().name);
150 }
151 return ERR_OK;
152 }
153
GetOrCreateExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,bool & isLoaded)154 int32_t ExtensionRecordManager::GetOrCreateExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
155 const std::string &hostBundleName, std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, bool &isLoaded)
156 {
157 CHECK_POINTER_AND_RETURN(abilityRequest.sessionInfo, ERR_INVALID_VALUE);
158 abilityRecord = GetAbilityRecordBySessionInfo(abilityRequest.sessionInfo);
159 if (abilityRecord != nullptr) {
160 isLoaded = true;
161 return ERR_OK;
162 }
163 std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
164 TAG_LOGD(AAFwkTag::ABILITYMGR, "Check Preload Extension Record.");
165 auto result = IsPreloadExtensionRecord(abilityRequest, hostBundleName, extensionRecord, isLoaded);
166 if (result) {
167 std::string abilityName = abilityRequest.want.GetElement().GetAbilityName();
168 std::string bundleName = abilityRequest.want.GetElement().GetBundleName();
169 std::string moduleName = abilityRequest.want.GetElement().GetModuleName();
170 auto extensionRecordMapKey = std::make_tuple(abilityName, bundleName, moduleName, hostBundleName);
171 RemovePreloadUIExtensionRecord(extensionRecordMapKey);
172 } else {
173 int32_t ret = GetOrCreateExtensionRecordInner(abilityRequest, hostBundleName, extensionRecord, isLoaded);
174 if (ret != ERR_OK) {
175 TAG_LOGE(AAFwkTag::ABILITYMGR, "GetOrCreateExtensionRecordInner error");
176 return ret;
177 }
178 }
179 if (extensionRecord != nullptr) {
180 abilityRecord = extensionRecord->abilityRecord_;
181 }
182 return ERR_OK;
183 }
184
GetAbilityRecordBySessionInfo(const sptr<AAFwk::SessionInfo> & sessionInfo)185 std::shared_ptr<AAFwk::AbilityRecord> ExtensionRecordManager::GetAbilityRecordBySessionInfo(
186 const sptr<AAFwk::SessionInfo> &sessionInfo)
187 {
188 CHECK_POINTER_AND_RETURN(sessionInfo, nullptr);
189 if (sessionInfo->uiExtensionComponentId == INVALID_EXTENSION_RECORD_ID) {
190 TAG_LOGD(AAFwkTag::ABILITYMGR, "ExtensionAbility id invalid or not configured.");
191 return nullptr;
192 }
193
194 std::lock_guard<std::mutex> lock(mutex_);
195 for (const auto& it : extensionRecords_) {
196 if (it.second == nullptr) {
197 continue;
198 }
199 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = it.second->abilityRecord_;
200 if (abilityRecord == nullptr) {
201 continue;
202 }
203 sptr<AAFwk::SessionInfo> recordSessionInfo = abilityRecord->GetSessionInfo();
204 if (recordSessionInfo == nullptr) {
205 continue;
206 }
207 if (recordSessionInfo->uiExtensionComponentId == sessionInfo->uiExtensionComponentId) {
208 TAG_LOGD(AAFwkTag::ABILITYMGR,
209 "found record, uiExtensionComponentId: %{public}" PRIu64, sessionInfo->uiExtensionComponentId);
210 return abilityRecord;
211 }
212 }
213 return nullptr;
214 }
215
IsHostSpecifiedProcessValid(const AAFwk::AbilityRequest & abilityRequest,std::shared_ptr<ExtensionRecord> & record,const std::string & process)216 bool ExtensionRecordManager::IsHostSpecifiedProcessValid(const AAFwk::AbilityRequest &abilityRequest,
217 std::shared_ptr<ExtensionRecord> &record, const std::string &process)
218 {
219 std::lock_guard<std::mutex> lock(mutex_);
220 for (const auto &iter: extensionRecords_) {
221 if (iter.second == nullptr || iter.second->abilityRecord_ == nullptr) {
222 continue;
223 }
224 if (iter.second->abilityRecord_->GetProcessName() != process) {
225 continue;
226 }
227 TAG_LOGD(AAFwkTag::ABILITYMGR, "found match extension record: id %{public}d", iter.first);
228 AppExecFwk::AbilityInfo abilityInfo = iter.second->abilityRecord_->GetAbilityInfo();
229 if (abilityRequest.abilityInfo.bundleName != abilityInfo.bundleName) {
230 TAG_LOGE(AAFwkTag::ABILITYMGR, "bundleName not match");
231 return false;
232 }
233 if (abilityRequest.abilityInfo.name != abilityInfo.name) {
234 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityName not match");
235 return false;
236 }
237 return true;
238 }
239 TAG_LOGE(AAFwkTag::ABILITYMGR, "process not found, %{public}s", process.c_str());
240 return false;
241 }
242
UpdateProcessName(const AAFwk::AbilityRequest & abilityRequest,std::shared_ptr<ExtensionRecord> & record)243 int32_t ExtensionRecordManager::UpdateProcessName(const AAFwk::AbilityRequest &abilityRequest,
244 std::shared_ptr<ExtensionRecord> &record)
245 {
246 CHECK_POINTER_AND_RETURN(record, ERR_INVALID_VALUE);
247 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = record->abilityRecord_;
248 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
249 switch (record->processMode_) {
250 case PROCESS_MODE_INSTANCE: {
251 std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name
252 + SEPARATOR + std::to_string(abilityRecord->GetUIExtensionAbilityId());
253 abilityRecord->SetProcessName(process);
254 break;
255 }
256 case PROCESS_MODE_TYPE: {
257 std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name;
258 abilityRecord->SetProcessName(process);
259 break;
260 }
261 case PROCESS_MODE_CUSTOM: {
262 std::string process = abilityRequest.abilityInfo.bundleName + abilityRequest.customProcess;
263 abilityRecord->SetProcessName(process);
264 abilityRecord->SetCustomProcessFlag(abilityRequest.customProcess);
265 break;
266 }
267 case PROCESS_MODE_HOST_SPECIFIED: {
268 std::string process = abilityRequest.want.GetStringParam(PROCESS_MODE_HOST_SPECIFIED_KEY);
269 if (!IsHostSpecifiedProcessValid(abilityRequest, record, process)) {
270 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid name, %{public}s", process.c_str());
271 return ERR_INVALID_VALUE;
272 }
273 abilityRecord->SetProcessName(process);
274 break;
275 }
276 case PROCESS_MODE_RUN_WITH_MAIN_PROCESS: {
277 if (!abilityRequest.appInfo.process.empty()) {
278 abilityRecord->SetProcessName(abilityRequest.appInfo.process);
279 } else {
280 abilityRecord->SetProcessName(abilityRequest.abilityInfo.bundleName);
281 }
282 break;
283 }
284 default: // AppExecFwk::ExtensionProcessMode::UNDEFINED or AppExecFwk::ExtensionProcessMode::BUNDLE
285 // no need to update
286 break;
287 }
288 return ERR_OK;
289 }
290
GetHostBundleNameForExtensionId(int32_t extensionRecordId,std::string & hostBundleName)291 int32_t ExtensionRecordManager::GetHostBundleNameForExtensionId(int32_t extensionRecordId, std::string &hostBundleName)
292 {
293 TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
294 std::lock_guard<std::mutex> lock(mutex_);
295 std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
296 if (extensionRecords_.find(extensionRecordId) != extensionRecords_.end()) {
297 extensionRecord = extensionRecords_[extensionRecordId];
298 CHECK_POINTER_AND_RETURN(extensionRecord, ERR_INVALID_VALUE);
299 hostBundleName = extensionRecord->hostBundleName_;
300 return ERR_OK;
301 }
302 return ERR_INVALID_VALUE;
303 }
304
AddPreloadUIExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> abilityRecord)305 int32_t ExtensionRecordManager::AddPreloadUIExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> abilityRecord)
306 {
307 TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
308 std::lock_guard<std::mutex> lock(mutex_);
309 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
310 std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
311 auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
312 if (extensionRecords_.find(extensionRecordId) != extensionRecords_.end()) {
313 extensionRecord = extensionRecords_[extensionRecordId];
314 CHECK_POINTER_AND_RETURN(extensionRecord, ERR_INVALID_VALUE);
315 auto hostBundleName = extensionRecord->hostBundleName_;
316 auto preLoadUIExtensionInfo = std::make_tuple(abilityRecord->GetWant().GetElement().GetAbilityName(),
317 abilityRecord->GetWant().GetElement().GetBundleName(),
318 abilityRecord->GetWant().GetElement().GetModuleName(), hostBundleName);
319 TAG_LOGD(AAFwkTag::ABILITYMGR, "hostBundleName: %{public}s, elementName:%{public}s ",
320 hostBundleName.c_str(), abilityRecord->GetWant().GetElement().GetURI().c_str());
321 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
322 preloadUIExtensionMap_[preLoadUIExtensionInfo].push_back(extensionRecord);
323 return ERR_OK;
324 }
325 TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionRecordId invalid");
326 return ERR_INVALID_VALUE;
327 }
328
RemoveAllPreloadUIExtensionRecord(PreLoadUIExtensionMapKey & preLoadUIExtensionInfo)329 void ExtensionRecordManager::RemoveAllPreloadUIExtensionRecord(PreLoadUIExtensionMapKey &preLoadUIExtensionInfo)
330 {
331 TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
332 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
333 if (preloadUIExtensionMap_.find(preLoadUIExtensionInfo) != preloadUIExtensionMap_.end()) {
334 preloadUIExtensionMap_.erase(preLoadUIExtensionInfo);
335 } else {
336 TAG_LOGD(AAFwkTag::ABILITYMGR, "The preLoadUIExtensionInfo has no corresponding extensionRecord object!");
337 }
338 }
339
IsPreloadExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)340 bool ExtensionRecordManager::IsPreloadExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
341 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
342 {
343 TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
344 std::string abilityName = abilityRequest.want.GetElement().GetAbilityName();
345 std::string bundleName = abilityRequest.want.GetElement().GetBundleName();
346 std::string moduleName = abilityRequest.want.GetElement().GetModuleName();
347 auto extensionRecordMapKey = std::make_tuple(abilityName, bundleName, moduleName, hostBundleName);
348 TAG_LOGD(AAFwkTag::ABILITYMGR, "hostBundleName: %{public}s, bundleName: %{public}s",
349 hostBundleName.c_str(), bundleName.c_str());
350 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
351 auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
352 if (item != preloadUIExtensionMap_.end()) {
353 if (!item->second.empty()) {
354 TAG_LOGD(AAFwkTag::ABILITYMGR, "UIExtensionAbility has been preloaded.");
355 auto extensionRecords = item->second;
356 extensionRecord = extensionRecords[0];
357 if (extensionRecord == nullptr) {
358 TAG_LOGE(AAFwkTag::ABILITYMGR, "null ExtensionRecord");
359 return false;
360 }
361 extensionRecord->Update(abilityRequest);
362 isLoaded = true;
363 return true;
364 }
365 }
366 TAG_LOGD(AAFwkTag::ABILITYMGR, "UIExtension is not preloaded.");
367 return false;
368 }
369
RemovePreloadUIExtensionRecordById(const std::tuple<std::string,std::string,std::string,std::string> & extensionRecordMapKey,int32_t extensionRecordId)370 bool ExtensionRecordManager::RemovePreloadUIExtensionRecordById(
371 const std::tuple<std::string, std::string, std::string, std::string> &extensionRecordMapKey,
372 int32_t extensionRecordId)
373 {
374 TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
375 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
376 auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
377 if (item == preloadUIExtensionMap_.end()) {
378 TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionRecords unfound");
379 return false;
380 }
381 if (item->second.empty()) {
382 TAG_LOGE(AAFwkTag::ABILITYMGR, "clean the map key");
383 preloadUIExtensionMap_.erase(extensionRecordMapKey);
384 return false;
385 }
386 for (auto it = item->second.begin(); it != item->second.end(); ++it) {
387 if ((*it)->extensionRecordId_ == extensionRecordId) {
388 item->second.erase(it);
389 TAG_LOGD(AAFwkTag::ABILITYMGR, "Remove extension record by id: %{public}d success.", extensionRecordId);
390 if (item->second.empty()) {
391 TAG_LOGD(AAFwkTag::ABILITYMGR, "Clean extensionRecord by map key");
392 preloadUIExtensionMap_.erase(extensionRecordMapKey);
393 }
394 return true;
395 }
396 }
397 TAG_LOGE(AAFwkTag::ABILITYMGR, "findRecordsbyID: %{public}d failed", extensionRecordId);
398 return false;
399 }
400
RemovePreloadUIExtensionRecord(const std::tuple<std::string,std::string,std::string,std::string> extensionRecordMapKey)401 bool ExtensionRecordManager::RemovePreloadUIExtensionRecord(
402 const std::tuple<std::string, std::string, std::string, std::string> extensionRecordMapKey)
403 {
404 TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
405 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
406 auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
407 if (item != preloadUIExtensionMap_.end()) {
408 if (!item->second.empty()) {
409 item->second.erase(item->second.begin());
410 }
411 if (item->second.empty()) {
412 preloadUIExtensionMap_.erase(extensionRecordMapKey);
413 }
414 return true;
415 }
416 TAG_LOGE(AAFwkTag::ABILITYMGR, "preloadUIExtensionMap_ erase key error");
417 return false;
418 }
419
GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)420 int32_t ExtensionRecordManager::GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest &abilityRequest,
421 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
422 {
423 std::shared_ptr<ExtensionRecordFactory> factory = nullptr;
424 if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
425 factory = DelayedSingleton<UIExtensionRecordFactory>::GetInstance();
426 }
427 if (factory == nullptr) {
428 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid extensionAbilityType");
429 return ERR_INVALID_VALUE;
430 }
431 int32_t result = factory->PreCheck(abilityRequest, hostBundleName);
432 if (result != ERR_OK) {
433 return result;
434 }
435 int32_t extensionRecordId = INVALID_EXTENSION_RECORD_ID;
436 bool needReuse = factory->NeedReuse(abilityRequest, extensionRecordId);
437 if (needReuse) {
438 TAG_LOGD(AAFwkTag::ABILITYMGR, "reuse record, id: %{public}d", extensionRecordId);
439 int32_t ret = GetExtensionRecord(extensionRecordId, hostBundleName, extensionRecord, isLoaded);
440 if (ret == ERR_OK) {
441 extensionRecord->Update(abilityRequest);
442 }
443 return ret;
444 }
445 result = factory->CreateRecord(abilityRequest, extensionRecord);
446 if (result != ERR_OK) {
447 return result;
448 }
449 CHECK_POINTER_AND_RETURN(extensionRecord, ERR_NULL_OBJECT);
450 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = extensionRecord->abilityRecord_;
451 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_NULL_OBJECT);
452 isLoaded = false;
453 // Reuse id or not has been checked, so alloc a new id here.
454 extensionRecordId = GenerateExtensionRecordId(INVALID_EXTENSION_RECORD_ID);
455 extensionRecord->extensionRecordId_ = extensionRecordId;
456 extensionRecord->hostBundleName_ = hostBundleName;
457 abilityRecord->SetOwnerMissionUserId(userId_);
458 abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
459 result = SetAbilityProcessName(abilityRequest, abilityRecord, extensionRecord);
460 if (result != ERR_OK) {
461 return result;
462 }
463 TAG_LOGD(AAFwkTag::ABILITYMGR,
464 "extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
465 extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
466 std::lock_guard<std::mutex> lock(mutex_);
467 extensionRecords_[extensionRecordId] = extensionRecord;
468 return ERR_OK;
469 }
470
SetAbilityProcessName(const AAFwk::AbilityRequest & abilityRequest,const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,std::shared_ptr<ExtensionRecord> & extensionRecord)471 int32_t ExtensionRecordManager::SetAbilityProcessName(const AAFwk::AbilityRequest &abilityRequest,
472 const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, std::shared_ptr<ExtensionRecord> &extensionRecord)
473 {
474 if (abilityRequest.abilityInfo.isolationProcess &&
475 AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
476 abilityRecord->SetProcessName(
477 abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.extensionTypeName);
478 return ERR_OK;
479 } else {
480 return UpdateProcessName(abilityRequest, extensionRecord);
481 }
482 }
483
StartAbility(const AAFwk::AbilityRequest & abilityRequest)484 int32_t ExtensionRecordManager::StartAbility(const AAFwk::AbilityRequest &abilityRequest)
485 {
486 return ERR_OK;
487 }
488
SetCachedFocusedCallerToken(int32_t extensionRecordId,sptr<IRemoteObject> & focusedCallerToken)489 void ExtensionRecordManager::SetCachedFocusedCallerToken(int32_t extensionRecordId,
490 sptr<IRemoteObject> &focusedCallerToken)
491 {
492 auto it = extensionRecords_.find(extensionRecordId);
493 if (it != extensionRecords_.end() && it->second != nullptr) {
494 it->second->SetFocusedCallerToken(focusedCallerToken);
495 }
496 }
497
GetCachedFocusedCallerToken(int32_t extensionRecordId) const498 sptr<IRemoteObject> ExtensionRecordManager::GetCachedFocusedCallerToken(int32_t extensionRecordId) const
499 {
500 auto it = extensionRecords_.find(extensionRecordId);
501 if (it != extensionRecords_.end() && it->second != nullptr) {
502 return it->second->GetFocusedCallerToken();
503 }
504 return nullptr;
505 }
506
GetRootCallerTokenLocked(int32_t extensionRecordId,const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord)507 sptr<IRemoteObject> ExtensionRecordManager::GetRootCallerTokenLocked(
508 int32_t extensionRecordId, const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord)
509 {
510 auto it = extensionRecords_.find(extensionRecordId);
511 if (it != extensionRecords_.end() && it->second != nullptr) {
512 sptr<IRemoteObject> rootCallerToken = it->second->GetRootCallerToken();
513 if (rootCallerToken != nullptr) {
514 return rootCallerToken;
515 }
516 std::list<sptr<IRemoteObject>> callerList;
517 GetCallerTokenList(abilityRecord, callerList);
518
519 if (callerList.empty()) {
520 TAG_LOGE(AAFwkTag::ABILITYMGR, "callerList empty");
521 return nullptr;
522 }
523
524 rootCallerToken = callerList.front();
525 it->second->SetRootCallerToken(rootCallerToken);
526 return rootCallerToken;
527 }
528 TAG_LOGE(AAFwkTag::ABILITYMGR, "not found id %{public}d", extensionRecordId);
529 return nullptr;
530 }
531
CreateExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,int32_t & extensionRecordId,int32_t hostPid)532 int32_t ExtensionRecordManager::CreateExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
533 const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord,
534 int32_t &extensionRecordId, int32_t hostPid)
535 {
536 TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
537 std::shared_ptr<ExtensionRecordFactory> factory = nullptr;
538 if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
539 factory = DelayedSingleton<UIExtensionRecordFactory>::GetInstance();
540 }
541 if (factory == nullptr) {
542 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid extensionAbilityType");
543 return ERR_INVALID_VALUE;
544 }
545 int32_t result = factory->PreCheck(abilityRequest, hostBundleName);
546 if (result != ERR_OK) {
547 return result;
548 }
549 result = factory->CreateRecord(abilityRequest, extensionRecord);
550 if (result != ERR_OK) {
551 TAG_LOGE(AAFwkTag::ABILITYMGR, "createRecord error");
552 return result;
553 }
554 CHECK_POINTER_AND_RETURN(extensionRecord, ERR_NULL_OBJECT);
555 std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = extensionRecord->abilityRecord_;
556 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_NULL_OBJECT);
557 extensionRecordId = GenerateExtensionRecordId(extensionRecordId);
558 extensionRecord->extensionRecordId_ = extensionRecordId;
559 extensionRecord->hostBundleName_ = hostBundleName;
560 abilityRecord->SetOwnerMissionUserId(userId_);
561 abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
562 extensionRecord->hostPid_ = (hostPid == AAFwk::DEFAULT_INVAL_VALUE) ? IPCSkeleton::GetCallingPid() : hostPid;
563 //add uiextension record register state observer object.
564 if (abilityRecord->GetWant().GetBoolParam(IS_PRELOAD_UIEXTENSION_ABILITY, false)) {
565 auto ret = extensionRecord->RegisterStateObserver(hostBundleName);
566 if (ret != ERR_OK) {
567 TAG_LOGE(AAFwkTag::ABILITYMGR, "register failed, err: %{public}d", ret);
568 return ERR_INVALID_VALUE;
569 }
570 }
571 result = UpdateProcessName(abilityRequest, extensionRecord);
572 if (result != ERR_OK) {
573 TAG_LOGE(AAFwkTag::ABILITYMGR, "update processname error");
574 return result;
575 }
576 TAG_LOGI(AAFwkTag::ABILITYMGR,
577 "extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
578 extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
579 std::lock_guard<std::mutex> lock(mutex_);
580 extensionRecords_[extensionRecordId] = extensionRecord;
581 return ERR_OK;
582 }
583
GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token)584 std::shared_ptr<AAFwk::AbilityRecord> ExtensionRecordManager::GetUIExtensionRootHostInfo(
585 const sptr<IRemoteObject> token)
586 {
587 if (token == nullptr) {
588 TAG_LOGE(AAFwkTag::ABILITYMGR, "input param invalid");
589 return nullptr;
590 }
591
592 auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
593 if (abilityRecord == nullptr) {
594 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityRecord empty");
595 return nullptr;
596 }
597
598 if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
599 TAG_LOGW(AAFwkTag::ABILITYMGR, "not uiextension ability");
600 return nullptr;
601 }
602
603 sptr<IRemoteObject> rootCallerToken = nullptr;
604 auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
605 {
606 std::lock_guard<std::mutex> lock(mutex_);
607 rootCallerToken = GetRootCallerTokenLocked(extensionRecordId, abilityRecord);
608 }
609
610 if (rootCallerToken == nullptr) {
611 TAG_LOGE(AAFwkTag::ABILITYMGR, "get record failed");
612 return nullptr;
613 }
614
615 return AAFwk::Token::GetAbilityRecordByToken(rootCallerToken);
616 }
617
GetUIExtensionSessionInfo(const sptr<IRemoteObject> token,UIExtensionSessionInfo & uiExtensionSessionInfo)618 int32_t ExtensionRecordManager::GetUIExtensionSessionInfo(
619 const sptr<IRemoteObject> token, UIExtensionSessionInfo &uiExtensionSessionInfo)
620 {
621 if (token == nullptr) {
622 TAG_LOGE(AAFwkTag::ABILITYMGR, "input param invalid");
623 return ERR_NULL_OBJECT;
624 }
625
626 auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
627 if (abilityRecord == nullptr) {
628 TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityRecord empty");
629 return ERR_NULL_OBJECT;
630 }
631
632 if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
633 TAG_LOGW(AAFwkTag::ABILITYMGR, "not uiextension ability");
634 return ERR_INVALID_VALUE;
635 }
636
637 auto sessionInfo = abilityRecord->GetSessionInfo();
638 if (sessionInfo == nullptr) {
639 TAG_LOGE(AAFwkTag::ABILITYMGR, "null sessionInfo");
640 return ERR_NULL_OBJECT;
641 }
642
643 uiExtensionSessionInfo.persistentId = sessionInfo->persistentId;
644 uiExtensionSessionInfo.hostWindowId = sessionInfo->hostWindowId;
645 uiExtensionSessionInfo.uiExtensionUsage = sessionInfo->uiExtensionUsage;
646 uiExtensionSessionInfo.elementName = abilityRecord->GetElementName();
647 uiExtensionSessionInfo.extensionAbilityType = abilityRecord->GetAbilityInfo().extensionAbilityType;
648
649 auto callerToken = sessionInfo->callerToken;
650 if (callerToken != nullptr) {
651 auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
652 if (callerAbilityRecord != nullptr) {
653 uiExtensionSessionInfo.hostElementName = callerAbilityRecord->GetElementName();
654 }
655 }
656 return ERR_OK;
657 }
658
GetExtensionRecordById(int32_t extensionRecordId)659 std::shared_ptr<ExtensionRecord> ExtensionRecordManager::GetExtensionRecordById(int32_t extensionRecordId)
660 {
661 std::lock_guard<std::mutex> lock(mutex_);
662 auto findRecord = extensionRecords_.find(extensionRecordId);
663 if (findRecord != extensionRecords_.end()) {
664 return findRecord->second;
665 }
666 findRecord = terminateRecords_.find(extensionRecordId);
667 if (findRecord == terminateRecords_.end()) {
668 TAG_LOGE(AAFwkTag::ABILITYMGR, "uiextension record unfound, id: %{public}d", extensionRecordId);
669 return nullptr;
670 }
671
672 return findRecord->second;
673 }
674
LoadTimeout(int32_t extensionRecordId)675 void ExtensionRecordManager::LoadTimeout(int32_t extensionRecordId)
676 {
677 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
678 auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
679 if (uiExtensionRecord == nullptr) {
680 TAG_LOGE(AAFwkTag::ABILITYMGR, "parsing uiExtensionRecord failed");
681 return;
682 }
683 TAG_LOGD(AAFwkTag::ABILITYMGR, "Start load timeout.");
684 uiExtensionRecord->LoadTimeout();
685 }
686
ForegroundTimeout(int32_t extensionRecordId)687 void ExtensionRecordManager::ForegroundTimeout(int32_t extensionRecordId)
688 {
689 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
690 auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
691 if (uiExtensionRecord == nullptr) {
692 TAG_LOGE(AAFwkTag::ABILITYMGR, "parsing uiExtensionRecord failed");
693 return;
694 }
695 TAG_LOGD(AAFwkTag::ABILITYMGR, "Start foreground timeout.");
696 uiExtensionRecord->ForegroundTimeout();
697 }
698
BackgroundTimeout(int32_t extensionRecordId)699 void ExtensionRecordManager::BackgroundTimeout(int32_t extensionRecordId)
700 {
701 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
702 auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
703 if (uiExtensionRecord == nullptr) {
704 TAG_LOGE(AAFwkTag::ABILITYMGR, "parsing uiextension record failed");
705 return;
706 }
707 TAG_LOGD(AAFwkTag::ABILITYMGR, "Start background timeout.");
708 uiExtensionRecord->BackgroundTimeout();
709 }
710
TerminateTimeout(int32_t extensionRecordId)711 void ExtensionRecordManager::TerminateTimeout(int32_t extensionRecordId)
712 {
713 TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
714 auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
715 if (uiExtensionRecord == nullptr) {
716 TAG_LOGE(AAFwkTag::ABILITYMGR, "parsing uiExtensionRecord failed");
717 return;
718 }
719 TAG_LOGD(AAFwkTag::ABILITYMGR, "Start terminate timeout.");
720 uiExtensionRecord->TerminateTimeout();
721 }
722
GetCallerTokenList(const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,std::list<sptr<IRemoteObject>> & callerList)723 void ExtensionRecordManager::GetCallerTokenList(
724 const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, std::list<sptr<IRemoteObject>> &callerList)
725 {
726 CHECK_POINTER(abilityRecord);
727 auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
728 auto sessionInfo = abilityRecord->GetSessionInfo();
729 if (!sessionInfo) {
730 TAG_LOGE(AAFwkTag::ABILITYMGR, "sessionInfo null, id: %{public}d", extensionRecordId);
731 callerList.clear();
732 return;
733 }
734
735 auto callerToken = sessionInfo->callerToken;
736 auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
737 if (callerAbilityRecord == nullptr) {
738 TAG_LOGE(AAFwkTag::ABILITYMGR, "callerRecord null, id: %{public}d", extensionRecordId);
739 callerList.clear();
740 return;
741 }
742
743 TAG_LOGD(AAFwkTag::ABILITYMGR, "ability: %{public}s, pid: %{public}d, tokenId: %{public}d",
744 callerAbilityRecord->GetWant().GetElement().GetURI().c_str(), callerAbilityRecord->GetPid(),
745 callerAbilityRecord->GetApplicationInfo().accessTokenId);
746
747 auto callerExtensionRecordId = callerAbilityRecord->GetUIExtensionAbilityId();
748 if (callerExtensionRecordId == INVALID_EXTENSION_RECORD_ID) {
749 TAG_LOGD(AAFwkTag::ABILITYMGR, "Get caller, callerRecord: %{public}d", callerExtensionRecordId);
750 callerList.push_front(callerToken);
751 return;
752 }
753
754 // If caller extension record id is same with current, need terminate, prevent possible stack-overflow.
755 if (callerExtensionRecordId == extensionRecordId) {
756 TAG_LOGE(AAFwkTag::ABILITYMGR, "callerRecordId: %{public}d, same with caller", extensionRecordId);
757 callerList.clear();
758 return;
759 }
760
761 callerList.push_front(callerToken);
762 GetCallerTokenList(callerAbilityRecord, callerList);
763 }
764
IsFocused(int32_t extensionRecordId,const sptr<IRemoteObject> & token,const sptr<IRemoteObject> & focusToken)765 bool ExtensionRecordManager::IsFocused(
766 int32_t extensionRecordId, const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &focusToken)
767 {
768 std::lock_guard<std::mutex> lock(mutex_);
769 auto cachedCaller = GetCachedFocusedCallerToken(extensionRecordId);
770 if (cachedCaller != nullptr && cachedCaller == focusToken) {
771 TAG_LOGD(AAFwkTag::ABILITYMGR, "id: %{public}d has focused", extensionRecordId);
772 return true;
773 }
774
775 auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
776 if (!abilityRecord) {
777 return false;
778 }
779
780 TAG_LOGD(AAFwkTag::ABILITYMGR, "ability: %{public}s, pid: %{public}d, tokenId: %{public}d",
781 abilityRecord->GetWant().GetElement().GetURI().c_str(), abilityRecord->GetPid(),
782 abilityRecord->GetApplicationInfo().accessTokenId);
783
784 if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
785 TAG_LOGW(AAFwkTag::ABILITYMGR, "not uiextension");
786 return false;
787 }
788
789 bool isFocused = false;
790 std::list<sptr<IRemoteObject>> callerList;
791 GetCallerTokenList(abilityRecord, callerList);
792 for (auto& item : callerList) {
793 auto ability = AAFwk::Token::GetAbilityRecordByToken(item);
794 if (ability == nullptr) {
795 TAG_LOGW(AAFwkTag::ABILITYMGR, "wrong ability");
796 continue;
797 }
798
799 if (item == focusToken) {
800 isFocused = true;
801 SetCachedFocusedCallerToken(extensionRecordId, item);
802 break;
803 }
804 }
805 return isFocused;
806 }
807
QueryPreLoadUIExtensionRecord(const AppExecFwk::ElementName & element,const std::string & moduleName,const std::string & hostBundleName,int32_t & recordNum)808 int32_t ExtensionRecordManager::QueryPreLoadUIExtensionRecord(const AppExecFwk::ElementName &element,
809 const std::string &moduleName,
810 const std::string &hostBundleName,
811 int32_t &recordNum)
812 {
813 std::string abilityName = element.GetAbilityName();
814 std::string bundleName = element.GetBundleName();
815 TAG_LOGD(AAFwkTag::UI_EXT,
816 "hostBundleName: %{public}s, bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
817 hostBundleName.c_str(), bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
818 if (element.GetAbilityName().empty() || element.GetBundleName().empty() || moduleName.empty() ||
819 hostBundleName.empty()) {
820 recordNum = 0;
821 TAG_LOGD(AAFwkTag::UI_EXT, "element or hostBundleName is null.");
822 return ERR_INVALID_VALUE;
823 }
824
825 auto extensionRecordMapKey =
826 std::make_tuple(abilityName, bundleName, moduleName, hostBundleName);
827 std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
828 auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
829 if (item != preloadUIExtensionMap_.end()) {
830 if (!item->second.empty()) {
831 recordNum = item->second.size();
832 TAG_LOGD(AAFwkTag::ABILITYMGR, "UIExtensionAbility has been preloaded,recordNum:%{public}d.", recordNum);
833 return ERR_OK;
834 }
835 }
836 TAG_LOGD(AAFwkTag::UI_EXT, "UIExtension is not preloaded.");
837 recordNum = 0;
838 return ERR_OK;
839 }
840 } // namespace AbilityRuntime
841 } // namespace OHOS
842