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