• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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