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