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