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