• 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 
HandleUnfocusedModalUecBackPressed()74 bool UIExtensionManager::HandleUnfocusedModalUecBackPressed()
75 {
76     RefPtr<SessionWrapper> session = nullptr;
77     {
78         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
79         for (auto item = aliveUIExtensions_.rbegin(); item != aliveUIExtensions_.rend(); ++item) {
80             auto uiExtension = item->second.Upgrade();
81             if (uiExtension == nullptr) {
82                 continue;
83             }
84 
85             if (!uiExtension->IsModalUec()) {
86                 continue;
87             }
88 
89             bool isForeground = uiExtension->IsForeground();
90             bool isLastModal = IsLastModalUec(uiExtension->GetHost());
91             TAG_LOGI(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "HandleUnfocusedModalUecBackPressed,"
92                 " sessionId: %{public}d, isForeground: %{public}d, isLastModal: %{public}d",
93                 uiExtension->GetSessionId(), isForeground, isLastModal);
94             if (!isForeground || !isLastModal) {
95                 continue;
96             }
97 
98             session = uiExtension->GetSessionWrapper();
99             break;
100         }
101     }
102 
103     if (session) {
104         return session->NotifyBackPressedSync();
105     }
106 
107     return false;
108 }
109 
IsLastModalUec(const RefPtr<FrameNode> & frameNode)110 bool UIExtensionManager::IsLastModalUec(const RefPtr<FrameNode>& frameNode)
111 {
112     CHECK_NULL_RETURN(frameNode, false);
113     auto parentNode = frameNode->GetParent();
114     CHECK_NULL_RETURN(parentNode, false);
115     if (parentNode->GetTag() != V2::MODAL_PAGE_TAG) {
116         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
117             "parentNode not modalPage, parentNode tag: %{public}s",
118             parentNode->GetTag().c_str());
119         return false;
120     }
121 
122     auto grandpaNode = parentNode->GetParent();
123     if (grandpaNode == nullptr) {
124         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "ModalPage no parent.");
125         return false;
126     }
127 
128     auto lastChild = grandpaNode->GetLastChild();
129     if (lastChild == nullptr) {
130         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "LastChild is null.");
131         return false;
132     }
133 
134     if (lastChild != parentNode) {
135         TAG_LOGW(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "ModalPage is not the last "
136             "child of rootNode, lastChild tag: %{public}s, parentNode tag: %{public}s",
137             lastChild->GetTag().c_str(), parentNode->GetTag().c_str());
138         return false;
139     }
140 
141     return true;
142 }
143 
IsWrapExtensionAbilityId(int64_t elementId)144 bool UIExtensionManager::IsWrapExtensionAbilityId(int64_t elementId)
145 {
146     return elementId > UI_EXTENSION_OFFSET_MIN;
147 }
148 
SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo & eventInfo,int64_t uiExtensionOffset,const RefPtr<PipelineBase> & pipeline)149 bool UIExtensionManager::SendAccessibilityEventInfo(const Accessibility::AccessibilityEventInfo& eventInfo,
150     int64_t uiExtensionOffset, const RefPtr<PipelineBase>& pipeline)
151 {
152     CHECK_NULL_RETURN(pipeline, false);
153     auto instanceId = pipeline->GetInstanceId();
154     auto window = Platform::AceContainer::GetUIWindow(instanceId);
155     CHECK_NULL_RETURN(window, false);
156     OHOS::Rosen::WMError ret = window->TransferAccessibilityEvent(eventInfo, uiExtensionOffset);
157     return ret == OHOS::Rosen::WMError::WM_OK;
158 }
159 
UnWrapExtensionAbilityId(int64_t extensionOffset,int64_t elementId)160 std::pair<int64_t, int64_t> UIExtensionManager::UnWrapExtensionAbilityId(int64_t extensionOffset, int64_t elementId)
161 {
162     if (extensionOffset == 0) {
163         return std::pair<int64_t, int64_t>(0, 0);
164     }
165     int64_t index = elementId / extensionOffset;
166     int64_t abilityId = elementId % extensionOffset;
167     return std::pair<int64_t, int64_t>(index, abilityId);
168 }
169 
GetFocusUiExtensionNode()170 const RefPtr<FrameNode> UIExtensionManager::GetFocusUiExtensionNode()
171 {
172     auto uiExtensionFocused = uiExtensionFocused_.Upgrade();
173     CHECK_NULL_RETURN(uiExtensionFocused, nullptr);
174     return uiExtensionFocused->GetHost();
175 }
176 
ApplyExtensionId()177 int32_t UIExtensionManager::ApplyExtensionId()
178 {
179     return UIExtensionIdUtility::GetInstance().ApplyExtensionId();
180 }
181 
RecycleExtensionId(int32_t id)182 void UIExtensionManager::RecycleExtensionId(int32_t id)
183 {
184     UIExtensionIdUtility::GetInstance().RecycleExtensionId(id);
185 }
186 
AddAliveUIExtension(int32_t nodeId,const WeakPtr<UIExtensionPattern> & uiExtension)187 void UIExtensionManager::AddAliveUIExtension(int32_t nodeId, const WeakPtr<UIExtensionPattern>& uiExtension)
188 {
189     std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
190     aliveUIExtensions_.try_emplace(nodeId, uiExtension);
191 }
192 
AddAliveUIExtension(int32_t nodeId,const WeakPtr<SecurityUIExtensionPattern> & uiExtension)193 void UIExtensionManager::AddAliveUIExtension(
194     int32_t nodeId, const WeakPtr<SecurityUIExtensionPattern>& uiExtension)
195 {
196     aliveSecurityUIExtensions_.try_emplace(nodeId, uiExtension);
197 }
198 
TransferOriginAvoidArea(const Rosen::AvoidArea & avoidArea,uint32_t type)199 void UIExtensionManager::TransferOriginAvoidArea(const Rosen::AvoidArea& avoidArea, uint32_t type)
200 {
201     for (const auto& it : aliveUIExtensions_) {
202         auto uiExtension = it.second.Upgrade();
203         if (uiExtension) {
204             uiExtension->DispatchOriginAvoidArea(avoidArea, type);
205         }
206     }
207 
208     for (const auto& it : aliveSecurityUIExtensions_) {
209         auto uiExtension = it.second.Upgrade();
210         if (uiExtension) {
211             uiExtension->DispatchOriginAvoidArea(avoidArea, type);
212         }
213     }
214 }
215 
RemoveDestroyedUIExtension(int32_t nodeId)216 void UIExtensionManager::RemoveDestroyedUIExtension(int32_t nodeId)
217 {
218     {
219         std::lock_guard<std::mutex> aliveUIExtensionMutex(aliveUIExtensionMutex_);
220         auto it = aliveUIExtensions_.find(nodeId);
221         if (it != aliveUIExtensions_.end()) {
222             aliveUIExtensions_.erase(nodeId);
223         }
224     }
225 
226     auto iter = aliveSecurityUIExtensions_.find(nodeId);
227     if (iter != aliveSecurityUIExtensions_.end()) {
228         aliveSecurityUIExtensions_.erase(nodeId);
229     }
230 }
231 
NotifyOccupiedAreaChangeInfo(const sptr<Rosen::OccupiedAreaChangeInfo> & info)232 bool UIExtensionManager::NotifyOccupiedAreaChangeInfo(const sptr<Rosen::OccupiedAreaChangeInfo>& info)
233 {
234     int32_t keyboardHeight = static_cast<int32_t>(info->rect_.height_);
235     if (keyboardHeight != 0) {
236         auto sessionWrapper = sessionWrapper_.Upgrade();
237         return sessionWrapper && sessionWrapper->NotifyOccupiedAreaChangeInfo(info, true);
238     }
239     // keyboardHeight is 0, broadcast it.
240     bool ret = false;
241     for (const auto& it : aliveUIExtensions_) {
242         auto uiExtension = it.second.Upgrade();
243         if (uiExtension) {
244             auto session = uiExtension->GetSessionWrapper();
245             if (session && session->IsSessionValid()) {
246                 ret |= session->NotifyOccupiedAreaChangeInfo(info);
247             }
248         }
249     }
250     return ret;
251 }
252 
NotifySizeChangeReason(WindowSizeChangeReason type,const std::shared_ptr<Rosen::RSTransaction> & rsTransaction)253 void UIExtensionManager::NotifySizeChangeReason(
254     WindowSizeChangeReason type, const std::shared_ptr<Rosen::RSTransaction>& rsTransaction)
255 {
256     for (const auto& it : aliveUIExtensions_) {
257         auto uiExtension = it.second.Upgrade();
258         if (uiExtension) {
259             uiExtension->NotifySizeChangeReason(type, rsTransaction);
260         }
261     }
262 
263     for (const auto& it : aliveSecurityUIExtensions_) {
264         auto uiExtension = it.second.Upgrade();
265         if (uiExtension) {
266             uiExtension->NotifySizeChangeReason(type, rsTransaction);
267         }
268     }
269 }
270 
IsShowPlaceholder(int32_t nodeId)271 bool UIExtensionManager::IsShowPlaceholder(int32_t nodeId)
272 {
273     auto it = aliveUIExtensions_.find(nodeId);
274     if (it != aliveUIExtensions_.end()) {
275         auto uiExtension = it->second.Upgrade();
276         if (uiExtension) {
277             return uiExtension->IsShowPlaceholder();
278         }
279     }
280     return true;
281 }
282 } // namespace OHOS::Ace::NG
283