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