• 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 "core/components_ng/pattern/ui_extension/ui_extension_manager.h"
17 
18 #include "adapter/ohos/entrance/ace_container.h"
19 #include "core/components_ng/pattern/ui_extension/security_ui_extension_pattern.h"
20 #include "core/components_ng/pattern/ui_extension/ui_extension_pattern.h"
21 
22 namespace OHOS::Ace::NG {
UIExtensionIdUtility()23 UIExtensionIdUtility::UIExtensionIdUtility() {}
24 
~UIExtensionIdUtility()25 UIExtensionIdUtility::~UIExtensionIdUtility() {}
26 
ApplyExtensionId()27 int32_t UIExtensionIdUtility::ApplyExtensionId()
28 {
29     std::lock_guard<std::mutex> poolMutex(poolMutex_);
30     for (int32_t index = 0; index < UI_EXTENSION_ID_FIRST_MAX; index++) {
31         if (!idPool_.test(index)) {
32             idPool_.set(index, 1);
33             return index + 1;
34         }
35     }
36     return UI_EXTENSION_UNKNOW_ID;
37 }
38 
RecycleExtensionId(int32_t id)39 void UIExtensionIdUtility::RecycleExtensionId(int32_t id)
40 {
41     std::lock_guard<std::mutex> poolMutex(poolMutex_);
42     if ((id > UI_EXTENSION_UNKNOW_ID) && (id <= UI_EXTENSION_ID_FIRST_MAX)) {
43         idPool_.set(id - 1, 0);
44     }
45 }
46 
RegisterUIExtensionInFocus(const WeakPtr<UIExtensionPattern> & uiExtensionFocused,const WeakPtr<SessionWrapper> & sessionWrapper)47 void UIExtensionManager::RegisterUIExtensionInFocus(
48     const WeakPtr<UIExtensionPattern>& uiExtensionFocused, const WeakPtr<SessionWrapper>& sessionWrapper)
49 {
50     securityUiExtensionFocused_ = nullptr;
51     uiExtensionFocused_ = uiExtensionFocused;
52     sessionWrapper_ = sessionWrapper;
53 }
54 
RegisterSecurityUIExtensionInFocus(const WeakPtr<SecurityUIExtensionPattern> & uiExtensionFocused,const WeakPtr<SessionWrapper> & sessionWrapper)55 void UIExtensionManager::RegisterSecurityUIExtensionInFocus(
56     const WeakPtr<SecurityUIExtensionPattern>& uiExtensionFocused,
57     const WeakPtr<SessionWrapper>& sessionWrapper)
58 {
59     uiExtensionFocused_ = nullptr;
60     securityUiExtensionFocused_ = uiExtensionFocused;
61     sessionWrapper_ = sessionWrapper;
62 }
63 
OnBackPressed()64 bool UIExtensionManager::OnBackPressed()
65 {
66     auto sessionWrapper = sessionWrapper_.Upgrade();
67     if (sessionWrapper) {
68         return sessionWrapper->NotifyBackPressedSync();
69     }
70 
71     return HandleUnfocusedModalUecBackPressed();
72 }
73 
DumpUIExt()74 void UIExtensionManager::DumpUIExt()
75 {
76     auto pattern = uiExtensionFocused_.Upgrade();
77     CHECK_NULL_VOID(pattern);
78     pattern->DumpOthers();
79 }
80 
HandleUnfocusedModalUecBackPressed()81 bool UIExtensionManager::HandleUnfocusedModalUecBackPressed()
82 {
83     RefPtr<SessionWrapper> session = nullptr;
84     {
85         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
86         for (auto item = aliveUIExtensions_.rbegin(); item != aliveUIExtensions_.rend(); ++item) {
87             auto uiExtension = item->second.Upgrade();
88             if (uiExtension == nullptr) {
89                 continue;
90             }
91 
92             if (!uiExtension->IsModalUec()) {
93                 continue;
94             }
95 
96             bool isForeground = uiExtension->IsForeground();
97             bool isLastModal = IsLastModalUec(uiExtension->GetHost());
98             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "HandleUnfocusedModalUecBackPressed,"
99                 " sessionId: %{public}d, isForeground: %{public}d, isLastModal: %{public}d",
100                 uiExtension->GetSessionId(), isForeground, isLastModal);
101             if (!isForeground || !isLastModal) {
102                 continue;
103             }
104 
105             session = uiExtension->GetSessionWrapper();
106             break;
107         }
108     }
109 
110     if (session) {
111         return session->NotifyBackPressedSync();
112     }
113 
114     return false;
115 }
116 
IsLastModalUec(const RefPtr<FrameNode> & frameNode)117 bool UIExtensionManager::IsLastModalUec(const RefPtr<FrameNode>& frameNode)
118 {
119     CHECK_NULL_RETURN(frameNode, false);
120     auto parentNode = frameNode->GetParent();
121     CHECK_NULL_RETURN(parentNode, false);
122     if (parentNode->GetTag() != V2::MODAL_PAGE_TAG) {
123         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
124             "parentNode not modalPage, parentNode tag: %{public}s",
125             parentNode->GetTag().c_str());
126         return false;
127     }
128 
129     auto grandpaNode = parentNode->GetParent();
130     if (grandpaNode == nullptr) {
131         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "ModalPage no parent.");
132         return false;
133     }
134 
135     auto lastChild = grandpaNode->GetLastChild();
136     if (lastChild == nullptr) {
137         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "LastChild is null.");
138         return false;
139     }
140 
141     if (lastChild != parentNode) {
142         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "ModalPage is not the last "
143             "child of rootNode, lastChild tag: %{public}s, parentNode tag: %{public}s",
144             lastChild->GetTag().c_str(), parentNode->GetTag().c_str());
145         return false;
146     }
147 
148     return true;
149 }
150 
IsWrapExtensionAbilityId(int64_t elementId)151 bool UIExtensionManager::IsWrapExtensionAbilityId(int64_t elementId)
152 {
153     return elementId > UI_EXTENSION_OFFSET_MIN;
154 }
155 
SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset,const RefPtr<PipelineBase> & pipeline)156 bool UIExtensionManager::SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo,
157     int64_t uiExtensionOffset, const RefPtr<PipelineBase>& pipeline)
158 {
159     CHECK_NULL_RETURN(pipeline, false);
160     auto instanceId = pipeline->GetInstanceId();
161     auto window = Platform::AceContainer::GetUIWindow(instanceId);
162     CHECK_NULL_RETURN(window, false);
163     OHOS::Rosen::WMError ret = window->TransferAccessibilityEvent(eventInfo, uiExtensionOffset);
164     return ret == OHOS::Rosen::WMError::WM_OK;
165 }
166 
UnWrapExtensionAbilityId(int64_t extensionOffset,int64_t elementId)167 std::pair<int64_t, int64_t> UIExtensionManager::UnWrapExtensionAbilityId(int64_t extensionOffset, int64_t elementId)
168 {
169     if (extensionOffset == 0) {
170         return std::pair<int64_t, int64_t>(0, 0);
171     }
172     int64_t index = elementId / extensionOffset;
173     int64_t abilityId = elementId % extensionOffset;
174     return std::pair<int64_t, int64_t>(index, abilityId);
175 }
176 
GetFocusUiExtensionNode()177 const RefPtr<FrameNode> UIExtensionManager::GetFocusUiExtensionNode()
178 {
179     auto uiExtensionFocused = uiExtensionFocused_.Upgrade();
180     CHECK_NULL_RETURN(uiExtensionFocused, nullptr);
181     return uiExtensionFocused->GetHost();
182 }
183 
ApplyExtensionId()184 int32_t UIExtensionManager::ApplyExtensionId()
185 {
186     return UIExtensionIdUtility::GetInstance().ApplyExtensionId();
187 }
188 
RecycleExtensionId(int32_t id)189 void UIExtensionManager::RecycleExtensionId(int32_t id)
190 {
191     UIExtensionIdUtility::GetInstance().RecycleExtensionId(id);
192 }
193 
AddAliveUIExtension(int32_t nodeId,const WeakPtr<UIExtensionPattern> & uiExtension)194 void UIExtensionManager::AddAliveUIExtension(int32_t nodeId, const WeakPtr<UIExtensionPattern>& uiExtension)
195 {
196     std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
197     aliveUIExtensions_.try_emplace(nodeId, uiExtension);
198 }
199 
AddAliveUIExtension(int32_t nodeId,const WeakPtr<SecurityUIExtensionPattern> & uiExtension)200 void UIExtensionManager::AddAliveUIExtension(
201     int32_t nodeId, const WeakPtr<SecurityUIExtensionPattern>& uiExtension)
202 {
203     aliveSecurityUIExtensions_.try_emplace(nodeId, uiExtension);
204 }
205 
TransferOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)206 void UIExtensionManager::TransferOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
207 {
208     for (const auto& it : aliveUIExtensions_) {
209         auto uiExtension = it.second.Upgrade();
210         if (uiExtension) {
211             uiExtension->DispatchOriginAvoidArea(avoidArea, type);
212         }
213     }
214 
215     for (const auto& it : aliveSecurityUIExtensions_) {
216         auto uiExtension = it.second.Upgrade();
217         if (uiExtension) {
218             uiExtension->DispatchOriginAvoidArea(avoidArea, type);
219         }
220     }
221 }
222 
RemoveDestroyedUIExtension(int32_t nodeId)223 void UIExtensionManager::RemoveDestroyedUIExtension(int32_t nodeId)
224 {
225     {
226         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
227         auto it = aliveUIExtensions_.find(nodeId);
228         if (it != aliveUIExtensions_.end()) {
229             aliveUIExtensions_.erase(nodeId);
230         }
231     }
232 
233     auto iter = aliveSecurityUIExtensions_.find(nodeId);
234     if (iter != aliveSecurityUIExtensions_.end()) {
235         aliveSecurityUIExtensions_.erase(nodeId);
236     }
237 }
238 
NotifyOccupiedAreaChangeInfo(const sptr<Rosen::OccupiedAreaChangeInfo> & info)239 bool UIExtensionManager::NotifyOccupiedAreaChangeInfo(const sptr<Rosen::OccupiedAreaChangeInfo>& info)
240 {
241     int32_t keyboardHeight = static_cast<int32_t>(info->rect_.height_);
242     if (keyboardHeight != 0) {
243         auto sessionWrapper = sessionWrapper_.Upgrade();
244         return sessionWrapper && sessionWrapper->NotifyOccupiedAreaChangeInfo(info, true);
245     }
246     // keyboardHeight is 0, broadcast it.
247     bool ret = false;
248     for (const auto& it : aliveUIExtensions_) {
249         auto uiExtension = it.second.Upgrade();
250         if (uiExtension) {
251             auto session = uiExtension->GetSessionWrapper();
252             if (session && session->IsSessionValid()) {
253                 ret |= session->NotifyOccupiedAreaChangeInfo(info);
254             }
255         }
256     }
257     return ret;
258 }
259 
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)260 void UIExtensionManager::NotifySizeChangeReason(
261     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
262 {
263     for (const auto& it : aliveUIExtensions_) {
264         auto uiExtension = it.second.Upgrade();
265         if (uiExtension) {
266             uiExtension->NotifySizeChangeReason(type, rsTransaction);
267         }
268     }
269 
270     for (const auto& it : aliveSecurityUIExtensions_) {
271         auto uiExtension = it.second.Upgrade();
272         if (uiExtension) {
273             uiExtension->NotifySizeChangeReason(type, rsTransaction);
274         }
275     }
276 }
277 
IsShowPlaceholder(int32_t nodeId)278 bool UIExtensionManager::IsShowPlaceholder(int32_t nodeId)
279 {
280     auto it = aliveUIExtensions_.find(nodeId);
281     if (it != aliveUIExtensions_.end()) {
282         auto uiExtension = it->second.Upgrade();
283         if (uiExtension) {
284             return uiExtension->IsShowPlaceholder();
285         }
286     }
287     return true;
288 }
289 
UIExtBusinessDataSendValid()290 bool UIExtensionManager::UIExtBusinessDataSendValid()
291 {
292     if (!businessSendToHostReplyFunc_ || !businessSendToHostFunc_) {
293         return false;
294     }
295     return true;
296 }
297 
298 // host send data to provider
RegisterBusinessDataSendCallback(UIContentBusinessCode code,BusinessDataSendType type,UIExtBusinessDataSendCallback callback)299 void UIExtensionManager::RegisterBusinessDataSendCallback(
300     UIContentBusinessCode code, BusinessDataSendType type, UIExtBusinessDataSendCallback callback)
301 {
302     businessDataSendCallbacks_.try_emplace(
303         code, std::pair<BusinessDataSendType, UIExtBusinessDataSendCallback>(type, callback));
304 }
305 
TriggerBusinessDataSend(UIContentBusinessCode code)306 bool UIExtensionManager::TriggerBusinessDataSend(UIContentBusinessCode code)
307 {
308     auto it = businessDataSendCallbacks_.find(code);
309     if (it == businessDataSendCallbacks_.end()) {
310         return false;
311     }
312     auto type = it->second.first;
313     auto callback = it->second.second;
314     CHECK_NULL_RETURN(callback, false);
315     bool ret = false;
316     {
317         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
318         for (const auto& pattern : aliveUIExtensions_) {
319             auto uiExtension = pattern.second.Upgrade();
320             if (!uiExtension) {
321                 continue;
322             }
323             // data is std::optional<AAFwk::Want>, if data has value then send it.
324             auto data = callback(uiExtension);
325             if (!data.has_value()) {
326                 continue;
327             }
328             ret |= uiExtension->SendBusinessData(code, std::move(data.value()), type);
329         }
330     }
331     return ret;
332 }
333 
334 // provider consume data
RegisterBusinessDataConsumeCallback(UIContentBusinessCode code,UIExtBusinessDataConsumeCallback callback)335 void UIExtensionManager::RegisterBusinessDataConsumeCallback(
336     UIContentBusinessCode code, UIExtBusinessDataConsumeCallback callback)
337 {
338     businessDataConsumeCallbacks_.try_emplace(code, callback);
339 }
340 
DispatchBusinessDataConsume(UIContentBusinessCode code,const AAFwk::Want & data)341 void UIExtensionManager::DispatchBusinessDataConsume(
342     UIContentBusinessCode code, const AAFwk::Want& data)
343 {
344     auto it = businessDataConsumeCallbacks_.find(code);
345     if (it == businessDataConsumeCallbacks_.end()) {
346         return;
347     }
348     auto callback = it->second;
349     CHECK_NULL_VOID(callback);
350     callback(data);
351 }
352 
RegisterBusinessDataConsumeReplyCallback(UIContentBusinessCode code,UIExtBusinessDataConsumeReplyCallback callback)353 void UIExtensionManager::RegisterBusinessDataConsumeReplyCallback(
354     UIContentBusinessCode code, UIExtBusinessDataConsumeReplyCallback callback)
355 {
356     businessDataConsumeReplyCallbacks_.try_emplace(code, callback);
357 }
358 
DispatchBusinessDataConsumeReply(UIContentBusinessCode code,const AAFwk::Want & data,std::optional<AAFwk::Want> & reply)359 void UIExtensionManager::DispatchBusinessDataConsumeReply(
360     UIContentBusinessCode code, const AAFwk::Want& data, std::optional<AAFwk::Want>& reply)
361 {
362     auto it = businessDataConsumeReplyCallbacks_.find(code);
363     if (it == businessDataConsumeReplyCallbacks_.end()) {
364         return;
365     }
366     auto callback = it->second;
367     CHECK_NULL_VOID(callback);
368     callback(data, reply);
369 }
370 
371 // provider send data to host
RegisterBusinessSendToHostReply(UIExtBusinessSendToHostReplyFunc func)372 void UIExtensionManager::RegisterBusinessSendToHostReply(UIExtBusinessSendToHostReplyFunc func)
373 {
374     businessSendToHostReplyFunc_ = func;
375 }
376 
RegisterBusinessSendToHost(UIExtBusinessSendToHostFunc func)377 void UIExtensionManager::RegisterBusinessSendToHost(UIExtBusinessSendToHostFunc func)
378 {
379     businessSendToHostFunc_ = func;
380 }
381 
SendBusinessToHost(UIContentBusinessCode code,AAFwk::Want && data,BusinessDataSendType type)382 bool UIExtensionManager::SendBusinessToHost(UIContentBusinessCode code, AAFwk::Want&& data, BusinessDataSendType type)
383 {
384     if (!UIExtBusinessDataSendValid()) {
385         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "SendBusinessToHost callback not set.");
386         return false;
387     }
388     auto callback = businessSendToHostFunc_;
389     return callback(static_cast<uint32_t>(code), std::move(data), type);
390 }
391 
SendBusinessToHostSyncReply(UIContentBusinessCode code,AAFwk::Want && data,AAFwk::Want & reply)392 bool UIExtensionManager::SendBusinessToHostSyncReply(UIContentBusinessCode code, AAFwk::Want&& data, AAFwk::Want& reply)
393 {
394     if (!UIExtBusinessDataSendValid()) {
395         TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "SendBusinessToHost callback not set.");
396         return false;
397     }
398     auto callback = businessSendToHostReplyFunc_;
399     return callback(static_cast<uint32_t>(code), std::move(data), reply);
400 }
401 
TransferAccessibilityRectInfo()402 void UIExtensionManager::TransferAccessibilityRectInfo()
403 {
404     {
405         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
406         for (const auto& it : aliveUIExtensions_) {
407             auto uiExtension = it.second.Upgrade();
408             if (uiExtension) {
409                 uiExtension->TransferAccessibilityRectInfo();
410             }
411         }
412     }
413     for (const auto& it : aliveSecurityUIExtensions_) {
414         auto uiExtension = it.second.Upgrade();
415         if (uiExtension) {
416             uiExtension->TransferAccessibilityRectInfo();
417         }
418     }
419 }
420 } // namespace OHOS::Ace::NG
421