• 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 "ui/rs_surface_node.h"
20 
21 #include "adapter/ohos/entrance/mmi_event_convertor.h"
22 #include "base/utils/system_properties.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 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
31 #include "core/components_ng/pattern/window_scene/scene/atomicservice_basic_engine_plugin.h"
32 #endif
33 
34 namespace OHOS::Ace::NG {
35 namespace {
36 constexpr uint32_t COLOR_BLACK = 0xff000000;
37 constexpr uint32_t COLOR_WHITE = 0xffffffff;
38 constexpr uint32_t COLOR_TRANSLUCENT_WHITE = 0x66ffffff;
39 constexpr uint32_t COLOR_TRANSLUCENT_BLACK = 0x66000000;
40 constexpr Dimension SNAPSHOT_RADIUS = 16.0_vp;
41 
42 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
43 constexpr uint32_t ASENGINE_ATTRIBUTIONS_COUNT = 3;
44 constexpr uint32_t CIRCLE_ICON_INDEX = 1;
45 constexpr uint32_t EYELASHRING_ICON_INDEX = 2;
46 constexpr float HALF_PERCENT_TAG = 0.5f;
47 constexpr float BASE_X_OFFSET = 0.25f;
48 constexpr float BASE_Y_OFFSET = 0.4f;
49 constexpr float ROTATION_ANGLE = 360.0f;
50 constexpr uint32_t TEXT_NODE_HEIGHT = 42;
51 constexpr uint32_t TEXT_OFFSET_Y = 44;
52 constexpr uint32_t TEXT_NODE_FONT_SIZE = 16;
53 constexpr uint32_t TEXT_MAX_LINE = 2;
54 constexpr uint32_t IMAGE_NODE_SIZE = 72;
55 constexpr uint32_t ANIMATION_DURATION = 1750;
56 constexpr Dimension IMAGE_NODE_OFFSET = Dimension(-36, DimensionUnit::VP);
57 const Rosen::RSAnimationTimingCurve NODE_ANIMATION_TIMING_CURVE =
58     Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.40f, 0.08f, 0.60f, 0.92f);
59 #endif
60 } // namespace
61 
62 class LifecycleListener : public Rosen::ILifecycleListener {
63 public:
LifecycleListener(const WeakPtr<WindowPattern> & windowPattern)64     explicit LifecycleListener(const WeakPtr<WindowPattern>& windowPattern) : windowPattern_(windowPattern) {}
65     virtual ~LifecycleListener() = default;
66 
OnActivation()67     void OnActivation() override
68     {
69         auto windowPattern = windowPattern_.Upgrade();
70         CHECK_NULL_VOID(windowPattern);
71         windowPattern->OnActivation();
72     }
73 
OnConnect()74     void OnConnect() override
75     {
76         auto windowPattern = windowPattern_.Upgrade();
77         CHECK_NULL_VOID(windowPattern);
78         windowPattern->OnConnect();
79     }
80 
OnForeground()81     void OnForeground() override
82     {
83         auto windowPattern = windowPattern_.Upgrade();
84         CHECK_NULL_VOID(windowPattern);
85         windowPattern->OnForeground();
86     }
87 
OnBackground()88     void OnBackground() override
89     {
90         auto windowPattern = windowPattern_.Upgrade();
91         CHECK_NULL_VOID(windowPattern);
92         windowPattern->OnBackground();
93     }
94 
OnDisconnect()95     void OnDisconnect() override
96     {
97         auto windowPattern = windowPattern_.Upgrade();
98         CHECK_NULL_VOID(windowPattern);
99         windowPattern->OnDisconnect();
100     }
101 
OnLayoutFinished()102     void OnLayoutFinished() override
103     {
104         auto windowPattern = windowPattern_.Upgrade();
105         CHECK_NULL_VOID(windowPattern);
106         windowPattern->OnLayoutFinished();
107     }
108 
OnDrawingCompleted()109     void OnDrawingCompleted() override
110     {
111         auto windowPattern = windowPattern_.Upgrade();
112         CHECK_NULL_VOID(windowPattern);
113         windowPattern->OnDrawingCompleted();
114     }
115 
OnRemoveBlank()116     void OnRemoveBlank() override
117     {
118         auto windowPattern = windowPattern_.Upgrade();
119         CHECK_NULL_VOID(windowPattern);
120         windowPattern->OnRemoveBlank();
121     }
122 
123 private:
124     WeakPtr<WindowPattern> windowPattern_;
125 };
126 
RegisterLifecycleListener()127 void WindowPattern::RegisterLifecycleListener()
128 {
129     CHECK_NULL_VOID(session_);
130     lifecycleListener_ = std::make_shared<LifecycleListener>(WeakClaim(this));
131     session_->RegisterLifecycleListener(lifecycleListener_);
132 }
133 
UnregisterLifecycleListener()134 void WindowPattern::UnregisterLifecycleListener()
135 {
136     CHECK_NULL_VOID(session_);
137     session_->UnregisterLifecycleListener(lifecycleListener_);
138 }
139 
IsMainWindow() const140 bool WindowPattern::IsMainWindow() const
141 {
142     CHECK_NULL_RETURN(session_, false);
143     return session_->GetWindowType() == Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW;
144 }
145 
OnAttachToFrameNode()146 void WindowPattern::OnAttachToFrameNode()
147 {
148     CreateAppWindow();
149     auto host = GetHost();
150     CHECK_NULL_VOID(host);
151     auto state = session_->GetSessionState();
152     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "[WMSMain]OnAttachToFrameNode id: %{public}d, node id: %{public}d, "
153         "name: %{public}s, state: %{public}u, in recents: %{public}d", session_->GetPersistentId(), host->GetId(),
154         session_->GetSessionInfo().bundleName_.c_str(), state, session_->GetShowRecent());
155     if (state == Rosen::SessionState::STATE_DISCONNECT) {
156         CHECK_EQUAL_VOID(HasStartingPage(), false);
157         if (session_->GetShowRecent() && session_->GetScenePersistence() &&
158             (session_->GetScenePersistence()->IsSnapshotExisted() ||
159             session_->GetScenePersistence()->IsSavingSnapshot())) {
160             CreateSnapshotWindow();
161             AddChild(host, snapshotWindow_, snapshotWindowName_);
162             return;
163         }
164         CreateStartingWindow();
165         AddChild(host, startingWindow_, startingWindowName_);
166         return;
167     }
168 
169     CHECK_EQUAL_VOID(CheckAndAddStartingWindowAboveLocked(), true);
170 
171     if (state == Rosen::SessionState::STATE_BACKGROUND && session_->GetScenePersistence() &&
172         session_->GetScenePersistence()->HasSnapshot()) {
173         if (!session_->GetShowRecent()) {
174             AddChild(host, appWindow_, appWindowName_, 0);
175         }
176         CreateSnapshotWindow();
177         AddChild(host, snapshotWindow_, snapshotWindowName_);
178         attachToFrameNodeFlag_ = true;
179         return;
180     }
181 
182     if (session_->GetShowRecent()) {
183         CreateStartingWindow();
184         AddChild(host, startingWindow_, startingWindowName_);
185         return;
186     }
187 
188     AddChild(host, appWindow_, appWindowName_, 0);
189     auto surfaceNode = session_->GetSurfaceNode();
190     CHECK_NULL_VOID(surfaceNode);
191     if (!surfaceNode->IsBufferAvailable()) {
192         CreateStartingWindow();
193         AddChild(host, startingWindow_, startingWindowName_);
194         surfaceNode->SetBufferAvailableCallback(callback_);
195         return;
196     }
197     attachToFrameNodeFlag_ = true;
198 }
199 
CreateBlankWindow()200 void WindowPattern::CreateBlankWindow()
201 {
202     auto host = GetHost();
203     CHECK_NULL_VOID(host);
204     ACE_SCOPED_TRACE("CreateBlankWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
205     blankWindow_ = FrameNode::CreateFrameNode(
206         V2::WINDOW_SCENE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
207     auto layoutProperty = blankWindow_->GetLayoutProperty<LayoutProperty>();
208     layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
209     auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
210     blankWindow_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
211 }
212 
CreateAppWindow()213 void WindowPattern::CreateAppWindow()
214 {
215     auto host = GetHost();
216     CHECK_NULL_VOID(host);
217     ACE_SCOPED_TRACE("CreateAppWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
218     appWindow_ = FrameNode::CreateFrameNode(
219         V2::WINDOW_SCENE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<Pattern>());
220     appWindow_->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
221     appWindow_->SetHitTestMode(HitTestMode::HTMNONE);
222     CHECK_NULL_VOID(session_);
223     auto surfaceNode = session_->GetSurfaceNode();
224     if (surfaceNode) {
225         auto context = AceType::DynamicCast<NG::RosenRenderContext>(appWindow_->GetRenderContext());
226         CHECK_NULL_VOID(context);
227         context->SetRSNode(surfaceNode);
228         surfaceNode->SetVisible(true);
229     }
230 }
231 
232 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
BuildTextNode(const std::string & appNameInfo)233 RefPtr<FrameNode> WindowPattern::BuildTextNode(const std::string& appNameInfo)
234 {
235     auto textNode = FrameNode::CreateFrameNode(
236         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
237     CHECK_NULL_RETURN(textNode, nullptr);
238     // set size
239     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
240     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
241     auto textNodeHeight = CalcLength(Dimension(TEXT_NODE_HEIGHT, DimensionUnit::VP));
242     auto textNodeWidth = CalcLength(Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT));
243     textLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(textNodeWidth, textNodeHeight));
244     // set basic attributions
245     textLayoutProperty->UpdateContent(appNameInfo);
246     textLayoutProperty->UpdateAlignment(Alignment::TOP_CENTER);
247     textLayoutProperty->UpdateFontSize(Dimension(TEXT_NODE_FONT_SIZE, DimensionUnit::FP));
248     textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM);
249     textLayoutProperty->UpdateMaxLines(TEXT_MAX_LINE);
250     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
251     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
252     // set position
253     double textOffsetY = Dimension(TEXT_OFFSET_Y, DimensionUnit::VP).ConvertToPx();
254     auto basePositionX = Dimension(BASE_X_OFFSET, DimensionUnit::PERCENT);
255     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
256     auto textContext = AceType::DynamicCast<RosenRenderContext>(textNode->GetRenderContext());
257     CHECK_NULL_RETURN(textContext, nullptr);
258     textContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
259     textContext->SetTranslate(0, textOffsetY, 0);
260     textNode->MarkModifyDone();
261     return textNode;
262 }
263 
BuildAnimateNode(const std::string & base64Resource)264 RefPtr<FrameNode> WindowPattern::BuildAnimateNode(const std::string& base64Resource)
265 {
266     CHECK_NULL_RETURN(session_, nullptr);
267     const auto& sessionInfo = session_->GetSessionInfo();
268     auto testImageSource = ImageSourceInfo(
269         base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_);
270     auto animateNode = FrameNode::CreateFrameNode(
271         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
272     CHECK_NULL_RETURN(animateNode, nullptr);
273     auto animateLayoutProperty = animateNode->GetLayoutProperty<ImageLayoutProperty>();
274     CHECK_NULL_RETURN(animateLayoutProperty, nullptr);
275     animateLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
276     animateLayoutProperty->UpdateImageSourceInfo(testImageSource);
277     animateLayoutProperty->UpdateImageFit(ImageFit::FILL);
278     auto animateContext = AceType::DynamicCast<RosenRenderContext>(animateNode->GetRenderContext());
279     CHECK_NULL_RETURN(animateContext, nullptr);
280     auto animateRSNode = animateContext->GetRSNode();
281     CHECK_NULL_RETURN(animateRSNode, nullptr);
282     auto animatePaintProperty = animateNode->GetPaintProperty<ImageRenderProperty>();
283     CHECK_NULL_RETURN(animatePaintProperty, nullptr);
284     animatePaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
285     // set position
286     auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT);
287     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
288     animateContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
289     animateContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0);
290     // set size
291     auto animateNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
292     auto animateNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
293     animateLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(animateNodeWidth, animateNodeHeight));
294     // set animation
295     Rosen::RSAnimationTimingProtocol protocol;
296     animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
297     protocol.SetDuration(ANIMATION_DURATION);
298     protocol.SetRepeatCount(-1);
299     Rosen::RSNode::Animate(protocol, NODE_ANIMATION_TIMING_CURVE, [animateContext] {
300         animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, ROTATION_ANGLE, 0.0f));
301     });
302     animateNode->MarkModifyDone();
303     return animateNode;
304 }
305 
BuildStaticImageNode(const std::string & base64Resource)306 RefPtr<FrameNode> WindowPattern::BuildStaticImageNode(const std::string& base64Resource)
307 {
308     CHECK_NULL_RETURN(session_, nullptr);
309     const auto& sessionInfo = session_->GetSessionInfo();
310     auto testImageSource = ImageSourceInfo(
311         base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_);
312     auto staticNode = FrameNode::CreateFrameNode(
313         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
314     CHECK_NULL_RETURN(staticNode, nullptr);
315     auto staticLayoutProperty = staticNode->GetLayoutProperty<ImageLayoutProperty>();
316     CHECK_NULL_RETURN(staticLayoutProperty, nullptr);
317     staticLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
318     staticLayoutProperty->UpdateImageSourceInfo(testImageSource);
319     staticLayoutProperty->UpdateImageFit(ImageFit::CONTAIN);
320     // set size
321     auto staticNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
322     auto staticNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP));
323     staticLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(staticNodeWidth, staticNodeHeight));
324     // get context and property
325     auto staticContext = AceType::DynamicCast<RosenRenderContext>(staticNode->GetRenderContext());
326     CHECK_NULL_RETURN(staticContext, nullptr);
327     auto staticPaintProperty = staticNode->GetPaintProperty<ImageRenderProperty>();
328     CHECK_NULL_RETURN(staticPaintProperty, nullptr);
329     staticPaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
330     // set position
331     auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT);
332     auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT);
333     staticContext->UpdatePosition(OffsetT<Dimension>(basePositionX, basePositionY));
334     staticContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0);
335     staticNode->MarkModifyDone();
336     return staticNode;
337 }
338 
CreateASStartingWindow()339 void WindowPattern::CreateASStartingWindow()
340 {
341     auto host = GetHost();
342     CHECK_NULL_VOID(host);
343     ACE_SCOPED_TRACE("CreateASStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
344 
345     CHECK_NULL_VOID(session_);
346     const auto& sessionInfo = session_->GetSessionInfo();
347     // get atomic service resources
348     std::string appNameInfo = "";
349     std::string eyelashRingIcon = "";
350     std::string circleIcon = "";
351 
352 #ifdef ACE_ENGINE_PLUGIN_PATH
353     std::vector<std::string> atomicServiceIconInfo = AtomicServiceBasicEnginePlugin::GetInstance().
354         getParamsFromAtomicServiceBasicEngine(sessionInfo.bundleName_);
355     if (atomicServiceIconInfo.size() >= ASENGINE_ATTRIBUTIONS_COUNT) {
356         appNameInfo = atomicServiceIconInfo[0];
357         circleIcon = atomicServiceIconInfo[CIRCLE_ICON_INDEX];
358         eyelashRingIcon = atomicServiceIconInfo[EYELASHRING_ICON_INDEX];
359     }
360     AtomicServiceBasicEnginePlugin::GetInstance().releaseData();
361 #endif // ACE_ENGINE_PLUGIN_PATH
362 
363     startingWindow_ = FrameNode::CreateFrameNode(
364         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
365     CHECK_NULL_VOID(startingWindow_);
366     auto asStartingLayoutProperty = startingWindow_->GetLayoutProperty<StackLayoutProperty>();
367     CHECK_NULL_VOID(asStartingLayoutProperty);
368     asStartingLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
369     startingWindow_->SetHitTestMode(HitTestMode::HTMNONE);
370     startingWindow_->GetRenderContext()->UpdateBackgroundColor(
371         SystemProperties::GetColorMode() == ColorMode::DARK ? Color::BLACK : Color::WHITE);
372 
373     auto staticNode = BuildStaticImageNode(circleIcon);
374     auto animateNode = BuildAnimateNode(eyelashRingIcon);
375     auto textNode = BuildTextNode(appNameInfo);
376 
377     startingWindow_->AddChild(staticNode);
378     startingWindow_->AddChild(animateNode);
379     startingWindow_->AddChild(textNode);
380     startingWindow_->MarkModifyDone();
381 }
382 #endif
383 
CheckAndAddStartingWindowAboveLocked()384 bool WindowPattern::CheckAndAddStartingWindowAboveLocked()
385 {
386     CHECK_EQUAL_RETURN(
387         Rosen::SceneSessionManager::GetInstance().IsScreenLocked() && session_->UseStartingWindowAboveLocked(),
388         false, false);
389     auto host = GetHost();
390     CHECK_NULL_RETURN(host, false);
391     auto surfaceNode = session_->GetSurfaceNode();
392     CHECK_NULL_RETURN(surfaceNode, false);
393     AddChild(host, appWindow_, appWindowName_, 0);
394     CreateStartingWindow();
395     AddChild(host, startingWindow_, startingWindowName_);
396     surfaceNode->SetBufferAvailableCallback(callback_);
397     return true;
398 }
399 
CreateStartingWindow()400 void WindowPattern::CreateStartingWindow()
401 {
402     const auto& sessionInfo = session_->GetSessionInfo();
403 #ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE
404     if (sessionInfo.isAtomicService_) {
405         CreateASStartingWindow();
406         return;
407     }
408 #endif
409 
410     auto host = GetHost();
411     CHECK_NULL_VOID(host);
412     ACE_SCOPED_TRACE("CreateStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
413     startingWindow_ = FrameNode::CreateFrameNode(
414         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
415     auto imageLayoutProperty = startingWindow_->GetLayoutProperty<ImageLayoutProperty>();
416     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
417     startingWindow_->SetHitTestMode(HitTestMode::HTMNONE);
418 
419     std::string startupPagePath;
420     auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
421     Rosen::SceneSessionManager::GetInstance().GetStartupPage(sessionInfo, startupPagePath, backgroundColor);
422     startingWindow_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
423     imageLayoutProperty->UpdateImageSourceInfo(
424         ImageSourceInfo(startupPagePath, sessionInfo.bundleName_, sessionInfo.moduleName_));
425     imageLayoutProperty->UpdateImageFit(ImageFit::NONE);
426     startingWindow_->MarkModifyDone();
427 }
428 
UpdateSnapshotWindowProperty()429 void WindowPattern::UpdateSnapshotWindowProperty()
430 {
431     CHECK_NULL_VOID(snapshotWindow_ && session_);
432     auto isExitSplitOnBackground = session_->IsExitSplitOnBackground();
433     if (isExitSplitOnBackground) {
434         auto imagePattern = snapshotWindow_->GetPattern<ImagePattern>();
435         auto renderContext = snapshotWindow_->GetRenderContext();
436         auto imageRenderProperty = snapshotWindow_->GetPaintProperty<ImageRenderProperty>();
437         CHECK_NULL_VOID(imagePattern && renderContext && imageRenderProperty);
438 
439         BorderRadiusProperty borderRadius;
440         borderRadius.SetRadius(SNAPSHOT_RADIUS);
441         borderRadius.multiValued = false;
442         renderContext->UpdateBorderRadius(borderRadius);
443         auto backgroundColor =
444             SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_TRANSLUCENT_BLACK : COLOR_TRANSLUCENT_WHITE;
445         renderContext->UpdateBackgroundColor(Color(backgroundColor));
446         imagePattern->SetNeedBorderRadius(true);
447         imageRenderProperty->UpdateNeedBorderRadius(true);
448     }
449     auto imageLayoutProperty = snapshotWindow_->GetLayoutProperty<ImageLayoutProperty>();
450     CHECK_NULL_VOID(imageLayoutProperty);
451     imageLayoutProperty->UpdateImageFit(isExitSplitOnBackground ? ImageFit::CONTAIN : ImageFit::COVER_TOP_LEFT);
452     snapshotWindow_->MarkModifyDone();
453 }
454 
CreateSnapshotWindow(std::optional<std::shared_ptr<Media::PixelMap>> snapshot)455 void WindowPattern::CreateSnapshotWindow(std::optional<std::shared_ptr<Media::PixelMap>> snapshot)
456 {
457     auto host = GetHost();
458     CHECK_NULL_VOID(host);
459     ACE_SCOPED_TRACE("CreateSnapshotWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId());
460     session_->SetNeedSnapshot(false);
461     snapshotWindow_ = FrameNode::CreateFrameNode(
462         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
463     auto imageLayoutProperty = snapshotWindow_->GetLayoutProperty<ImageLayoutProperty>();
464     imageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
465     auto imagePaintProperty = snapshotWindow_->GetPaintProperty<ImageRenderProperty>();
466     imagePaintProperty->UpdateImageInterpolation(ImageInterpolation::MEDIUM);
467     snapshotWindow_->SetHitTestMode(HitTestMode::HTMNONE);
468 
469     if (snapshot) {
470         auto pixelMap = PixelMap::CreatePixelMap(&snapshot.value());
471         imageLayoutProperty->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
472         snapshotWindow_->GetPattern<ImagePattern>()->SetSyncLoad(true);
473     } else {
474         ImageSourceInfo sourceInfo;
475         auto scenePersistence = session_->GetScenePersistence();
476         CHECK_NULL_VOID(scenePersistence);
477         if (scenePersistence->IsSavingSnapshot()) {
478             auto snapshotPixelMap = session_->GetSnapshotPixelMap();
479             CHECK_NULL_VOID(snapshotPixelMap);
480             auto pixelMap = PixelMap::CreatePixelMap(&snapshotPixelMap);
481             sourceInfo = ImageSourceInfo(pixelMap);
482         } else {
483             sourceInfo = ImageSourceInfo("file://" + scenePersistence->GetSnapshotFilePath());
484         }
485         imageLayoutProperty->UpdateImageSourceInfo(sourceInfo);
486         ClearImageCache(sourceInfo);
487         auto eventHub = snapshotWindow_->GetEventHub<ImageEventHub>();
488         CHECK_NULL_VOID(eventHub);
489         eventHub->SetOnError([weakThis = WeakClaim(this)](const LoadImageFailEvent& info) {
490             auto self = weakThis.Upgrade();
491             CHECK_NULL_VOID(self && self->snapshotWindow_);
492             TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "load snapshot failed: %{public}s", info.GetErrorMessage().c_str());
493             auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE;
494             self->snapshotWindow_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor));
495             self->snapshotWindow_->MarkNeedRenderOnly();
496         });
497     }
498     UpdateSnapshotWindowProperty();
499 }
500 
ClearImageCache(const ImageSourceInfo & sourceInfo)501 void WindowPattern::ClearImageCache(const ImageSourceInfo& sourceInfo)
502 {
503     if (!Rosen::ScenePersistence::IsAstcEnabled()) {
504         auto pipelineContext = PipelineContext::GetCurrentContext();
505         CHECK_NULL_VOID(pipelineContext);
506         auto imageCache = pipelineContext->GetImageCache();
507         CHECK_NULL_VOID(imageCache);
508         auto snapshotSize = session_->GetScenePersistence()->GetSnapshotSize();
509         imageCache->ClearCacheImage(
510             ImageUtils::GenerateImageKey(sourceInfo, SizeF(snapshotSize.first, snapshotSize.second)));
511         imageCache->ClearCacheImage(
512             ImageUtils::GenerateImageKey(sourceInfo, SizeF(snapshotSize.second, snapshotSize.first)));
513         imageCache->ClearCacheImage(sourceInfo.GetKey());
514     }
515 }
516 
DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)517 void WindowPattern::DispatchPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
518 {
519     CHECK_NULL_VOID(session_);
520     CHECK_NULL_VOID(pointerEvent);
521     session_->TransferPointerEvent(pointerEvent);
522     if (pointerEvent->GetPointerAction() >= MMI::PointerEvent::POINTER_ACTION_PULL_DOWN &&
523         pointerEvent->GetPointerAction() <= MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
524         auto pipeline = PipelineContext::GetCurrentContext();
525         if (pipeline) {
526             auto manager = pipeline->GetDragDropManager();
527             CHECK_NULL_VOID(manager);
528             manager->SetIsWindowConsumed(true);
529         }
530     }
531 }
532 
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)533 void WindowPattern::DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
534 {
535     CHECK_NULL_VOID(session_);
536     CHECK_NULL_VOID(keyEvent);
537     session_->TransferKeyEvent(keyEvent);
538 }
539 
DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed)540 void WindowPattern::DispatchKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed)
541 {
542     CHECK_NULL_VOID(session_);
543     session_->TransferKeyEventForConsumed(keyEvent, isConsumed);
544 }
545 
DisPatchFocusActiveEvent(bool isFocusActive)546 void WindowPattern::DisPatchFocusActiveEvent(bool isFocusActive)
547 {
548     CHECK_NULL_VOID(session_);
549     session_->TransferFocusActiveEvent(isFocusActive);
550 }
551 
GetSession()552 sptr<Rosen::Session> WindowPattern::GetSession()
553 {
554     return session_;
555 }
556 
TransferFocusState(bool focusState)557 void WindowPattern::TransferFocusState(bool focusState)
558 {
559     CHECK_NULL_VOID(session_);
560     session_->TransferFocusStateEvent(focusState);
561 }
562 
GetHotAreas()563 std::vector<Rosen::Rect> WindowPattern::GetHotAreas()
564 {
565     if (session_ == nullptr) {
566         return std::vector<Rosen::Rect>();
567     }
568     return session_->GetTouchHotAreas();
569 }
570 
AddChild(const RefPtr<FrameNode> & host,const RefPtr<FrameNode> & child,const std::string & nodeType,int32_t index)571 void WindowPattern::AddChild(const RefPtr<FrameNode>& host, const RefPtr<FrameNode>& child,
572     const std::string& nodeType, int32_t index)
573 {
574     ACE_SCOPED_TRACE("WindowScene::AddChild[%s][self:%d]", nodeType.c_str(), host->GetId());
575     host->AddChild(child, index);
576     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "AddChild %{public}s, %{public}d", nodeType.c_str(), host->GetId());
577 }
578 
RemoveChild(const RefPtr<FrameNode> & host,const RefPtr<FrameNode> & child,const std::string & nodeType,bool allowTransition)579 void WindowPattern::RemoveChild(const RefPtr<FrameNode>& host, const RefPtr<FrameNode>& child,
580     const std::string& nodeType, bool allowTransition)
581 {
582     ACE_SCOPED_TRACE("WindowScene::RemoveChild[%s][self:%d]", nodeType.c_str(), host->GetId());
583     host->RemoveChild(child, allowTransition);
584     TAG_LOGI(AceLogTag::ACE_WINDOW_SCENE, "RemoveChild %{public}s, %{public}d", nodeType.c_str(), host->GetId());
585 }
586 } // namespace OHOS::Ace::NG
587