• 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/app_bar/app_bar_view.h"
17 #include <cstdint>
18 #include "ui/base/geometry/dimension.h"
19 #include "ui/base/utils/utils.h"
20 
21 #include "bridge/declarative_frontend/view_stack_processor.h"
22 #include "core/common/app_bar_helper.h"
23 #include "core/common/container.h"
24 #include "core/common/container_scope.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/event/focus_hub.h"
27 #include "core/components_ng/layout/layout_property.h"
28 #include "core/components_ng/pattern/app_bar/atomic_service_pattern.h"
29 #include "core/components_ng/pattern/button/button_layout_property.h"
30 #include "core/components_ng/pattern/button/button_pattern.h"
31 #include "core/components_ng/pattern/divider/divider_pattern.h"
32 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
33 #include "core/components_ng/pattern/text/text_pattern.h"
34 #include "core/components_ng/pattern/app_bar/app_bar_utils.h"
35 #include "core/components_ng/base/inspector.h"
36 
37 namespace OHOS::Ace::NG {
38 std::function<RefPtr<FrameNode>(NG::AppBarView* appBar, const RefPtr<FrameNode>& stage)>
39     AppBarView::appBarNodeBuilder_ = nullptr;
40 namespace {
41 
42 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_WIDTH = 96;
43 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_MARGIN_RIGHT = 8;
44 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_MARGIN_LEFT = 12;
45 constexpr int32_t INVALID_LISTENER_ID = -1;
46 constexpr int32_t MENU_BAR_AY_Z_INDEX = -2;
47 
GetAppBarTheme()48 RefPtr<AppBarTheme> GetAppBarTheme()
49 {
50     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
51     CHECK_NULL_RETURN(pipeline, nullptr);
52     return pipeline->GetTheme<AppBarTheme>();
53 }
54 
55 #ifndef PREVIEW
AssembleUiExtensionParams(bool firstTry,std::string & appGalleryBundleName,std::map<std::string,std::string> & params)56 void AssembleUiExtensionParams(
57     bool firstTry, std::string& appGalleryBundleName, std::map<std::string, std::string>& params)
58 {
59     auto missionId = AceApplicationInfo::GetInstance().GetMissionId();
60     params.try_emplace("bundleName", AceApplicationInfo::GetInstance().GetProcessName());
61     params.try_emplace("abilityName", AceApplicationInfo::GetInstance().GetAbilityName());
62     auto container = Container::Current();
63     CHECK_NULL_VOID(container);
64     params.try_emplace("module", container->GetModuleName());
65     if (missionId != -1) {
66         params.try_emplace("missionId", std::to_string(missionId));
67     }
68     auto frontend = container->GetFrontend();
69     if (frontend) {
70         auto info = frontend->GetTopNavDestinationInfo(false, true);
71         params.try_emplace("TopNavPathInfo", info);
72     }
73     if (firstTry) {
74         params.try_emplace("ability.want.params.uiExtensionType", "sysDialog/atomicServicePanel");
75         appGalleryBundleName = OHOS::Ace::SystemProperties::GetAtomicServiceBundleName();
76     } else {
77         params.try_emplace("ability.want.params.uiExtensionType", "sys/commonUI");
78         appGalleryBundleName = OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName();
79     }
80 }
81 #endif
82 } // namespace
83 
SetOnBackPressedConsumed()84 void AppBarView::SetOnBackPressedConsumed()
85 {
86     auto atomicService = atomicService_.Upgrade();
87     CHECK_NULL_VOID(atomicService);
88     auto atomicServicePattern = atomicService->GetPattern<NG::AtomicServicePattern>();
89     CHECK_NULL_VOID(atomicServicePattern);
90     atomicServicePattern->SetOnBackPressedConsumed();
91 }
92 
GetAtomicServicePattern()93 RefPtr<Pattern> AppBarView::GetAtomicServicePattern()
94 {
95     auto atomicService = atomicService_.Upgrade();
96     CHECK_NULL_RETURN(atomicService, nullptr);
97     return atomicService->GetPattern<NG::AtomicServicePattern>();
98 }
99 
RegistAppBarNodeBuilder(std::function<RefPtr<FrameNode> (NG::AppBarView * appBar,const RefPtr<FrameNode> & stage)> appBarNodeBuilder)100 void AppBarView::RegistAppBarNodeBuilder(
101     std::function<RefPtr<FrameNode>(NG::AppBarView* appBar, const RefPtr<FrameNode>& stage)> appBarNodeBuilder)
102 {
103     appBarNodeBuilder_ = appBarNodeBuilder;
104 }
105 
Create(const RefPtr<FrameNode> & stage)106 RefPtr<FrameNode> AppBarView::Create(const RefPtr<FrameNode>& stage)
107 {
108     auto atom = FrameNode::CreateFrameNode(V2::ATOMIC_SERVICE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
109         AceType::MakeRefPtr<AtomicServicePattern>());
110     // add children
111     if (appBarNodeBuilder_) {
112         // app bar builder for cj frontend
113         return appBarNodeBuilder_(this, stage);
114     }
115     contentStage_ = stage;
116     atomicService_ = atom;
117     BindJSContainer();
118     // init
119     atom->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
120     stage->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
121     return atom;
122 }
123 
BindJSContainer()124 void AppBarView::BindJSContainer()
125 {
126     auto atom = atomicService_.Upgrade();
127     CHECK_NULL_VOID(atom);
128     auto isSucc = ExecuteCustomAppBarAbc();
129     if (!isSucc) {
130         return;
131     }
132     auto customAppBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomAppBarNode();
133     CHECK_NULL_VOID(customAppBarNode);
134     atom->AddChild(customAppBarNode);
135     auto pattern = atom->GetPattern<AtomicServicePattern>();
136     CHECK_NULL_VOID(pattern);
137     pattern->AppInfoCallBack();
138     pattern->AppScreenCallBack();
139     pattern->AppBgColorCallBack();
140 }
141 
BuildAppbar(RefPtr<PipelineBase> pipleline)142 void AppBarView::BuildAppbar(RefPtr<PipelineBase> pipleline)
143 {
144     CHECK_NULL_VOID(pipleline);
145     auto pipelineContext = AceType::DynamicCast<PipelineContext>(pipleline);
146     CHECK_NULL_VOID(pipelineContext);
147     auto container = Container::GetContainer(pipelineContext->GetInstanceId());
148     CHECK_NULL_VOID(container);
149     auto appbar = container->GetAppBar();
150     CHECK_NULL_VOID(appbar);
151     auto atom = appbar->atomicService_.Upgrade();
152     CHECK_NULL_VOID(atom);
153     auto customAppBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomAppBarNode();
154     CHECK_NULL_VOID(customAppBarNode);
155     customAppBarNode->Build(nullptr);
156     auto stageNodeWrapperNode = Inspector::GetInspectorByKey(atom, "AtomicServiceStageId");
157     CHECK_NULL_VOID(stageNodeWrapperNode);
158     auto stageNodeWrapper = AceType::DynamicCast<FrameNode>(stageNodeWrapperNode);
159     CHECK_NULL_VOID(stageNodeWrapper);
160     CHECK_NULL_VOID(appbar->contentStage_);
161     auto pattern = atom->GetPattern<AtomicServicePattern>();
162     CHECK_NULL_VOID(pattern);
163     pattern->BeforeCreateLayoutWrapper();
164     InitAccessibility(Inspector::GetInspectorByKey(atom, "AtomicServiceMenubarRowId"));
165     stageNodeWrapper->AddChild(appbar->contentStage_);
166     stageNodeWrapper->MarkModifyDone();
167     stageNodeWrapper->MarkDirtyNode(PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
168 }
169 
InitAccessibility(RefPtr<UINode> uiNode)170 void AppBarView::InitAccessibility(RefPtr<UINode> uiNode)
171 {
172     CHECK_NULL_VOID(uiNode);
173     auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
174     CHECK_NULL_VOID(frameNode);
175     auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
176     CHECK_NULL_VOID(accessibilityProperty);
177     accessibilityProperty->SetAccessibilityZIndex(MENU_BAR_AY_Z_INDEX);
178 }
179 
BuildMenuBarRow()180 RefPtr<FrameNode> AppBarView::BuildMenuBarRow()
181 {
182     auto menuBarRow = FrameNode::CreateFrameNode(V2::APP_BAR_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
183         AceType::MakeRefPtr<LinearLayoutPattern>(false));
184     auto theme = GetAppBarTheme();
185     CHECK_NULL_RETURN(theme, nullptr);
186 
187     auto menuBar = BuildMenuBar();
188     menuBarRow->AddChild(menuBar);
189 
190     auto layoutProperty = menuBarRow->GetLayoutProperty<LinearLayoutProperty>();
191     auto renderContext = menuBarRow->GetRenderContext();
192     // size
193     layoutProperty->UpdateUserDefinedIdealSize(
194         CalcSize(CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(theme->GetMenuBarHeight())));
195     // main axis align
196     layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_END);
197     // position
198     renderContext->UpdatePosition(OffsetT<Dimension>(0.0_vp, theme->GetMenuBarTopMargin()));
199     // background color
200     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
201     // hit test mode
202     menuBarRow->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
203 
204     menuBarRow->MarkModifyDone();
205     return menuBarRow;
206 }
207 
BuildMenuBar()208 RefPtr<FrameNode> AppBarView::BuildMenuBar()
209 {
210     auto menuBar = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
211         AceType::MakeRefPtr<LinearLayoutPattern>(false));
212     auto theme = GetAppBarTheme();
213     CHECK_NULL_RETURN(theme, nullptr);
214 
215     auto menuButton = BuildButton(true);
216     BindMenuCallback(menuButton);
217     menuBar->AddChild(menuButton);
218     auto divider = BuildDivider();
219     menuBar->AddChild(divider);
220     auto closeButton = BuildButton(false);
221     BindCloseCallback(closeButton);
222     menuBar->AddChild(closeButton);
223 
224     auto layoutProperty = menuBar->GetLayoutProperty<LinearLayoutProperty>();
225     auto renderContext = menuBar->GetRenderContext();
226     // main axis align
227     layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START);
228     // border width
229     BorderWidthProperty borderWidth;
230     borderWidth.SetBorderWidth(theme->GetBorderWidth());
231     layoutProperty->UpdateBorderWidth(borderWidth);
232     renderContext->UpdateBorderWidth(borderWidth);
233     // border radius
234     auto bent = theme->GetBentRadius();
235     renderContext->UpdateBorderRadius(BorderRadiusProperty(bent));
236 
237     menuBar->MarkModifyDone();
238     return menuBar;
239 }
240 
BuildButton(bool isMenuButton)241 RefPtr<FrameNode> AppBarView::BuildButton(bool isMenuButton)
242 {
243     auto button = FrameNode::CreateFrameNode(
244         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
245     auto renderContext = button->GetRenderContext();
246     renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
247     auto theme = GetAppBarTheme();
248     CHECK_NULL_RETURN(theme, nullptr);
249 
250     auto icon = BuildIcon(isMenuButton);
251     button->AddChild(icon);
252 
253     auto layoutProperty = button->GetLayoutProperty<ButtonLayoutProperty>();
254     // type
255     layoutProperty->UpdateType(ButtonType::NORMAL);
256     // size
257     layoutProperty->UpdateUserDefinedIdealSize(
258         CalcSize(CalcLength(theme->GetButtonWidth()), CalcLength(theme->GetButtonHeight())));
259     // focus style type
260     auto focusHub = button->GetFocusHub();
261     CHECK_NULL_RETURN(focusHub, nullptr);
262     focusHub->SetFocusStyleType(FocusStyleType::INNER_BORDER);
263     // focus border width
264     auto buttonPattern = button->GetPattern<ButtonPattern>();
265     CHECK_NULL_RETURN(buttonPattern, nullptr);
266     buttonPattern->SetFocusBorderWidth(theme->GetFocusedOutlineWidth());
267 
268     button->MarkModifyDone();
269     return button;
270 }
271 
BuildIcon(bool isMenuIcon)272 RefPtr<FrameNode> AppBarView::BuildIcon(bool isMenuIcon)
273 {
274     auto icon = FrameNode::CreateFrameNode(
275         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
276     auto theme = GetAppBarTheme();
277     CHECK_NULL_RETURN(theme, nullptr);
278 
279     ImageSourceInfo imageSourceInfo;
280     imageSourceInfo.SetResourceId(
281         isMenuIcon ? InternalResource::ResourceId::APP_BAR_MENU_SVG : InternalResource::ResourceId::APP_BAR_CLOSE_SVG);
282     auto layoutProperty = icon->GetLayoutProperty<ImageLayoutProperty>();
283     layoutProperty->UpdateImageSourceInfo(imageSourceInfo);
284     // size
285     layoutProperty->UpdateUserDefinedIdealSize(
286         CalcSize(CalcLength(theme->GetNewIconSize()), CalcLength(theme->GetNewIconSize())));
287     // focusable
288     auto focusHub = icon->GetFocusHub();
289     CHECK_NULL_RETURN(focusHub, nullptr);
290     focusHub->SetFocusable(true);
291 
292     icon->MarkModifyDone();
293     return icon;
294 }
295 
BuildDivider()296 RefPtr<FrameNode> AppBarView::BuildDivider()
297 {
298     auto divider = FrameNode::CreateFrameNode(
299         V2::DIVIDER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<DividerPattern>());
300     auto theme = GetAppBarTheme();
301     CHECK_NULL_RETURN(theme, nullptr);
302 
303     auto layoutProperty = divider->GetLayoutProperty<DividerLayoutProperty>();
304     // size
305     layoutProperty->UpdateUserDefinedIdealSize(
306         CalcSize(CalcLength(theme->GetDividerWidth()), CalcLength(theme->GetDividerHeight())));
307     // direction
308     layoutProperty->UpdateVertical(true);
309     // stroke width
310     layoutProperty->UpdateStrokeWidth(theme->GetDividerWidth());
311     // marigin
312     MarginProperty margin;
313     margin.left = CalcLength(-(theme->GetDividerWidth()));
314     auto renderProperty = divider->GetPaintProperty<DividerRenderProperty>();
315     // line cap
316     renderProperty->UpdateLineCap(LineCap::ROUND);
317 
318     divider->MarkModifyDone();
319     return divider;
320 }
321 
BindMenuCallback(const RefPtr<FrameNode> & menuButton)322 void AppBarView::BindMenuCallback(const RefPtr<FrameNode>& menuButton)
323 {
324     auto clickCallback = [wp = WeakClaim(this)](GestureEvent& info) {
325 #ifdef PREVIEW
326         LOGW("[Engine Log] Unable to show the SharePanel in the Previewer. "
327              "Perform this operation on the emulator or a real device instead.");
328 #else
329         auto appbarView = wp.Upgrade();
330         CHECK_NULL_VOID(appbarView);
331         auto node = appbarView->atomicService_.Upgrade();
332         auto pipeline = node->GetContext();
333         CHECK_NULL_VOID(pipeline);
334         auto theme = pipeline->GetTheme<AppBarTheme>();
335         CHECK_NULL_VOID(theme);
336         if (SystemProperties::GetExtSurfaceEnabled()) {
337             LOGI("start panel bundleName is %{public}s, abilityName is %{public}s", theme->GetBundleName().c_str(),
338                 theme->GetAbilityName().c_str());
339             pipeline->FireSharePanelCallback(theme->GetBundleName(), theme->GetAbilityName());
340         } else {
341             appbarView->CreateServicePanel(true);
342         }
343 #endif
344     };
345     auto eventHub = menuButton->GetOrCreateGestureEventHub();
346     if (eventHub) {
347         eventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback)));
348     }
349 }
350 
BindCloseCallback(const RefPtr<FrameNode> & closeButton)351 void AppBarView::BindCloseCallback(const RefPtr<FrameNode>& closeButton)
352 {
353     auto clickCallback = [](GestureEvent& info) {
354         auto pipeline = PipelineContext::GetCurrentContext();
355         CHECK_NULL_VOID(pipeline);
356         auto container = Container::Current();
357         CHECK_NULL_VOID(container);
358         if (container->IsUIExtensionWindow()) {
359             container->TerminateUIExtension();
360         } else {
361             auto windowManager = pipeline->GetWindowManager();
362             CHECK_NULL_VOID(windowManager);
363             windowManager->WindowPerformBack();
364         }
365     };
366     auto eventHub = closeButton->GetOrCreateGestureEventHub();
367     if (eventHub) {
368         eventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback)));
369     }
370 }
371 
DestroyServicePanel()372 void AppBarView::DestroyServicePanel()
373 {
374     auto node = atomicService_.Upgrade();
375     auto pipeline = node->GetContext();
376     CHECK_NULL_VOID(pipeline);
377     auto overlayManager = pipeline->GetOverlayManager();
378     CHECK_NULL_VOID(overlayManager);
379     ContainerScope scope(pipeline->GetInstanceId());
380     overlayManager->CloseModalUIExtension(sessionId_);
381     LOGI("ServicePanel release session:%{public}d", sessionId_);
382 }
383 
CreateServicePanel(const std::string & appGalleryBundleName,const std::string & abilityName,std::map<std::string,std::string> & params)384 void AppBarView::CreateServicePanel(
385     const std::string& appGalleryBundleName, const std::string& abilityName, std::map<std::string, std::string>& params)
386 {
387 #ifndef PREVIEW
388     if (OHOS::Ace::SystemProperties::GetAtomicServiceBundleName().empty() &&
389         OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName().empty()) {
390         LOGE("UIExtension BundleName is empty.");
391         return;
392     }
393 
394     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
395     CHECK_NULL_VOID(pipeline);
396     auto overlayManager = pipeline->GetOverlayManager();
397     CHECK_NULL_VOID(overlayManager);
398 
399     ModalUIExtensionCallbacks callbacks;
400     callbacks.onRelease = [wp = WeakClaim(this)](int32_t releaseCode) {
401         auto bar = wp.Upgrade();
402         bar->DestroyServicePanel();
403     };
404     callbacks.onError = [wp = WeakClaim(this)](int32_t code, const std::string& name, const std::string& message) {
405         auto bar = wp.Upgrade();
406         bar->DestroyServicePanel();
407     };
408     auto wantWrap = WantWrap::CreateWantWrap(appGalleryBundleName, abilityName);
409     wantWrap->SetWantParam(params);
410     LOGI("ServicePanel request bundle: %{public}s, ability: %{public}s. "
411          "UIExtension bundle: %{public}s, ability: %{public}s, module: %{public}s",
412         appGalleryBundleName.c_str(), abilityName.c_str(), params["bundleName"].c_str(), params["abilityName"].c_str(),
413         params["module"].c_str());
414     ModalUIExtensionConfig config;
415     sessionId_ = overlayManager->CreateModalUIExtension(wantWrap, callbacks, config);
416 #endif
417 }
418 
CreateServicePanel(bool firstTry)419 void AppBarView::CreateServicePanel(bool firstTry)
420 {
421 #ifndef PREVIEW
422     if (OHOS::Ace::SystemProperties::GetAtomicServiceBundleName().empty() &&
423         OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName().empty()) {
424         LOGE("UIExtension BundleName is empty.");
425         return;
426     }
427 
428     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
429     CHECK_NULL_VOID(pipeline);
430     auto overlayManager = pipeline->GetOverlayManager();
431     CHECK_NULL_VOID(overlayManager);
432 
433     ModalUIExtensionCallbacks callbacks;
434     callbacks.onRelease = [wp = WeakClaim(this)](int32_t releaseCode) {
435         auto bar = wp.Upgrade();
436         bar->DestroyServicePanel();
437     };
438     callbacks.onError = [wp = WeakClaim(this), firstTry](
439                             int32_t code, const std::string& name, const std::string& message) {
440         auto bar = wp.Upgrade();
441         bar->DestroyServicePanel();
442         if (firstTry) {
443             bar->CreateServicePanel(false);
444         }
445     };
446     std::string abilityName;
447     auto theme = pipeline->GetTheme<AppBarTheme>();
448     if (theme) {
449         abilityName = theme->GetStageAbilityName();
450     }
451     std::string appGalleryBundleName;
452     std::map<std::string, std::string> params;
453     AssembleUiExtensionParams(firstTry, appGalleryBundleName, params);
454     auto wantWrap = WantWrap::CreateWantWrap(appGalleryBundleName, abilityName);
455     wantWrap->SetWantParam(params);
456     LOGI("ServicePanel request bundle: %{public}s, ability: %{public}s. "
457          "UIExtension bundle: %{public}s, ability: %{public}s, module: %{public}s",
458         appGalleryBundleName.c_str(), abilityName.c_str(), params["bundleName"].c_str(), params["abilityName"].c_str(),
459         params["module"].c_str());
460     ModalUIExtensionConfig config;
461     sessionId_ = overlayManager->CreateModalUIExtension(wantWrap, callbacks, config);
462 #endif
463 }
464 
InitUIExtensionNode(const RefPtr<FrameNode> & uiExtNode)465 void AppBarView::InitUIExtensionNode(const RefPtr<FrameNode>& uiExtNode)
466 {
467     CHECK_NULL_VOID(uiExtNode);
468     // Update ideal size of UIExtension.
469     auto layoutProperty = uiExtNode->GetLayoutProperty();
470     layoutProperty->UpdateUserDefinedIdealSize(CalcSize(
471         CalcLength(Dimension(1.0, DimensionUnit::PERCENT)), CalcLength(Dimension(1.0, DimensionUnit::PERCENT))));
472     uiExtNode->MarkModifyDone();
473 }
474 
GetAppBarRect()475 std::optional<RectF> AppBarView::GetAppBarRect()
476 {
477     auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
478     if (!pipeline || !pipeline->GetInstallationFree()) {
479         return std::nullopt;
480     }
481     auto theme = GetAppBarTheme();
482     CHECK_NULL_RETURN(theme, std::nullopt);
483     auto atom = atomicService_.Upgrade();
484     CHECK_NULL_RETURN(atom, std::nullopt);
485     auto pattern = atom->GetPattern<AtomicServicePattern>();
486     CHECK_NULL_RETURN(pattern, std::nullopt);
487     auto menuBarRow = pattern->GetMenuBarRow();
488     CHECK_NULL_RETURN(menuBarRow, std::nullopt);
489     auto rowGeometryNode = menuBarRow->GetGeometryNode();
490     CHECK_NULL_RETURN(rowGeometryNode, std::nullopt);
491     auto menuBar = pattern->GetMenuBar();
492     CHECK_NULL_RETURN(menuBar, std::nullopt);
493     auto geometryNode = menuBar->GetGeometryNode();
494     CHECK_NULL_RETURN(geometryNode, std::nullopt);
495     auto size = geometryNode->GetMarginFrameSize();
496     auto offset = geometryNode->GetMarginFrameOffset();
497     auto parent = menuBar->GetParent();
498     while (parent) {
499         auto frameNode = AceType::DynamicCast<FrameNode>(parent);
500         if (frameNode) {
501             offset += frameNode->GetGeometryNode()->GetFrameOffset();
502         }
503         parent = parent->GetParent();
504     }
505     auto atomRect = atom->GetGeometryNode()->GetFrameRect();
506     bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
507     auto defalutLeftMargin = Dimension(ATOMIC_SERVICE_MENU_BAR_MARGIN_LEFT, DimensionUnit::VP).ConvertToPx();
508     auto defalutRightMargin = Dimension(ATOMIC_SERVICE_MENU_BAR_MARGIN_RIGHT, DimensionUnit::VP).ConvertToPx();
509     auto left = defalutLeftMargin;
510     auto right = defalutRightMargin;
511     if (rowGeometryNode->GetMargin()) {
512         left = rowGeometryNode->GetMargin()->left.value_or(defalutLeftMargin);
513         right = rowGeometryNode->GetMargin()->right.value_or(defalutRightMargin);
514     }
515     if (LessOrEqual(offset.GetX(), 0.0) && atomRect.Width() > 0) {
516         auto width = Dimension(ATOMIC_SERVICE_MENU_BAR_WIDTH, DimensionUnit::VP).ConvertToPx();
517         offset.SetX(isRtl ? (right) : (atomRect.Width() - width - left));
518     } else {
519         auto addEnd = isRtl ? left : right;
520         size.AddWidth((defalutLeftMargin + addEnd));
521         offset.AddX(isRtl ? -addEnd : -defalutLeftMargin);
522     }
523     return RectF(offset, size);
524 }
525 
SetStatusBarItemColor(bool isLight)526 void AppBarView::SetStatusBarItemColor(bool isLight)
527 {
528     auto atom = atomicService_.Upgrade();
529     CHECK_NULL_VOID(atom);
530     auto pattern = atom->GetPattern<AtomicServicePattern>();
531     CHECK_NULL_VOID(pattern);
532     auto theme = GetAppBarTheme();
533     auto menuBar = pattern->GetMenuBar();
534     pattern->settedColorMode = isLight;
535     pattern->ColorConfigurationCallBack();
536 }
537 
OnMenuClick()538 void AppBarView::OnMenuClick()
539 {
540     auto atom = atomicService_.Upgrade();
541     CHECK_NULL_VOID(atom);
542     auto pipeline = atom->GetContext();
543     CHECK_NULL_VOID(pipeline);
544     auto theme = pipeline->GetTheme<AppBarTheme>();
545     CHECK_NULL_VOID(theme);
546     if (SystemProperties::GetExtSurfaceEnabled()) {
547         LOGI("start panel bundleName is %{public}s, abilityName is %{public}s", theme->GetBundleName().c_str(),
548             theme->GetAbilityName().c_str());
549         pipeline->FireSharePanelCallback(theme->GetBundleName(), theme->GetAbilityName());
550     } else {
551         CreateServicePanel(true);
552     }
553 }
554 
OnCloseClick()555 void AppBarView::OnCloseClick()
556 {
557     auto atom = atomicService_.Upgrade();
558     CHECK_NULL_VOID(atom);
559     auto pipeline = atom->GetContext();
560     CHECK_NULL_VOID(pipeline);
561     auto container = Container::Current();
562     CHECK_NULL_VOID(container);
563     TAG_LOGI(AceLogTag::ACE_APPBAR, "AppBar OnCloseClick");
564     if (container->IsUIExtensionWindow()) {
565         container->TerminateUIExtension();
566     } else {
567         auto windowManager = pipeline->GetWindowManager();
568         CHECK_NULL_VOID(windowManager);
569         windowManager->WindowPerformBack();
570     }
571 }
572 
RequestAtomicServiceTerminate()573 void AppBarView::RequestAtomicServiceTerminate()
574 {
575     auto atom = atomicService_.Upgrade();
576     CHECK_NULL_VOID(atom);
577     auto pipeline = atom->GetContext();
578     CHECK_NULL_VOID(pipeline);
579     auto container = Container::Current();
580     CHECK_NULL_VOID(container);
581     TAG_LOGI(AceLogTag::ACE_APPBAR, "AppBar RequestAtomicServiceTerminate");
582     if (container->IsUIExtensionWindow()) {
583         container->RequestAtomicServiceTerminate();
584     } else {
585         auto windowManager = pipeline->GetWindowManager();
586         CHECK_NULL_VOID(windowManager);
587         windowManager->WindowPerformBack();
588     }
589 }
590 
AddRectChangeListener(const RefPtr<PipelineContext> & pipelineContext,std::function<void (const RectF & rect)> && listener)591 int32_t AppBarView::AddRectChangeListener(
592     const RefPtr<PipelineContext>& pipelineContext, std::function<void(const RectF& rect)>&& listener)
593 {
594     CHECK_NULL_RETURN(pipelineContext, INVALID_LISTENER_ID);
595     auto container = Container::GetContainer(pipelineContext->GetInstanceId());
596     CHECK_NULL_RETURN(container, INVALID_LISTENER_ID);
597     auto appbar = container->GetAppBar();
598     CHECK_NULL_RETURN(appbar, INVALID_LISTENER_ID);
599     auto atom = appbar->atomicService_.Upgrade();
600     CHECK_NULL_RETURN(atom, INVALID_LISTENER_ID);
601     auto pattern = atom->GetPattern<AtomicServicePattern>();
602     CHECK_NULL_RETURN(pattern, INVALID_LISTENER_ID);
603     return pattern->AddRectChangeListener(std::move(listener));
604 }
605 
RemoveRectChangeListener(const RefPtr<PipelineContext> & pipelineContext,int32_t id)606 void AppBarView::RemoveRectChangeListener(const RefPtr<PipelineContext>& pipelineContext, int32_t id)
607 {
608     CHECK_NULL_VOID(pipelineContext);
609     auto container = Container::GetContainer(pipelineContext->GetInstanceId());
610     CHECK_NULL_VOID(container);
611     auto appbar = container->GetAppBar();
612     CHECK_NULL_VOID(appbar);
613     auto atom = appbar->atomicService_.Upgrade();
614     CHECK_NULL_VOID(atom);
615     auto pattern = atom->GetPattern<AtomicServicePattern>();
616     CHECK_NULL_VOID(pattern);
617     pattern->RemoveRectChangeListener(id);
618 }
619 } // namespace OHOS::Ace::NG
620