1 /*
2  * Copyright (c) 2023-2024 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 is not match");
231             return false;
232         }
233         if (abilityRequest.abilityInfo.name != abilityInfo.name) {
234             TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityName is not match");
235             return false;
236         }
237         return true;
238     }
239     TAG_LOGE(AAFwkTag::ABILITYMGR, "specified 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     std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = record->abilityRecord_;
247     switch (record->processMode_) {
248         case PROCESS_MODE_INSTANCE: {
249             std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name
250                 + SEPARATOR + std::to_string(abilityRecord->GetUIExtensionAbilityId());
251             abilityRecord->SetProcessName(process);
252             break;
253         }
254         case PROCESS_MODE_TYPE: {
255             std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name;
256             abilityRecord->SetProcessName(process);
257             break;
258         }
259         case PROCESS_MODE_HOST_SPECIFIED: {
260             std::string process = abilityRequest.want.GetStringParam(PROCESS_MODE_HOST_SPECIFIED_KEY);
261             if (!IsHostSpecifiedProcessValid(abilityRequest, record, process)) {
262                 TAG_LOGE(AAFwkTag::ABILITYMGR, "host specified process name is invalid, %{public}s", process.c_str());
263                 return ERR_INVALID_VALUE;
264             }
265             abilityRecord->SetProcessName(process);
266             break;
267         }
268         default: // AppExecFwk::ExtensionProcessMode::UNDEFINED or AppExecFwk::ExtensionProcessMode::BUNDLE
269             // no need to update
270             break;
271     }
272     return ERR_OK;
273 }
274 
GetHostBundleNameForExtensionId(int32_t extensionRecordId,std::string & hostBundleName)275 int32_t ExtensionRecordManager::GetHostBundleNameForExtensionId(int32_t extensionRecordId, std::string &hostBundleName)
276 {
277     TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
278     std::lock_guard<std::mutex> lock(mutex_);
279     std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
280     if (extensionRecords_.find(extensionRecordId) != extensionRecords_.end()) {
281         extensionRecord = extensionRecords_[extensionRecordId];
282         CHECK_POINTER_AND_RETURN(extensionRecord, ERR_INVALID_VALUE);
283         hostBundleName = extensionRecord->hostBundleName_;
284         return ERR_OK;
285     }
286     return ERR_INVALID_VALUE;
287 }
288 
AddPreloadUIExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> abilityRecord)289 int32_t ExtensionRecordManager::AddPreloadUIExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> abilityRecord)
290 {
291     TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
292     std::lock_guard<std::mutex> lock(mutex_);
293     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
294     std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
295     auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
296     if (extensionRecords_.find(extensionRecordId) != extensionRecords_.end()) {
297         extensionRecord = extensionRecords_[extensionRecordId];
298         CHECK_POINTER_AND_RETURN(extensionRecord, ERR_INVALID_VALUE);
299         auto hostBundleName = extensionRecord->hostBundleName_;
300         auto preLoadUIExtensionInfo = std::make_tuple(abilityRecord->GetWant().GetElement().GetAbilityName(),
301             abilityRecord->GetWant().GetElement().GetBundleName(),
302             abilityRecord->GetWant().GetElement().GetModuleName(), hostBundleName);
303         TAG_LOGD(AAFwkTag::ABILITYMGR, "hostBundleName: %{public}s, elementName:%{public}s ",
304             hostBundleName.c_str(), abilityRecord->GetWant().GetElement().GetURI().c_str());
305         std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
306         preloadUIExtensionMap_[preLoadUIExtensionInfo].push_back(extensionRecord);
307         return ERR_OK;
308     }
309     TAG_LOGE(AAFwkTag::ABILITYMGR, "The extensionRecordId has no corresponding extensionRecord object!");
310     return ERR_INVALID_VALUE;
311 }
312 
RemoveAllPreloadUIExtensionRecord(PreLoadUIExtensionMapKey & preLoadUIExtensionInfo)313 void ExtensionRecordManager::RemoveAllPreloadUIExtensionRecord(PreLoadUIExtensionMapKey &preLoadUIExtensionInfo)
314 {
315     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
316     std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
317     if (preloadUIExtensionMap_.find(preLoadUIExtensionInfo) != preloadUIExtensionMap_.end()) {
318         preloadUIExtensionMap_.erase(preLoadUIExtensionInfo);
319     } else {
320         TAG_LOGD(AAFwkTag::ABILITYMGR, "The preLoadUIExtensionInfo has no corresponding extensionRecord object!");
321     }
322 }
323 
IsPreloadExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)324 bool ExtensionRecordManager::IsPreloadExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
325     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
326 {
327     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
328     std::string abilityName = abilityRequest.want.GetElement().GetAbilityName();
329     std::string bundleName = abilityRequest.want.GetElement().GetBundleName();
330     std::string moduleName = abilityRequest.want.GetElement().GetModuleName();
331     auto extensionRecordMapKey = std::make_tuple(abilityName, bundleName, moduleName, hostBundleName);
332     TAG_LOGD(AAFwkTag::ABILITYMGR, "hostBundleName: %{public}s, bundleName: %{public}s",
333         hostBundleName.c_str(), bundleName.c_str());
334     std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
335     auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
336     if (item != preloadUIExtensionMap_.end()) {
337         if (!item->second.empty()) {
338             TAG_LOGD(AAFwkTag::ABILITYMGR, "UIExtensionAbility has been preloaded.");
339             auto extensionRecords = item->second;
340             extensionRecord = extensionRecords[0];
341             if (extensionRecord == nullptr) {
342                 TAG_LOGE(AAFwkTag::ABILITYMGR, "ExtensionRecord is nullptr.");
343                 return false;
344             }
345             extensionRecord->Update(abilityRequest);
346             isLoaded = true;
347             return true;
348         }
349     }
350     TAG_LOGD(AAFwkTag::ABILITYMGR, "UIExtension is not preloaded.");
351     return false;
352 }
353 
RemovePreloadUIExtensionRecordById(const std::tuple<std::string,std::string,std::string,std::string> extensionRecordMapKey,int32_t extensionRecordId)354 bool ExtensionRecordManager::RemovePreloadUIExtensionRecordById(
355     const std::tuple<std::string, std::string, std::string, std::string> extensionRecordMapKey,
356     int32_t extensionRecordId)
357 {
358     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
359     std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
360     auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
361     if (item == preloadUIExtensionMap_.end()) {
362         TAG_LOGE(AAFwkTag::ABILITYMGR, "Cannot find ExtensionRecords!");
363         return false;
364     }
365     if (item->second.empty()) {
366         TAG_LOGE(AAFwkTag::ABILITYMGR, "Extension record vector is empty! Clean the map key");
367         preloadUIExtensionMap_.erase(extensionRecordMapKey);
368         return false;
369     }
370     for (auto it = item->second.begin(); it != item->second.end(); ++it) {
371         if ((*it)->extensionRecordId_ == extensionRecordId) {
372             item->second.erase(it);
373             TAG_LOGD(AAFwkTag::ABILITYMGR, "Remove extension record by id: %{public}d success.", extensionRecordId);
374             if (item->second.empty()) {
375                 TAG_LOGD(AAFwkTag::ABILITYMGR, "Clean extensionRecord by map key");
376                 preloadUIExtensionMap_.erase(extensionRecordMapKey);
377             }
378             return true;
379         }
380     }
381     TAG_LOGE(AAFwkTag::ABILITYMGR, "Cannot find extension records by id: %{public}d.", extensionRecordId);
382     return false;
383 }
384 
RemovePreloadUIExtensionRecord(const std::tuple<std::string,std::string,std::string,std::string> extensionRecordMapKey)385 bool ExtensionRecordManager::RemovePreloadUIExtensionRecord(
386     const std::tuple<std::string, std::string, std::string, std::string> extensionRecordMapKey)
387 {
388     TAG_LOGD(AAFwkTag::ABILITYMGR, "call.");
389     std::lock_guard<std::mutex> lock(preloadUIExtensionMapMutex_);
390     auto item = preloadUIExtensionMap_.find(extensionRecordMapKey);
391     if (item != preloadUIExtensionMap_.end()) {
392         if (!item->second.empty()) {
393             item->second.erase(item->second.begin());
394         }
395         if (item->second.empty()) {
396             preloadUIExtensionMap_.erase(extensionRecordMapKey);
397         }
398         return true;
399     }
400     TAG_LOGE(AAFwkTag::ABILITYMGR, "preloadUIExtensionMap_ erase key error.");
401     return false;
402 }
403 
GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)404 int32_t ExtensionRecordManager::GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest &abilityRequest,
405     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
406 {
407     std::shared_ptr<ExtensionRecordFactory> factory = nullptr;
408     if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
409         factory = DelayedSingleton<UIExtensionRecordFactory>::GetInstance();
410     }
411     if (factory == nullptr) {
412         TAG_LOGE(AAFwkTag::ABILITYMGR, "Invalid extensionAbilityType");
413         return ERR_INVALID_VALUE;
414     }
415     int32_t result = factory->PreCheck(abilityRequest, hostBundleName);
416     if (result != ERR_OK) {
417         return result;
418     }
419     int32_t extensionRecordId = INVALID_EXTENSION_RECORD_ID;
420     bool needReuse = factory->NeedReuse(abilityRequest, extensionRecordId);
421     if (needReuse) {
422         TAG_LOGD(AAFwkTag::ABILITYMGR, "reuse record, id: %{public}d", extensionRecordId);
423         int32_t ret = GetExtensionRecord(extensionRecordId, hostBundleName, extensionRecord, isLoaded);
424         if (ret == ERR_OK) {
425             extensionRecord->Update(abilityRequest);
426         }
427         return ret;
428     }
429     result = factory->CreateRecord(abilityRequest, extensionRecord);
430     if (result != ERR_OK) {
431         return result;
432     }
433     CHECK_POINTER_AND_RETURN(extensionRecord, ERR_NULL_OBJECT);
434     std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = extensionRecord->abilityRecord_;
435     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_NULL_OBJECT);
436     isLoaded = false;
437     // Reuse id or not has been checked, so alloc a new id here.
438     extensionRecordId = GenerateExtensionRecordId(INVALID_EXTENSION_RECORD_ID);
439     extensionRecord->extensionRecordId_ = extensionRecordId;
440     extensionRecord->hostBundleName_ = hostBundleName;
441     abilityRecord->SetOwnerMissionUserId(userId_);
442     abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
443     result = UpdateProcessName(abilityRequest, extensionRecord);
444     if (result != ERR_OK) {
445         return result;
446     }
447     TAG_LOGD(AAFwkTag::ABILITYMGR,
448         "extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
449         extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
450     std::lock_guard<std::mutex> lock(mutex_);
451     extensionRecords_[extensionRecordId] = extensionRecord;
452     return ERR_OK;
453 }
454 
StartAbility(const AAFwk::AbilityRequest & abilityRequest)455 int32_t ExtensionRecordManager::StartAbility(const AAFwk::AbilityRequest &abilityRequest)
456 {
457     return ERR_OK;
458 }
459 
SetCachedFocusedCallerToken(int32_t extensionRecordId,sptr<IRemoteObject> & focusedCallerToken)460 void ExtensionRecordManager::SetCachedFocusedCallerToken(int32_t extensionRecordId,
461     sptr<IRemoteObject> &focusedCallerToken)
462 {
463     auto it = extensionRecords_.find(extensionRecordId);
464     if (it != extensionRecords_.end() && it->second != nullptr) {
465         it->second->SetFocusedCallerToken(focusedCallerToken);
466     }
467 }
468 
GetCachedFocusedCallerToken(int32_t extensionRecordId) const469 sptr<IRemoteObject> ExtensionRecordManager::GetCachedFocusedCallerToken(int32_t extensionRecordId) const
470 {
471     auto it = extensionRecords_.find(extensionRecordId);
472     if (it != extensionRecords_.end() && it->second != nullptr) {
473         return it->second->GetFocusedCallerToken();
474     }
475     return nullptr;
476 }
477 
GetRootCallerTokenLocked(int32_t extensionRecordId,const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord)478 sptr<IRemoteObject> ExtensionRecordManager::GetRootCallerTokenLocked(
479     int32_t extensionRecordId, const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord)
480 {
481     auto it = extensionRecords_.find(extensionRecordId);
482     if (it != extensionRecords_.end() && it->second != nullptr) {
483         sptr<IRemoteObject> rootCallerToken = it->second->GetRootCallerToken();
484         if (rootCallerToken != nullptr) {
485             return rootCallerToken;
486         }
487         std::list<sptr<IRemoteObject>> callerList;
488         GetCallerTokenList(abilityRecord, callerList);
489 
490         if (callerList.empty()) {
491             TAG_LOGE(AAFwkTag::ABILITYMGR, "Get callerList failed");
492             return nullptr;
493         }
494 
495         rootCallerToken = callerList.front();
496         it->second->SetRootCallerToken(rootCallerToken);
497         return rootCallerToken;
498     }
499     TAG_LOGE(AAFwkTag::ABILITYMGR, "Not found id %{public}d.", extensionRecordId);
500     return nullptr;
501 }
502 
CreateExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,int32_t & extensionRecordId)503 int32_t ExtensionRecordManager::CreateExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
504     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, int32_t &extensionRecordId)
505 {
506     TAG_LOGD(AAFwkTag::ABILITYMGR, "call");
507     std::shared_ptr<ExtensionRecordFactory> factory = nullptr;
508     if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
509         factory = DelayedSingleton<UIExtensionRecordFactory>::GetInstance();
510     }
511     if (factory == nullptr) {
512         TAG_LOGE(AAFwkTag::ABILITYMGR, "Invalid extensionAbilityType");
513         return ERR_INVALID_VALUE;
514     }
515     int32_t result = factory->PreCheck(abilityRequest, hostBundleName);
516     if (result != ERR_OK) {
517         return result;
518     }
519     result = factory->CreateRecord(abilityRequest, extensionRecord);
520     if (result != ERR_OK) {
521         TAG_LOGE(AAFwkTag::ABILITYMGR, "createRecord error");
522         return result;
523     }
524     CHECK_POINTER_AND_RETURN(extensionRecord, ERR_NULL_OBJECT);
525     std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = extensionRecord->abilityRecord_;
526     CHECK_POINTER_AND_RETURN(abilityRecord, ERR_NULL_OBJECT);
527     extensionRecordId = GenerateExtensionRecordId(extensionRecordId);
528     extensionRecord->extensionRecordId_ = extensionRecordId;
529     extensionRecord->hostBundleName_ = hostBundleName;
530     abilityRecord->SetOwnerMissionUserId(userId_);
531     abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
532     extensionRecord->hostPid_ = IPCSkeleton::GetCallingPid();
533     //add uiextension record register state observer object.
534     if (abilityRecord->GetWant().GetBoolParam(IS_PRELOAD_UIEXTENSION_ABILITY, false)) {
535         auto ret = extensionRecord->RegisterStateObserver(hostBundleName);
536         if (ret != ERR_OK) {
537             TAG_LOGE(AAFwkTag::ABILITYMGR, "Register extensionRecord state observer failed, err: %{public}d.", ret);
538             return ERR_INVALID_VALUE;
539         }
540     }
541     result = UpdateProcessName(abilityRequest, extensionRecord);
542     if (result != ERR_OK) {
543         TAG_LOGE(AAFwkTag::ABILITYMGR, "update processname error!");
544         return result;
545     }
546     TAG_LOGI(AAFwkTag::ABILITYMGR,
547         "extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
548         extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
549     std::lock_guard<std::mutex> lock(mutex_);
550     extensionRecords_[extensionRecordId] = extensionRecord;
551     return ERR_OK;
552 }
553 
GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token)554 std::shared_ptr<AAFwk::AbilityRecord> ExtensionRecordManager::GetUIExtensionRootHostInfo(
555     const sptr<IRemoteObject> token)
556 {
557     if (token == nullptr) {
558         TAG_LOGE(AAFwkTag::ABILITYMGR, "Input param invalid.");
559         return nullptr;
560     }
561 
562     auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
563     if (abilityRecord == nullptr) {
564         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get ability record failed.");
565         return nullptr;
566     }
567 
568     if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
569         TAG_LOGW(AAFwkTag::ABILITYMGR, "Not ui extension ability.");
570         return nullptr;
571     }
572 
573     sptr<IRemoteObject> rootCallerToken = nullptr;
574     auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
575     {
576         std::lock_guard<std::mutex> lock(mutex_);
577         rootCallerToken = GetRootCallerTokenLocked(extensionRecordId, abilityRecord);
578     }
579 
580     if (rootCallerToken == nullptr) {
581         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get root caller record failed.");
582         return nullptr;
583     }
584 
585     return AAFwk::Token::GetAbilityRecordByToken(rootCallerToken);
586 }
587 
GetUIExtensionSessionInfo(const sptr<IRemoteObject> token,UIExtensionSessionInfo & uiExtensionSessionInfo)588 int32_t ExtensionRecordManager::GetUIExtensionSessionInfo(
589     const sptr<IRemoteObject> token, UIExtensionSessionInfo &uiExtensionSessionInfo)
590 {
591     if (token == nullptr) {
592         TAG_LOGE(AAFwkTag::ABILITYMGR, "Input param invalid.");
593         return ERR_NULL_OBJECT;
594     }
595 
596     auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
597     if (abilityRecord == nullptr) {
598         TAG_LOGE(AAFwkTag::ABILITYMGR, "Get ability record failed.");
599         return ERR_NULL_OBJECT;
600     }
601 
602     if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
603         TAG_LOGW(AAFwkTag::ABILITYMGR, "Not ui extension ability.");
604         return ERR_INVALID_VALUE;
605     }
606 
607     auto sessionInfo = abilityRecord->GetSessionInfo();
608     if (sessionInfo == nullptr) {
609         TAG_LOGE(AAFwkTag::ABILITYMGR, "session info is null.");
610         return ERR_NULL_OBJECT;
611     }
612 
613     uiExtensionSessionInfo.persistentId = sessionInfo->persistentId;
614     uiExtensionSessionInfo.hostWindowId = sessionInfo->hostWindowId;
615     uiExtensionSessionInfo.uiExtensionUsage = sessionInfo->uiExtensionUsage;
616     uiExtensionSessionInfo.elementName = abilityRecord->GetElementName();
617     uiExtensionSessionInfo.extensionAbilityType = abilityRecord->GetAbilityInfo().extensionAbilityType;
618     return ERR_OK;
619 }
620 
GetExtensionRecordById(int32_t extensionRecordId)621 std::shared_ptr<ExtensionRecord> ExtensionRecordManager::GetExtensionRecordById(int32_t extensionRecordId)
622 {
623     std::lock_guard<std::mutex> lock(mutex_);
624     auto findRecord = extensionRecords_.find(extensionRecordId);
625     if (findRecord != extensionRecords_.end()) {
626         return findRecord->second;
627     }
628     findRecord = terminateRecords_.find(extensionRecordId);
629     if (findRecord == terminateRecords_.end()) {
630         TAG_LOGE(AAFwkTag::ABILITYMGR, "Ui extension record not found, id: %{public}d.", extensionRecordId);
631         return nullptr;
632     }
633 
634     return findRecord->second;
635 }
636 
LoadTimeout(int32_t extensionRecordId)637 void ExtensionRecordManager::LoadTimeout(int32_t extensionRecordId)
638 {
639     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
640     auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
641     if (uiExtensionRecord == nullptr) {
642         TAG_LOGE(AAFwkTag::ABILITYMGR, "Parsing ui extension record failed.");
643         return;
644     }
645     TAG_LOGD(AAFwkTag::ABILITYMGR, "Start load timeout.");
646     uiExtensionRecord->LoadTimeout();
647 }
648 
ForegroundTimeout(int32_t extensionRecordId)649 void ExtensionRecordManager::ForegroundTimeout(int32_t extensionRecordId)
650 {
651     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
652     auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
653     if (uiExtensionRecord == nullptr) {
654         TAG_LOGE(AAFwkTag::ABILITYMGR, "Parsing ui extension record failed.");
655         return;
656     }
657     TAG_LOGD(AAFwkTag::ABILITYMGR, "Start foreground timeout.");
658     uiExtensionRecord->ForegroundTimeout();
659 }
660 
BackgroundTimeout(int32_t extensionRecordId)661 void ExtensionRecordManager::BackgroundTimeout(int32_t extensionRecordId)
662 {
663     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
664     auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
665     if (uiExtensionRecord == nullptr) {
666         TAG_LOGE(AAFwkTag::ABILITYMGR, "Parsing ui extension record failed.");
667         return;
668     }
669     TAG_LOGD(AAFwkTag::ABILITYMGR, "Start background timeout.");
670     uiExtensionRecord->BackgroundTimeout();
671 }
672 
TerminateTimeout(int32_t extensionRecordId)673 void ExtensionRecordManager::TerminateTimeout(int32_t extensionRecordId)
674 {
675     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
676     auto uiExtensionRecord = std::static_pointer_cast<UIExtensionRecord>(GetExtensionRecordById(extensionRecordId));
677     if (uiExtensionRecord == nullptr) {
678         TAG_LOGE(AAFwkTag::ABILITYMGR, "Parsing ui extension record failed.");
679         return;
680     }
681     TAG_LOGD(AAFwkTag::ABILITYMGR, "Start terminate timeout.");
682     uiExtensionRecord->TerminateTimeout();
683 }
684 
GetCallerTokenList(const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,std::list<sptr<IRemoteObject>> & callerList)685 void ExtensionRecordManager::GetCallerTokenList(
686     const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, std::list<sptr<IRemoteObject>> &callerList)
687 {
688     auto extensionRecordId = abilityRecord->GetUIExtensionAbilityId();
689     auto sessionInfo = abilityRecord->GetSessionInfo();
690     if (!sessionInfo) {
691         TAG_LOGE(AAFwkTag::ABILITYMGR, "sessionInfo null, id: %{public}d", extensionRecordId);
692         callerList.clear();
693         return;
694     }
695 
696     auto callerToken = sessionInfo->callerToken;
697     auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
698     if (callerAbilityRecord == nullptr) {
699         TAG_LOGE(AAFwkTag::ABILITYMGR, "callerRecord null, id: %{public}d", extensionRecordId);
700         callerList.clear();
701         return;
702     }
703 
704     TAG_LOGD(AAFwkTag::ABILITYMGR, "ability: %{public}s, pid: %{public}d, tokenId: %{public}d",
705         callerAbilityRecord->GetWant().GetElement().GetURI().c_str(), callerAbilityRecord->GetPid(),
706         callerAbilityRecord->GetApplicationInfo().accessTokenId);
707 
708     auto callerExtensionRecordId = callerAbilityRecord->GetUIExtensionAbilityId();
709     if (callerExtensionRecordId == INVALID_EXTENSION_RECORD_ID) {
710         TAG_LOGD(AAFwkTag::ABILITYMGR, "Get caller, callerRecord: %{public}d", callerExtensionRecordId);
711         callerList.push_front(callerToken);
712         return;
713     }
714 
715     // If caller extension record id is same with current, need terminate, prevent possible stack-overflow.
716     if (callerExtensionRecordId == extensionRecordId) {
717         TAG_LOGE(AAFwkTag::ABILITYMGR, "callerRecordId: %{public}d, same with caller", extensionRecordId);
718         callerList.clear();
719         return;
720     }
721 
722     callerList.push_front(callerToken);
723     GetCallerTokenList(callerAbilityRecord, callerList);
724 }
725 
IsFocused(int32_t extensionRecordId,const sptr<IRemoteObject> & token,const sptr<IRemoteObject> & focusToken)726 bool ExtensionRecordManager::IsFocused(
727     int32_t extensionRecordId, const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &focusToken)
728 {
729     std::lock_guard<std::mutex> lock(mutex_);
730     auto cachedCaller = GetCachedFocusedCallerToken(extensionRecordId);
731     if (cachedCaller != nullptr && cachedCaller == focusToken) {
732         TAG_LOGD(AAFwkTag::ABILITYMGR, "id: %{public}d has focused", extensionRecordId);
733         return true;
734     }
735 
736     auto abilityRecord = AAFwk::Token::GetAbilityRecordByToken(token);
737     if (!abilityRecord) {
738         return false;
739     }
740 
741     TAG_LOGD(AAFwkTag::ABILITYMGR, "ability: %{public}s, pid: %{public}d, tokenId: %{public}d",
742         abilityRecord->GetWant().GetElement().GetURI().c_str(), abilityRecord->GetPid(),
743         abilityRecord->GetApplicationInfo().accessTokenId);
744 
745     if (!AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
746         TAG_LOGW(AAFwkTag::ABILITYMGR, "Not uiextension");
747         return false;
748     }
749 
750     bool isFocused = false;
751     std::list<sptr<IRemoteObject>> callerList;
752     GetCallerTokenList(abilityRecord, callerList);
753     for (auto& item : callerList) {
754         auto ability = AAFwk::Token::GetAbilityRecordByToken(item);
755         if (ability == nullptr) {
756             TAG_LOGW(AAFwkTag::ABILITYMGR, "Wrong ability");
757             continue;
758         }
759 
760         if (item == focusToken) {
761             isFocused = true;
762             SetCachedFocusedCallerToken(extensionRecordId, item);
763             break;
764         }
765     }
766     return isFocused;
767 }
768 } // namespace AbilityRuntime
769 } // namespace OHOS
770