• 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/window_scene/scene/window_pattern.h"
17 
18 #include "session_manager/include/scene_session_manager.h"
19 #include "start_window_option.h"
20 #include "ui/rs_surface_node.h"
21 
22 #include "adapter/ohos/entrance/mmi_event_convertor.h"
23 #include "core/components_ng/pattern/text/text_pattern.h"
24 #include "core/components_ng/pattern/text/text_styles.h"
25 #include "core/components_ng/image_provider/image_utils.h"
26 #include "core/components_ng/pattern/image/image_pattern.h"
27 #include "core/components_ng/pattern/window_scene/scene/window_event_process.h"
28 #include "core/components_ng/render/adapter/rosen_render_context.h"
29 #include "core/components_v2/inspector/inspector_constants.h"
30 
31 namespace OHOS::Ace::NG {
32 namespace {
33 constexpr uint32_t ADD_BACKGROUND_COLOR_MS = 50;
34 constexpr uint32_t COLOR_BLACK = 0xff000000;
35 constexpr uint32_t COLOR_WHITE = 0xffffffff;
36 
37 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
38 constexpr uint32_t ASENGINE_ATTRIBUTIONS_COUNT = 3;
39 constexpr uint32_t CIRCLE_ICON_INDEX = 1;
40 constexpr uint32_t EYELASHRING_ICON_INDEX = 2;
41 constexpr float HALF_PERCENT_TAG = 0.5f;
42 constexpr float BASE_X_OFFSET = 0.25f;
43 constexpr float BASE_Y_OFFSET = 0.4f;
44 constexpr float ROTATION_ANGLE = 360.0f;
45 constexpr uint32_t TEXT_NODE_HEIGHT = 42;
46 constexpr uint32_t TEXT_OFFSET_Y = 44;
47 constexpr uint32_t TEXT_NODE_FONT_SIZE = 16;
48 constexpr uint32_t TEXT_MAX_LINE = 2;
49 constexpr uint32_t IMAGE_NODE_SIZE = 72;
50 constexpr uint32_t ANIMATION_DURATION = 1750;
51 constexpr Dimension IMAGE_NODE_OFFSET = Dimension(-36, DimensionUnit::VP);
52 const Rosen::RSAnimationTimingCurve NODE_ANIMATION_TIMING_CURVE =
53     Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.40f, 0.08f, 0.60f, 0.92f);
54 #endif
55 
56 constexpr uint32_t COLOR_TRANSLUCENT_WHITE = 0x66ffffff;
57 constexpr uint32_t COLOR_TRANSLUCENT_BLACK = 0x66000000;
58 constexpr Dimension SNAPSHOT_RADIUS = 16.0_vp;
59 constexpr uint32_t SNAPSHOT_LOAD_COMPLETE = 1;
60 constexpr uint32_t ROTATION_COUNT = 4;
61 constexpr uint32_t ROTATION_COUNT_SNAPSHOT = 2;
62 constexpr uint32_t STARTING_WINDOW_TIMEOUT_MS = 10000;
63 } // namespace
64 
65 class LifecycleListener : public Rosen::ILifecycleListener {
66 public:
LifecycleListener(const WeakPtr<WindowPattern> & windowPattern)67     explicit LifecycleListener(const WeakPtr<WindowPattern>& windowPattern) : windowPattern_(windowPattern) {}
68     virtual ~LifecycleListener() = default;
69 
OnActivation()70     void OnActivation() override
71     {
72         auto windowPattern = windowPattern_.Upgrade();
73         CHECK_NULL_VOID(windowPattern);
74         windowPattern->OnActivation();
75     }
76 
OnConnect()77     void OnConnect() override
78     {
79         auto windowPattern = windowPattern_.Upgrade();
80         CHECK_NULL_VOID(windowPattern);
81         windowPattern->OnConnect();
82     }
83 
OnForeground()84     void OnForeground() override
85     {
86         auto windowPattern = windowPattern_.Upgrade();
87         CHECK_NULL_VOID(windowPattern);
88         windowPattern->OnForeground();
89     }
90 
OnBackground()91     void OnBackground() override
92     {
93         auto windowPattern = windowPattern_.Upgrade();
94         CHECK_NULL_VOID(windowPattern);
95         windowPattern->OnBackground();
96     }
97 
OnDisconnect()98     void OnDisconnect() override
99     {
100         auto windowPattern = windowPattern_.Upgrade();
101         CHECK_NULL_VOID(windowPattern);
102         windowPattern->OnDisconnect();
103     }
104 
OnLayoutFinished()105     void OnLayoutFinished() override
106     {
107         auto windowPattern = windowPattern_.Upgrade();
108         CHECK_NULL_VOID(windowPattern);
109         windowPattern->OnLayoutFinished();
110     }
111 
OnDrawingCompleted()112     void OnDrawingCompleted() override
113     {
114         auto windowPattern = windowPattern_.Upgrade();
115         CHECK_NULL_VOID(windowPattern);
116         windowPattern->OnDrawingCompleted();
117     }
118 
OnRemoveBlank()119     void OnRemoveBlank() override
120     {
121         auto windowPattern = windowPattern_.Upgrade();
122         CHECK_NULL_VOID(windowPattern);
123         windowPattern->OnRemoveBlank();
124     }
125 
OnAddSnapshot()126     void OnAddSnapshot() override
127     {
128         auto windowPattern = windowPattern_.Upgrade();
129         CHECK_NULL_VOID(windowPattern);
130         windowPattern->OnAddSnapshot();
131     }
132 
OnRemoveSnapshot()133     void OnRemoveSnapshot() override
134     {
135         auto windowPattern = windowPattern_.Upgrade();
136         CHECK_NULL_VOID(windowPattern);
137         windowPattern->OnRemoveSnapshot();
138     }
139 
OnAppRemoveStartingWindow()140     void OnAppRemoveStartingWindow() override
141     {
142         auto windowPattern = windowPattern_.Upgrade();
143         CHECK_NULL_VOID(windowPattern);
144         windowPattern->OnAppRemoveStartingWindow();
145     }
146 
OnUpdateSnapshotWindow()147     void OnUpdateSnapshotWindow() override
148     {
149         auto windowPattern = windowPattern_.Upgrade();
150         CHECK_NULL_VOID(windowPattern);
151         windowPattern->OnUpdateSnapshotWindow();
152     }
153 
OnPreLoadStartingWindowFinished()154     void OnPreLoadStartingWindowFinished() override
155     {
156         auto windowPattern = windowPattern_.Upgrade();
157         CHECK_NULL_VOID(windowPattern);
158         windowPattern->OnPreLoadStartingWindowFinished();
159     }
160 
161 private:
162     WeakPtr<WindowPattern> windowPattern_;
163 };
164 
CheckAndMeasureStartingWindow(const SizeF & currentParentSize)165 void WindowPattern::CheckAndMeasureStartingWindow(const SizeF& currentParentSize)
166 {
167     CHECK_NULL_VOID(startingWindow_);
168     const auto& sessionInfo = session_->GetSessionInfo();
169 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
170     CHECK_EQUAL_VOID(sessionInfo.isAtomicService_, true);
171 #endif
172     bool parentSizeChanged = !NearEqual(currentParentSize.Width(), lastParentSize_.Width(), 1.0f) ||
173                              !NearEqual(currentParentSize.Height(), lastParentSize_.Height(), 1.0f);
174     lastParentSize_ = currentParentSize;
175     CHECK_EQUAL_VOID(parentSizeChanged, false);
176     startingWindowLayoutHelper_->MeasureChildNode(currentParentSize);
177 }
178 
RegisterLifecycleListener()179 void WindowPattern::RegisterLifecycleListener()
180 {
181     CHECK_NULL_VOID(session_);
182     lifecycleListener_ = std::make_shared<LifecycleListener>(WeakClaim(this));
183     session_->RegisterLifecycleListener(lifecycleListener_);
184 }
185 
UnregisterLifecycleListener()186 void WindowPattern::UnregisterLifecycleListener()
187 {
188     CHECK_NULL_VOID(session_);
189     session_->UnregisterLifecycleListener(lifecycleListener_);
190 }
191 
IsMainWindow() const192 bool WindowPattern::IsMainWindow() const
193 {
194     CHECK_NULL_RETURN(session_, false);
195     return session_->GetWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
196 }
197 
OnAttachToFrameNode()198 void WindowPattern::OnAttachToFrameNode()
199 {
200     CreateAppWindow();
201     auto host = GetHost();
202     CHECK_NULL_VOID(host);
203     auto state = session_->GetSessionState();
204     auto key = session_->GetWindowStatus();
205     TAG_LOGW(AceLogTag::ACE_WINDOW_SCENE, "OnAttachToFrameNode id: %{public}d, node id: %{public}d, "
206         "name: %{public}s, state: %{public}u, in recents: %{public}d", session_->GetPersistentId(), host->GetId(),
207         session_->GetSessionInfo().bundleName_.c_str(), state, session_->GetShowRecent());
208     if (state == Rosen::SessionState::STATE_DISCONNECT) {
209         CHECK_EQUAL_VOID(HasStartingPage(), false);
210         if (session_->GetShowRecent() && session_->GetScenePersistence() &&
211             (session_->GetScenePersistence()->IsSnapshotExisted(key) ||
212             session_->GetScenePersistence()->IsSavingSnapshot(key) ||
213             session_->GetScenePersistence()->HasSnapshot() || session_->HasSnapshot())) {
214             CreateSnapshotWindow();
215             AddChild(host, snapshotWindow_, snapshotWindowName_);
216             return;
217         }
218         CreateStartingWindow();
219         AddChild(host, startingWindow_, startingWindowName_);
220         return;
221     }
222 
223     CHECK_EQUAL_VOID(CheckAndAddStartingWindowAboveLocked(), true);
224 
225     if ((state == Rosen::SessionState::STATE_BACKGROUND || session_->IsAnco()) &&
226         session_->GetScenePersistence() &&
227         (session_->GetScenePersistence()->HasSnapshot() || session_->HasSnapshot())) {
228         if (!session_->GetShowRecent()) {
229             AddChild(host, appWindow_, appWindowName_, 0);
230         }
231         CreateSnapshotWindow();
232         AddChild(host, snapshotWindow_, snapshotWindowName_);
233         attachToFrameNodeFlag_ = true;
234         return;
235     }
236 
237     if (session_->GetShowRecent()) {
238         CreateStartingWindow();
239         AddChild(host, startingWindow_, startingWindowName_);
240         return;
241     }
242 
243     AddChild(host, appWindow_, appWindowName_, 0);
244     auto surfaceNode = session_->GetSurfaceNode();
245     CHECK_NULL_VOID(surfaceNode);
246     CHECK_EQUAL_VOID(AddPersistentImage(surfaceNode, host), true);
247     if (!surfaceNode->IsBufferAvailable()) {
248         CreateStartingWindow();
249         AddChild(host, startingWindow_, startingWindowName_);
250         surfaceNode->SetBufferAvailableCallback(callback_);
251         return;
252     }
253     attachToFrameNodeFlag_ = true;
254 }
255 
AddPersistentImage(const std::shared_ptr<Rosen::RSSurfaceNode> & surfaceNode,const RefPtr<NG::FrameNode> & host)256 bool WindowPattern::AddPersistentImage(const std::shared_ptr<Rosen::RSSurfaceNode>& surfaceNode,
257     const RefPtr<NG::FrameNode>& host)
258 {
259     int32_t imageFit = 0;
260     if (Rosen::SceneSessionManager::GetInstance().GetPersistentImageFit(
261         session_->GetPersistentId(), imageFit) == false) {
262         return false;
263     }
264     CreateSnapshotWindow();
265     AddChild(host, snapshotWindow_, snapshotWindowName_);
266     surfaceNode->SetIsNotifyUIBufferAvailable(false);
267     surfaceNode->SetBufferAvailableCallback(callback_);
268     return true;
269 }
270 
CreateBlankWindow(RefPtr<FrameNode> & window)271 void WindowPattern::CreateBlankWindow(RefPtr<FrameNode>& window)
272 {
273     auto host = GetHost();
274     CHECK_NULL_VOID(host);
275     auto context = host->GetContext();
276     CHECK_NULL_VOID(context);
277     ACE_SCOPED_TRACE("CreateBlankWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
278     window = FrameNode::CreateFrameNode(
279         V2::WINDOW_SCENE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
280     auto layoutProperty = window->GetLayoutProperty<LayoutProperty>();
281     layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
282     auto backgroundColor = context->GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
283     window->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
284 }
285 
CreateAppWindow()286 void WindowPattern::CreateAppWindow()
287 {
288     auto host = GetHost();
289     CHECK_NULL_VOID(host);
290     ACE_SCOPED_TRACE("CreateAppWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
291     RefPtr<FrameNode> tempWindow = FrameNode::CreateFrameNode(
292         V2::WINDOW_SCENE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
293     tempWindow->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
294     tempWindow->SetHitTestMode(HitTestMode::HTMNONE);
295     CHECK_NULL_VOID(session_);
296     auto surfaceNode = session_->GetSurfaceNode();
297     if (surfaceNode) {
298         auto context = AceType::DynamicCast<NG::RosenRenderContext>(tempWindow->GetRenderContext());
299         CHECK_NULL_VOID(context);
300         context->SetRSNode(surfaceNode);
301         surfaceNode->SetVisible(true);
302     }
303     (!appWindow_) ? appWindow_ = std::move(tempWindow) : (newAppWindow_ = std::move(tempWindow));
304 }
305 
306 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
BuildTextNode(const std::string & appNameInfo)307 RefPtr<FrameNode> WindowPattern::BuildTextNode(const std::string& appNameInfo)
308 {
309     auto textNode = FrameNode::CreateFrameNode(
310         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
311     CHECK_NULL_RETURN(textNode, nullptr);
312     // set size
313     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
314     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
315     auto textNodeHeight = CalcLength(Dimension(TEXT_NODE_HEIGHT, DimensionUnit::VP));
316     auto textNodeWidth = CalcLength(Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT));
317     textLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(textNodeWidth, textNodeHeight));
318     // set basic attributions
319     textLayoutProperty->UpdateContent(appNameInfo);
320     textLayoutProperty->UpdateAlignment(Alignment::TOP_CENTER);
321     textLayoutProperty->UpdateFontSize(Dimension(TEXT_NODE_FONT_SIZE, DimensionUnit::FP));
322     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
323     textLayoutProperty->UpdateMaxLines(TEXT_MAX_LINE);
324     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
325     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
326     // set position
327     double textOffsetY = Dimension(TEXT_OFFSET_Y, DimensionUnit::VP).ConvertToPx();
328     auto basePositionX = Dimension(BASE_X_OFFSET, DimensionUnit::PERCENT);
329     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
330     auto textContext = AceType::DynamicCast<RosenRenderContext>(textNode->GetRenderContext());
331     CHECK_NULL_RETURN(textContext, nullptr);
332     textContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
333     textContext->SetTranslate(0, textOffsetY, 0);
334     textNode->MarkModifyDone();
335     return textNode;
336 }
337 
BuildAnimateNode(const std::string & base64Resource)338 RefPtr<FrameNode> WindowPattern::BuildAnimateNode(const std::string& base64Resource)
339 {
340     CHECK_NULL_RETURN(session_, nullptr);
341     const auto& sessionInfo = session_->GetSessionInfo();
342     auto testImageSource = ImageSourceInfo(
343         base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_);
344     auto animateNode = FrameNode::CreateFrameNode(
345         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
346     CHECK_NULL_RETURN(animateNode, nullptr);
347     auto animateLayoutProperty = animateNode->GetLayoutProperty<ImageLayoutProperty>();
348     CHECK_NULL_RETURN(animateLayoutProperty, nullptr);
349     animateLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
350     animateLayoutProperty->UpdateImageSourceInfo(testImageSource);
351     animateLayoutProperty->UpdateImageFit(ImageFit::FILL);
352     auto animateContext = AceType::DynamicCast<RosenRenderContext>(animateNode->GetRenderContext());
353     CHECK_NULL_RETURN(animateContext, nullptr);
354     auto animateRSNode = animateContext->GetRSNode();
355     CHECK_NULL_RETURN(animateRSNode, nullptr);
356     auto animatePaintProperty = animateNode->GetPaintProperty<ImageRenderProperty>();
357     CHECK_NULL_RETURN(animatePaintProperty, nullptr);
358     animatePaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
359     // set position
360     auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT);
361     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
362     animateContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
363     animateContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0);
364     // set size
365     auto animateNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
366     auto animateNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
367     animateLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(animateNodeWidth, animateNodeHeight));
368     // set animation
369     Rosen::RSAnimationTimingProtocol protocol;
370     animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
371     protocol.SetDuration(ANIMATION_DURATION);
372     protocol.SetRepeatCount(-1);
373     Rosen::RSNode::Animate(animateRSNode->GetRSUIContext(), protocol, NODE_ANIMATION_TIMING_CURVE, [animateContext] {
374         animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, ROTATION_ANGLE, 0.0f));
375     });
376     animateNode->MarkModifyDone();
377     return animateNode;
378 }
379 
BuildStaticImageNode(const std::string & base64Resource)380 RefPtr<FrameNode> WindowPattern::BuildStaticImageNode(const std::string& base64Resource)
381 {
382     CHECK_NULL_RETURN(session_, nullptr);
383     const auto& sessionInfo = session_->GetSessionInfo();
384     auto testImageSource = ImageSourceInfo(
385         base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_);
386     auto staticNode = FrameNode::CreateFrameNode(
387         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
388     CHECK_NULL_RETURN(staticNode, nullptr);
389     auto staticLayoutProperty = staticNode->GetLayoutProperty<ImageLayoutProperty>();
390     CHECK_NULL_RETURN(staticLayoutProperty, nullptr);
391     staticLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
392     staticLayoutProperty->UpdateImageSourceInfo(testImageSource);
393     staticLayoutProperty->UpdateImageFit(ImageFit::CONTAIN);
394     // set size
395     auto staticNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
396     auto staticNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
397     staticLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(staticNodeWidth, staticNodeHeight));
398     // get context and property
399     auto staticContext = AceType::DynamicCast<RosenRenderContext>(staticNode->GetRenderContext());
400     CHECK_NULL_RETURN(staticContext, nullptr);
401     auto staticPaintProperty = staticNode->GetPaintProperty<ImageRenderProperty>();
402     CHECK_NULL_RETURN(staticPaintProperty, nullptr);
403     staticPaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
404     // set position
405     auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT);
406     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
407     staticContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
408     staticContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0);
409     staticNode->MarkModifyDone();
410     return staticNode;
411 }
412 
CreateASStartingWindow()413 void WindowPattern::CreateASStartingWindow()
414 {
415     auto host = GetHost();
416     CHECK_NULL_VOID(host);
417     auto context = host->GetContext();
418     CHECK_NULL_VOID(context);
419     ACE_SCOPED_TRACE("CreateASStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
420 
421     CHECK_NULL_VOID(session_);
422     const auto& sessionInfo = session_->GetSessionInfo();
423     // get atomic service resources
424     std::string appNameInfo = "";
425     std::string eyelashRingIcon = "";
426     std::string circleIcon = "";
427 
428 #ifdef ACE_ENGINE_PLUGIN_PATH
429     appNameInfo = sessionInfo.atomicServiceInfo_.appNameInfo;
430     eyelashRingIcon = sessionInfo.atomicServiceInfo_.eyelashRingIcon;
431     circleIcon = sessionInfo.atomicServiceInfo_.circleIcon;
432 #endif // ACE_ENGINE_PLUGIN_PATH
433 
434     startingWindow_ = FrameNode::CreateFrameNode(
435         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
436     CHECK_NULL_VOID(startingWindow_);
437     auto asStartingLayoutProperty = startingWindow_->GetLayoutProperty<StackLayoutProperty>();
438     CHECK_NULL_VOID(asStartingLayoutProperty);
439     asStartingLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
440     startingWindow_->SetHitTestMode(HitTestMode::HTMNONE);
441     startingWindow_->GetRenderContext()->UpdateBackgroundColor(
442         context->GetColorMode() == ColorMode::DARK ? Color::BLACK : Color::WHITE);
443 
444     auto staticNode = BuildStaticImageNode(circleIcon);
445     CHECK_NULL_VOID(staticNode);
446     auto animateNode = BuildAnimateNode(eyelashRingIcon);
447     CHECK_NULL_VOID(animateNode);
448     auto textNode = BuildTextNode(appNameInfo);
449     CHECK_NULL_VOID(textNode);
450 
451     startingWindow_->AddChild(staticNode);
452     startingWindow_->AddChild(animateNode);
453     startingWindow_->AddChild(textNode);
454     startingWindow_->MarkModifyDone();
455 }
456 #endif
457 
UpdateStartingWindowProperty(const Rosen::SessionInfo & sessionInfo,Color & color,ImageSourceInfo & sourceInfo)458 void WindowPattern::UpdateStartingWindowProperty(const Rosen::SessionInfo& sessionInfo,
459     Color &color, ImageSourceInfo &sourceInfo)
460 {
461     if (sessionInfo.startWindowOption == nullptr || !sessionInfo.startWindowOption->hasStartWindow) {
462         return;
463     }
464     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "Get starting window info from session info");
465     if (!sessionInfo.startWindowOption->startWindowBackgroundColor.empty()) {
466         Color::ParseColorString(sessionInfo.startWindowOption->startWindowBackgroundColor, color);
467     }
468     if (sessionInfo.startWindowOption->startWindowIcon != nullptr) {
469         auto pixelMap = PixelMap::CreatePixelMap(&(sessionInfo.startWindowOption->startWindowIcon));
470         sourceInfo = ImageSourceInfo(pixelMap);
471     }
472 }
473 
CheckAndAddStartingWindowAboveLocked()474 bool WindowPattern::CheckAndAddStartingWindowAboveLocked()
475 {
476     CHECK_EQUAL_RETURN(
477         Rosen::SceneSessionManager::GetInstance().IsScreenLocked() && session_->UseStartingWindowAboveLocked(),
478         false, false);
479     auto host = GetHost();
480     CHECK_NULL_RETURN(host, false);
481     auto surfaceNode = session_->GetSurfaceNode();
482     CHECK_NULL_RETURN(surfaceNode, false);
483     AddChild(host, appWindow_, appWindowName_, 0);
484     CreateStartingWindow();
485     AddChild(host, startingWindow_, startingWindowName_);
486     surfaceNode->SetBufferAvailableCallback(callback_);
487     return true;
488 }
489 
HideStartingWindow()490 void WindowPattern::HideStartingWindow()
491 {
492     session_->SetHidingStartingWindow(true);
493     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "hide startWindow: %{public}d", session_->GetPersistentId());
494 
495     ContainerScope scope(instanceId_);
496     auto context = PipelineContext::GetCurrentContext();
497     CHECK_NULL_VOID(context);
498     auto taskExecutor = context->GetTaskExecutor();
499     CHECK_NULL_VOID(taskExecutor);
500     interruptStartingTask_.Cancel();
501     interruptStartingTask_.Reset([weakThis = WeakClaim(this)]() {
502         ACE_SCOPED_TRACE("WindowScene::InterruptStartingTask");
503         auto self = weakThis.Upgrade();
504         CHECK_NULL_VOID(self);
505         CHECK_NULL_VOID(self->startingWindow_);
506         auto session = self->session_;
507         CHECK_NULL_VOID(session);
508         auto ret = session->Clear();
509         TAG_LOGE(AceLogTag::ACE_WINDOW_SCENE, "Terminate StartingWindow, ret: %{public}d", ret);
510     });
511     taskExecutor->PostDelayedTask(
512         interruptStartingTask_, TaskExecutor::TaskType::UI, STARTING_WINDOW_TIMEOUT_MS, "ArkUICleanStartingWindow");
513 }
514 
CreateStartingWindow()515 void WindowPattern::CreateStartingWindow()
516 {
517     if (session_->GetSessionInfo().startWindowType_ == Rosen::StartWindowType::RETAIN_AND_INVISIBLE) {
518         HideStartingWindow();
519         startingWindow_ = FrameNode::CreateFrameNode(
520             V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
521         return;
522     }
523 
524     const auto& sessionInfo = session_->GetSessionInfo();
525 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
526     if (sessionInfo.isAtomicService_) {
527         CreateASStartingWindow();
528         return;
529     }
530 #endif
531     auto host = GetHost();
532     CHECK_NULL_VOID(host);
533     auto context = host->GetContext();
534     CHECK_NULL_VOID(context);
535     ACE_SCOPED_TRACE("CreateStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
536     Rosen::StartingWindowInfo startingWindowInfo;
537     startingWindowInfo.backgroundColorEarlyVersion_ =
538         context->GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
539     Rosen::SceneSessionManager::GetInstance().GetStartupPage(sessionInfo, startingWindowInfo);
540     if (startingWindowInfo.configFileEnabled_) {
541         CHECK_NULL_VOID(startingWindowLayoutHelper_);
542         lastParentSize_ = { 0.0f, 0.0f };
543         startingWindow_ = startingWindowLayoutHelper_->CreateStartingWindowNode(
544             startingWindowInfo, sessionInfo.bundleName_, sessionInfo.moduleName_);
545         return;
546     }
547     startingWindow_ = FrameNode::CreateFrameNode(
548         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
549     auto imageLayoutProperty = startingWindow_->GetLayoutProperty<ImageLayoutProperty>();
550     CHECK_NULL_VOID(imageLayoutProperty);
551     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
552     startingWindow_->SetHitTestMode(HitTestMode::HTMNONE);
553     auto sourceInfo = ImageSourceInfo(
554         startingWindowInfo.iconPathEarlyVersion_, sessionInfo.bundleName_, sessionInfo.moduleName_);
555     auto color = Color(startingWindowInfo.backgroundColorEarlyVersion_);
556     auto preLoadPixelMap = Rosen::SceneSessionManager::GetInstance().GetPreLoadStartingWindow(sessionInfo);
557     if (preLoadPixelMap != nullptr) {
558         auto pixelMap = PixelMap::CreatePixelMap(&preLoadPixelMap);
559         sourceInfo = ImageSourceInfo(pixelMap);
560         Rosen::SceneSessionManager::GetInstance().RemovePreLoadStartingWindowFromMap(sessionInfo);
561         TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "use preload pixelMap id:%{public}d", session_->GetPersistentId());
562     }
563     UpdateStartingWindowProperty(sessionInfo, color, sourceInfo);
564     imageLayoutProperty->UpdateImageSourceInfo(sourceInfo);
565     startingWindow_->GetRenderContext()->UpdateBackgroundColor(color);
566     imageLayoutProperty->UpdateImageFit(ImageFit::NONE);
567     startingWindow_->MarkModifyDone();
568 }
569 
UpdateSnapshotWindowProperty()570 void WindowPattern::UpdateSnapshotWindowProperty()
571 {
572     CHECK_NULL_VOID(snapshotWindow_ && session_);
573     auto isExitSplitOnBackground = session_->IsExitSplitOnBackground();
574     if (isExitSplitOnBackground) {
575         Rosen::SceneSessionManager::GetInstance().SetDelayRemoveSnapshot(false);
576         auto imagePattern = snapshotWindow_->GetPattern<ImagePattern>();
577         auto renderContext = snapshotWindow_->GetRenderContext();
578         auto imageRenderProperty = snapshotWindow_->GetPaintProperty<ImageRenderProperty>();
579         CHECK_NULL_VOID(imagePattern && renderContext && imageRenderProperty);
580 
581         BorderRadiusProperty borderRadius;
582         borderRadius.SetRadius(SNAPSHOT_RADIUS);
583         borderRadius.multiValued = false;
584         renderContext->UpdateBorderRadius(borderRadius);
585         auto context = GetContext();
586         CHECK_NULL_VOID(context);
587         auto backgroundColor =
588             context->GetColorMode() == ColorMode::DARK ? COLOR_TRANSLUCENT_BLACK : COLOR_TRANSLUCENT_WHITE;
589         renderContext->UpdateBackgroundColor(Color(backgroundColor));
590         imagePattern->SetNeedBorderRadius(true);
591         imageRenderProperty->UpdateNeedBorderRadius(true);
592     }
593     auto imageLayoutProperty = snapshotWindow_->GetLayoutProperty<ImageLayoutProperty>();
594     CHECK_NULL_VOID(imageLayoutProperty);
595     int32_t persistentImageFit = 0;
596     auto isPersistentImageFit = Rosen::SceneSessionManager::GetInstance().GetPersistentImageFit(
597         session_->GetPersistentId(), persistentImageFit);
598     auto imageFit = static_cast<ImageFit>(persistentImageFit);
599     if (isPersistentImageFit) {
600         // ImageFit type COVER_TOP_LEFT is not support for api interface
601         imageLayoutProperty->UpdateImageFit(imageFit == ImageFit::COVER_TOP_LEFT ? ImageFit::MATRIX : imageFit);
602     } else {
603         imageLayoutProperty->UpdateImageFit(isExitSplitOnBackground ? ImageFit::CONTAIN : ImageFit::COVER_TOP_LEFT);
604     }
605     snapshotWindow_->MarkModifyDone();
606 }
607 
IsSnapshotSizeChanged()608 bool WindowPattern::IsSnapshotSizeChanged()
609 {
610     // pc and pad use the same snapshot size
611     CHECK_EQUAL_RETURN(session_->GetSystemConfig().IsPcWindow(), true, false);
612     CHECK_EQUAL_RETURN(session_->GetSystemConfig().freeMultiWindowEnable_, true, false);
613     Rosen::WSRect lastRect = session_->GetLastLayoutRect();
614     Rosen::WSRect curRect = session_->GetLayoutRect();
615     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "snapshot size changed id:%{public}d, last:%{public}s, cur:%{public}s",
616              session_->GetPersistentId(), lastRect.ToString().c_str(), curRect.ToString().c_str());
617     if (!session_->GetShowRecent() && !lastRect.IsInvalid() &&
618         NearEqual(lastRect.width_, curRect.width_, 1.0f) && NearEqual(lastRect.height_, curRect.height_, 1.0f)) {
619         return true;
620     }
621     return false;
622 }
623 
CreateSnapshotWindow(std::optional<std::shared_ptr<Media::PixelMap>> snapshot)624 void WindowPattern::CreateSnapshotWindow(std::optional<std::shared_ptr<Media::PixelMap>> snapshot)
625 {
626     auto host = GetHost();
627     CHECK_NULL_VOID(host);
628     auto persistentId = session_->GetPersistentId();
629     ACE_SCOPED_TRACE("CreateSnapshotWindow[id:%d][self:%d]", persistentId, host->GetId());
630     session_->SetNeedSnapshot(false);
631     isBlankForSnapshot_ = false;
632 
633     int32_t imageFit = 0;
634     auto isPersistentImageFit = Rosen::SceneSessionManager::GetInstance().GetPersistentImageFit(
635         session_->GetPersistentId(), imageFit);
636     if (IsSnapshotSizeChanged() && isPersistentImageFit == false) {
637         isBlankForSnapshot_ = true;
638         CreateBlankWindow(snapshotWindow_);
639         return;
640     }
641 
642     snapshotWindow_ = FrameNode::CreateFrameNode(
643         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
644     auto imageLayoutProperty = snapshotWindow_->GetLayoutProperty<ImageLayoutProperty>();
645     CHECK_NULL_VOID(imageLayoutProperty);
646     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
647     auto imagePaintProperty = snapshotWindow_->GetPaintProperty<ImageRenderProperty>();
648     imagePaintProperty->UpdateImageInterpolation(ImageInterpolation::LOW);
649     snapshotWindow_->SetHitTestMode(HitTestMode::HTMNONE);
650     auto pattern = snapshotWindow_->GetPattern<ImagePattern>();
651     CHECK_NULL_VOID(pattern);
652 
653     if (snapshot) {
654         auto pixelMap = PixelMap::CreatePixelMap(&snapshot.value());
655         imageLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
656         pattern->SetSyncLoad(true);
657     } else {
658         if ((DeviceConfig::realDeviceType == DeviceType::PHONE) && session_->GetShowRecent()) {
659             needAddBackgroundColor_ = true;
660             AddBackgroundColorDelayed();
661         }
662         ImageSourceInfo sourceInfo;
663         auto scenePersistence = session_->GetScenePersistence();
664         CHECK_NULL_VOID(scenePersistence);
665         auto key = session_->GetWindowStatus();
666         auto freeMultiWindow = session_->freeMultiWindow_.load();
667         auto isSavingSnapshot = scenePersistence->IsSavingSnapshot(key, freeMultiWindow);
668         auto hasSnapshot = scenePersistence->HasSnapshot(key, freeMultiWindow);
669         TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE,
670             "id: %{public}d isSavingSnapshot: %{public}d, hasSnapshot: %{public}d",
671             persistentId, isSavingSnapshot, hasSnapshot);
672         const bool matchSnapshot = isSavingSnapshot || hasSnapshot;
673         ImageRotateOrientation rotate;
674         auto lastRotation = session_->GetLastOrientation();
675         auto windowRotation = static_cast<uint32_t>(session_->GetWindowOrientation());
676         if (matchSnapshot && (!freeMultiWindow)) {
677             auto orientation = TransformOrientationForMatchSnapshot(lastRotation, windowRotation);
678             pattern->SetOrientation(orientation);
679         }
680         if (isSavingSnapshot) {
681             auto snapshotPixelMap = session_->GetSnapshotPixelMap();
682             CHECK_NULL_VOID(snapshotPixelMap);
683             TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "snapshotPixelMap id: %{public}d", snapshotPixelMap->GetUniqueId());
684             auto pixelMap = PixelMap::CreatePixelMap(&snapshotPixelMap);
685             sourceInfo = ImageSourceInfo(pixelMap);
686             snapshotWindow_->GetPattern<ImagePattern>()->SetSyncLoad(true);
687             Rosen::SceneSessionManager::GetInstance().VisitSnapshotFromCache(persistentId);
688         } else {
689             sourceInfo = ImageSourceInfo("file://" + scenePersistence->GetSnapshotFilePath(key, matchSnapshot,
690                 freeMultiWindow));
691             auto snapshotRotation =
692                 static_cast<uint32_t>(scenePersistence->rotate_[key.first][key.second]);
693             TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE,
694                 "lastRotation: %{public}d windowRotation: %{public}d, snapshotRotation: %{public}d",
695                 lastRotation, windowRotation, snapshotRotation);
696             if (!matchSnapshot) {
697                 auto orientation = TransformOrientationForDisMatchSnapshot(lastRotation,
698                     windowRotation, snapshotRotation);
699                 pattern->SetOrientation(orientation);
700             }
701         }
702         imageLayoutProperty->UpdateImageSourceInfo(sourceInfo);
703         ClearImageCache(sourceInfo, key, freeMultiWindow);
704         auto eventHub = snapshotWindow_->GetOrCreateEventHub<ImageEventHub>();
705         CHECK_NULL_VOID(eventHub);
706         eventHub->SetOnError([weakThis = WeakClaim(this)](const LoadImageFailEvent& info) {
707             auto self = weakThis.Upgrade();
708             CHECK_NULL_VOID(self && self->snapshotWindow_);
709             auto context = self->GetContext();
710             CHECK_NULL_VOID(context);
711             TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "load snapshot failed: %{public}s", info.GetErrorMessage().c_str());
712             auto backgroundColor = context->GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
713             self->snapshotWindow_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
714             self->snapshotWindow_->MarkNeedRenderOnly();
715         });
716         eventHub->SetOnComplete([weakThis = WeakClaim(this)](const LoadImageSuccessEvent& info) {
717             if (info.GetLoadingStatus() != SNAPSHOT_LOAD_COMPLETE) {
718                 return;
719             }
720             auto self = weakThis.Upgrade();
721             CHECK_NULL_VOID(self);
722             if (self->session_->IsExitSplitOnBackground()) {
723                 return;
724             }
725             CHECK_NULL_VOID(self->snapshotWindow_);
726             TAG_LOGD(AceLogTag::ACE_WINDOW_SCENE, "load snapshot complete id: %{public}d",
727                 self->session_->GetPersistentId());
728             auto context = self->snapshotWindow_->GetRenderContext();
729             CHECK_NULL_VOID(context);
730             context->UpdateBackgroundColor(Color::TRANSPARENT);
731             self->needAddBackgroundColor_ = false;
732             self->snapshotWindow_->MarkNeedRenderOnly();
733         });
734     }
735     UpdateSnapshotWindowProperty();
736 }
737 
AddBackgroundColorDelayed()738 void WindowPattern::AddBackgroundColorDelayed()
739 {
740     if (session_->IsExitSplitOnBackground()) {
741         return;
742     }
743     auto pipelineContext = PipelineContext::GetCurrentContext();
744     CHECK_NULL_VOID(pipelineContext);
745     auto taskExecutor = pipelineContext->GetTaskExecutor();
746     CHECK_NULL_VOID(taskExecutor);
747     addBackgroundColorTask_.Cancel();
748     addBackgroundColorTask_.Reset([weakThis = WeakClaim(this)]() {
749         auto self = weakThis.Upgrade();
750         CHECK_NULL_VOID(self);
751         CHECK_EQUAL_VOID(self->needAddBackgroundColor_, false);
752         ACE_SCOPED_TRACE("WindowScene::AddBackgroundColorTask");
753         TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "add background color: %{public}d", self->session_->GetPersistentId());
754         auto context = self->GetContext();
755         CHECK_NULL_VOID(context);
756         auto backgroundColor = context->GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
757         CHECK_NULL_VOID(self->snapshotWindow_);
758         auto snapshotContext = self->snapshotWindow_->GetRenderContext();
759         CHECK_NULL_VOID(snapshotContext);
760         snapshotContext->UpdateBackgroundColor(Color(backgroundColor));
761     });
762     taskExecutor->PostDelayedTask(
763         addBackgroundColorTask_, TaskExecutor::TaskType::UI, ADD_BACKGROUND_COLOR_MS, __func__);
764 }
765 
ClearImageCache(const ImageSourceInfo & sourceInfo,Rosen::SnapshotStatus key,bool freeMultiWindow)766 void WindowPattern::ClearImageCache(const ImageSourceInfo& sourceInfo, Rosen::SnapshotStatus key, bool freeMultiWindow)
767 {
768     auto frameNode = GetHost();
769     CHECK_NULL_VOID(frameNode);
770     auto pipelineContext = frameNode->GetContext();
771     CHECK_NULL_VOID(pipelineContext);
772     auto imageCache = pipelineContext->GetImageCache();
773     CHECK_NULL_VOID(imageCache);
774     imageCache->ClearCacheImgObj(sourceInfo.GetKey());
775     if (!Rosen::ScenePersistence::IsAstcEnabled()) {
776         auto snapshotSize = session_->GetScenePersistence()->GetSnapshotSize(key, freeMultiWindow);
777         imageCache->ClearCacheImage(
778             ImageUtils::GenerateImageKey(sourceInfo, SizeF(snapshotSize.first, snapshotSize.second)));
779         imageCache->ClearCacheImage(
780             ImageUtils::GenerateImageKey(sourceInfo, SizeF(snapshotSize.second, snapshotSize.first)));
781         imageCache->ClearCacheImage(sourceInfo.GetKey());
782     }
783 }
784 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)785 void WindowPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
786 {
787     CHECK_NULL_VOID(session_);
788     CHECK_NULL_VOID(pointerEvent);
789     session_->TransferPointerEvent(pointerEvent);
790     if (pointerEvent->GetPointerAction() >= MMI::PointerEvent::POINTER_ACTION_PULL_DOWN &&
791         pointerEvent->GetPointerAction() <= MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
792         auto pipeline = PipelineContext::GetCurrentContext();
793         if (pipeline) {
794             auto manager = pipeline->GetDragDropManager();
795             CHECK_NULL_VOID(manager);
796             manager->SetIsWindowConsumed(true);
797         }
798     }
799 }
800 
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)801 void WindowPattern::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
802 {
803     CHECK_NULL_VOID(session_);
804     CHECK_NULL_VOID(keyEvent);
805     session_->TransferKeyEvent(keyEvent);
806 }
807 
DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed)808 void WindowPattern::DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed)
809 {
810     CHECK_NULL_VOID(session_);
811     session_->TransferKeyEventForConsumed(keyEvent, isConsumed);
812 }
813 
DisPatchFocusActiveEvent(bool isFocusActive)814 void WindowPattern::DisPatchFocusActiveEvent(bool isFocusActive)
815 {
816     CHECK_NULL_VOID(session_);
817     session_->TransferFocusActiveEvent(isFocusActive);
818 }
819 
GetSession()820 sptr<Rosen::Session> WindowPattern::GetSession()
821 {
822     return session_;
823 }
824 
BorderUnoccupied() const825 bool WindowPattern::BorderUnoccupied() const
826 {
827     CHECK_NULL_RETURN(session_, false);
828     return session_->GetBorderUnoccupied();
829 }
830 
TransferFocusState(bool focusState)831 void WindowPattern::TransferFocusState(bool focusState)
832 {
833     CHECK_NULL_VOID(session_);
834     session_->TransferFocusStateEvent(focusState);
835 }
836 
GetHotAreas()837 std::vector<Rosen::Rect> WindowPattern::GetHotAreas()
838 {
839     if (session_ == nullptr) {
840         return std::vector<Rosen::Rect>();
841     }
842     return session_->GetTouchHotAreas();
843 }
844 
AddChild(const RefPtr<FrameNode> & host,const RefPtr<FrameNode> & child,const std::string & nodeType,int32_t index)845 void WindowPattern::AddChild(const RefPtr<FrameNode>& host, const RefPtr<FrameNode>& child,
846     const std::string& nodeType, int32_t index)
847 {
848     ACE_SCOPED_TRACE("WindowScene::AddChild[%s][self:%d]", nodeType.c_str(), host->GetId());
849     host->AddChild(child, index);
850     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "AddChild %{public}s, %{public}d", nodeType.c_str(), host->GetId());
851 }
852 
RemoveChild(const RefPtr<FrameNode> & host,const RefPtr<FrameNode> & child,const std::string & nodeType,bool allowTransition)853 void WindowPattern::RemoveChild(const RefPtr<FrameNode>& host, const RefPtr<FrameNode>& child,
854     const std::string& nodeType, bool allowTransition)
855 {
856     ACE_SCOPED_TRACE("WindowScene::RemoveChild[%s][self:%d]", nodeType.c_str(), host->GetId());
857     host->RemoveChild(child, allowTransition);
858     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "RemoveChild %{public}s, %{public}d", nodeType.c_str(), host->GetId());
859 }
860 
TransformOrientationForMatchSnapshot(uint32_t lastRotation,uint32_t windowRotation)861 ImageRotateOrientation WindowPattern::TransformOrientationForMatchSnapshot(uint32_t lastRotation,
862     uint32_t windowRotation)
863 {
864     auto orientation = static_cast<ImageRotateOrientation>(
865         TransformOrientation(lastRotation, windowRotation, ROTATION_COUNT) + 1);
866     if (orientation == ImageRotateOrientation::DOWN) {
867         orientation = ImageRotateOrientation::UP;
868     }
869     return orientation;
870 }
871 
TransformOrientationForDisMatchSnapshot(uint32_t lastRotation,uint32_t windowRotation,uint32_t snapshotRotation)872 ImageRotateOrientation WindowPattern::TransformOrientationForDisMatchSnapshot(uint32_t lastRotation,
873     uint32_t windowRotation, uint32_t snapshotRotation)
874 {
875     ImageRotateOrientation orientation = ImageRotateOrientation::UP;
876     if (lastRotation == snapshotRotation) {
877         return orientation;
878     }
879     if (TransformOrientation(lastRotation, snapshotRotation, ROTATION_COUNT_SNAPSHOT) != 0) {
880         if (TransformOrientation(lastRotation, windowRotation, ROTATION_COUNT_SNAPSHOT) != 0) {
881             orientation = static_cast<ImageRotateOrientation>(
882                 TransformOrientation(lastRotation, windowRotation, ROTATION_COUNT) + 1);
883         } else {
884             orientation = static_cast<ImageRotateOrientation>(
885                 TransformOrientation(windowRotation, snapshotRotation, ROTATION_COUNT) + 1);
886         }
887     }
888     return orientation;
889 }
890 
TransformOrientation(uint32_t lastRotation,uint32_t windowRotation,uint32_t count)891 uint32_t WindowPattern::TransformOrientation(uint32_t lastRotation, uint32_t windowRotation, uint32_t count)
892 {
893     if (count == 0) {
894         return 0;
895     }
896     return (lastRotation - windowRotation + ROTATION_COUNT) % count;
897 }
898 } // namespace OHOS::Ace::NG
899