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