• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "hilog_wrapper.h"
20 #include "ui_extension_utils.h"
21 #include "ui_extension_record.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26 constexpr const char* SEPARATOR = ":";
27 constexpr const char* DEFAULT_PROCESS_NAME = "UIExtension";
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     HILOG_DEBUG("constructor.");
34 }
35 
~ExtensionRecordManager()36 ExtensionRecordManager::~ExtensionRecordManager()
37 {
38     HILOG_INFO("deconstructor.");
39 }
40 
GenerateExtensionRecordId(const int32_t extensionRecordId)41 int32_t ExtensionRecordManager::GenerateExtensionRecordId(const int32_t extensionRecordId)
42 {
43     HILOG_DEBUG("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     HILOG_DEBUG("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     HILOG_DEBUG("extensionRecordId %{public}d.", extensionRecordId);
74     std::lock_guard<std::mutex> lock(mutex_);
75     extensionRecords_.erase(extensionRecordId);
76 }
77 
GetExtensionRecord(const int32_t extensionRecordId,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)78 int32_t ExtensionRecordManager::GetExtensionRecord(const int32_t extensionRecordId,
79     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
80 {
81     HILOG_DEBUG("extensionRecordId %{public}d.", extensionRecordId);
82     std::lock_guard<std::mutex> lock(mutex_);
83     // find target record firstly
84     auto it = extensionRecords_.find(extensionRecordId);
85     if (it != extensionRecords_.end() && it->second != nullptr) {
86         // check bundleName
87         HILOG_DEBUG("Stored host bundleName: %{public}s, input bundleName is %{public}s.",
88             it->second->hostBundleName_.c_str(), hostBundleName.c_str());
89         if (it->second->hostBundleName_ == hostBundleName) {
90             extensionRecord = it->second;
91             isLoaded = true;
92             return ERR_OK;
93         }
94     }
95     HILOG_DEBUG("Not found stored id %{public}d.", extensionRecordId);
96     extensionRecord = nullptr;
97     isLoaded = false;
98     return ERR_NULL_OBJECT;
99 }
100 
IsBelongToManager(const AppExecFwk::AbilityInfo & abilityInfo)101 bool ExtensionRecordManager::IsBelongToManager(const AppExecFwk::AbilityInfo &abilityInfo)
102 {
103     // only support UIExtension now
104     return AAFwk::UIExtensionUtils::IsUIExtension(abilityInfo.extensionAbilityType);
105 }
106 
GetOrCreateExtensionRecord(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,bool & isLoaded)107 int32_t ExtensionRecordManager::GetOrCreateExtensionRecord(const AAFwk::AbilityRequest &abilityRequest,
108     const std::string &hostBundleName, std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord, bool &isLoaded)
109 {
110     CHECK_POINTER_AND_RETURN(abilityRequest.sessionInfo, ERR_INVALID_VALUE);
111     abilityRecord = GetAbilityRecordBySessionInfo(abilityRequest.sessionInfo);
112     if (abilityRecord != nullptr) {
113         isLoaded = true;
114         return ERR_OK;
115     }
116     std::shared_ptr<ExtensionRecord> extensionRecord = nullptr;
117     int32_t ret = GetOrCreateExtensionRecordInner(abilityRequest, hostBundleName, extensionRecord, isLoaded);
118     if (ret != ERR_OK) {
119         return ret;
120     }
121     if (extensionRecord != nullptr) {
122         abilityRecord = extensionRecord->abilityRecord_;
123     }
124     return ERR_OK;
125 }
126 
GetAbilityRecordBySessionInfo(const sptr<AAFwk::SessionInfo> & sessionInfo)127 std::shared_ptr<AAFwk::AbilityRecord> ExtensionRecordManager::GetAbilityRecordBySessionInfo(
128     const sptr<AAFwk::SessionInfo> &sessionInfo)
129 {
130     CHECK_POINTER_AND_RETURN(sessionInfo, nullptr);
131     if (sessionInfo->uiExtensionComponentId == INVALID_EXTENSION_RECORD_ID) {
132         HILOG_DEBUG("Extensionability id invalid or not configured.");
133         return nullptr;
134     }
135 
136     std::lock_guard<std::mutex> lock(mutex_);
137     for (const auto& it : extensionRecords_) {
138         if (it.second == nullptr) {
139             continue;
140         }
141         std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = it.second->abilityRecord_;
142         if (abilityRecord == nullptr) {
143             continue;
144         }
145         sptr<AAFwk::SessionInfo> recordSessionInfo = abilityRecord->GetSessionInfo();
146         if (recordSessionInfo == nullptr) {
147             continue;
148         }
149         if (recordSessionInfo->uiExtensionComponentId == sessionInfo->uiExtensionComponentId) {
150             HILOG_DEBUG("found record, uiExtensionComponentId: %{public}" PRIu64, sessionInfo->uiExtensionComponentId);
151             return abilityRecord;
152         }
153     }
154     return nullptr;
155 }
156 
UpdateProcessName(const AAFwk::AbilityRequest & abilityRequest,std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord)157 void ExtensionRecordManager::UpdateProcessName(const AAFwk::AbilityRequest &abilityRequest,
158     std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord)
159 {
160     switch (abilityRequest.extensionProcessMode) {
161         case AppExecFwk::ExtensionProcessMode::INSTANCE: {
162             std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name
163                 + SEPARATOR + std::to_string(abilityRecord->GetUIExtensionAbilityId());
164             abilityRecord->SetProcessName(process);
165             break;
166         }
167         case AppExecFwk::ExtensionProcessMode::TYPE: {
168             std::string process = abilityRequest.abilityInfo.bundleName + SEPARATOR + abilityRequest.abilityInfo.name;
169             abilityRecord->SetProcessName(process);
170             break;
171         }
172         default: // AppExecFwk::ExtensionProcessMode::UNDEFINED or AppExecFwk::ExtensionProcessMode::BUNDLE
173             // no need to update
174             break;
175     }
176 }
177 
GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest & abilityRequest,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,bool & isLoaded)178 int32_t ExtensionRecordManager::GetOrCreateExtensionRecordInner(const AAFwk::AbilityRequest &abilityRequest,
179     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, bool &isLoaded)
180 {
181     // factory pattern with ability request
182     if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRequest.abilityInfo.extensionAbilityType)) {
183         int32_t extensionRecordId = UIExtensionRecord::NeedReuse(abilityRequest);
184         if (extensionRecordId != INVALID_EXTENSION_RECORD_ID) {
185             HILOG_DEBUG("reuse record, id: %{public}d", extensionRecordId);
186             int32_t ret = GetExtensionRecord(extensionRecordId, hostBundleName, extensionRecord, isLoaded);
187             if (ret == ERR_OK) {
188                 extensionRecord->Update(abilityRequest);
189             }
190             return ret;
191         }
192         std::shared_ptr<AAFwk::AbilityRecord> abilityRecord = AAFwk::AbilityRecord::CreateAbilityRecord(abilityRequest);
193         if (abilityRecord == nullptr) {
194             HILOG_ERROR("Failed to create ability record");
195             return ERR_NULL_OBJECT;
196         }
197         abilityRecord->SetOwnerMissionUserId(userId_);
198         int32_t ret = CreateExtensionRecord(abilityRecord, hostBundleName, extensionRecord, extensionRecordId);
199         if (ret != ERR_OK) {
200             HILOG_ERROR("Failed to create extension record, ret: %{public}d", ret);
201             return ret;
202         }
203         UpdateProcessName(abilityRequest, abilityRecord);
204         HILOG_DEBUG("extensionRecordId: %{public}d, extensionProcessMode:%{public}d, process: %{public}s",
205             extensionRecordId, abilityRequest.extensionProcessMode, abilityRecord->GetAbilityInfo().process.c_str());
206         isLoaded = false;
207         return ERR_OK;
208     }
209     return ERR_INVALID_VALUE;
210 }
211 
StartAbility(const AAFwk::AbilityRequest & abilityRequest)212 int32_t ExtensionRecordManager::StartAbility(const AAFwk::AbilityRequest &abilityRequest)
213 {
214     return ERR_OK;
215 }
216 
IsFocused(int32_t extensionRecordId,const sptr<IRemoteObject> & focusToken)217 bool ExtensionRecordManager::IsFocused(int32_t extensionRecordId, const sptr<IRemoteObject>& focusToken)
218 {
219     std::lock_guard<std::mutex> lock(mutex_);
220     sptr<IRemoteObject> rootCallerToken = GetRootCallerTokenLocked(extensionRecordId);
221     bool isFocused = rootCallerToken == focusToken;
222     HILOG_DEBUG("id: %{public}d isFocused: %{public}d.", extensionRecordId, isFocused);
223     return isFocused;
224 }
225 
GetRootCallerTokenLocked(int32_t extensionRecordId)226 sptr<IRemoteObject> ExtensionRecordManager::GetRootCallerTokenLocked(int32_t extensionRecordId)
227 {
228     auto it = extensionRecords_.find(extensionRecordId);
229     if (it != extensionRecords_.end() && it->second != nullptr) {
230         sptr<IRemoteObject> rootCallerToken = it->second->GetRootCallerToken();
231         if (rootCallerToken != nullptr) {
232             return rootCallerToken;
233         }
234         if (!it->second->ContinueToGetCallerToken()) {
235             return it->second->GetCallToken();
236         }
237         auto callerToken = it->second->GetCallToken();
238         if (callerToken == nullptr) {
239             HILOG_ERROR("callerToken is null, id: %{public}d.", extensionRecordId);
240             return nullptr;
241         }
242         auto callerAbilityRecord = AAFwk::Token::GetAbilityRecordByToken(callerToken);
243         if (callerAbilityRecord == nullptr) {
244             HILOG_ERROR("callerAbilityRecord is null, id: %{public}d.", extensionRecordId);
245             return nullptr;
246         }
247         if (callerAbilityRecord->GetUIExtensionAbilityId() == INVALID_EXTENSION_RECORD_ID) {
248             HILOG_DEBUG("update rootCallerToken, id: %{public}d.", extensionRecordId);
249             it->second->SetRootCallerToken(callerToken);
250             return callerToken;
251         }
252         rootCallerToken = GetRootCallerTokenLocked(callerAbilityRecord->GetUIExtensionAbilityId());
253         HILOG_DEBUG("update rootCallerToken, id: %{public}d.", extensionRecordId);
254         it->second->SetRootCallerToken(rootCallerToken);
255         return rootCallerToken;
256     }
257     HILOG_ERROR("Not found id %{public}d.", extensionRecordId);
258     return nullptr;
259 }
260 
CreateExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> & abilityRecord,const std::string & hostBundleName,std::shared_ptr<ExtensionRecord> & extensionRecord,int32_t & extensionRecordId)261 int32_t ExtensionRecordManager::CreateExtensionRecord(const std::shared_ptr<AAFwk::AbilityRecord> &abilityRecord,
262     const std::string &hostBundleName, std::shared_ptr<ExtensionRecord> &extensionRecord, int32_t &extensionRecordId)
263 {
264     // factory pattern with ability request
265     if (abilityRecord == nullptr) {
266         HILOG_ERROR("abilityRecord is null");
267         return ERR_NULL_OBJECT;
268     }
269     extensionRecordId = GenerateExtensionRecordId(extensionRecordId);
270     if (AAFwk::UIExtensionUtils::IsUIExtension(abilityRecord->GetAbilityInfo().extensionAbilityType)) {
271         extensionRecord = std::make_shared<UIExtensionRecord>(abilityRecord, hostBundleName, extensionRecordId);
272         std::lock_guard<std::mutex> lock(mutex_);
273         HILOG_DEBUG("add UIExtension, id %{public}d.", extensionRecordId);
274         extensionRecords_[extensionRecordId] = extensionRecord;
275         abilityRecord->SetUIExtensionAbilityId(extensionRecordId);
276         return ERR_OK;
277     }
278     return ERR_INVALID_VALUE;
279 }
280 } // namespace AbilityRuntime
281 } // namespace OHOS
282