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