diff --git a/bundle.json b/bundle.json index b38193317dcd14e4a18a5fb14b91ba65a2bdfae7..3d6a9424c5e0f2b20562c3846a8067c7cce37aff 100644 --- a/bundle.json +++ b/bundle.json @@ -91,7 +91,8 @@ "zlib", "skia", "libuv", - "background_task_mgr" + "background_task_mgr", + "atomicservice_basic_engine" ], "third_party": [] }, diff --git a/frameworks/core/components_ng/pattern/window_scene/BUILD.gn b/frameworks/core/components_ng/pattern/window_scene/BUILD.gn index b6bcc5551c2849bf731850fc36cc51a2a5458d3e..90e4b225d5f9103329fa43f7e9fe7002c5d658b0 100644 --- a/frameworks/core/components_ng/pattern/window_scene/BUILD.gn +++ b/frameworks/core/components_ng/pattern/window_scene/BUILD.gn @@ -17,6 +17,11 @@ import( if (is_ohos_standard_system) { config("window_scene_config") { visibility = [ ":*" ] + + if (defined(global_parts_info) && defined( + global_parts_info.atomicservicedistribution_atomicservice_basic_engine)) { + include_dirs = [ "//vendor/huawei/atomicservicedistribution/hag_serviceability/interface/innerkits/include" ] + } } } @@ -60,4 +65,10 @@ build_component_ng("window_scene") { "window_manager:screen_session_manager_client", ] } + + if (defined(global_parts_info) && defined( + global_parts_info.atomicservicedistribution_atomicservice_basic_engine)) { + external_deps += [ "atomicservice_basic_engine:hagserviceability_client" ] + defines = [ "ATOMIC_SERVICE_ATTRIBUTION_ENABLE" ] + } } diff --git a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp index d5fb1732c1a99e9ec2a33a102fb9c1447bac77c8..11bce3f6396dbb917d463a1ab58c712dbefb8b3d 100644 --- a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp +++ b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.cpp @@ -20,16 +20,39 @@ #include "adapter/ohos/entrance/mmi_event_convertor.h" #include "base/utils/system_properties.h" +#include "core/components_ng/pattern/text/text_pattern.h" +#include "core/components_ng/pattern/text/text_styles.h" #include "core/components_ng/image_provider/image_utils.h" #include "core/components_ng/pattern/image/image_pattern.h" #include "core/components_ng/pattern/window_scene/scene/window_event_process.h" #include "core/components_ng/render/adapter/rosen_render_context.h" #include "core/components_v2/inspector/inspector_constants.h" +#ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE +#include "hag_serviceability_client.h" +using namespace OHOS::AppExecFwk::AtomicserviceEcologicalRuleManager; +#endif namespace OHOS::Ace::NG { namespace { constexpr uint32_t COLOR_BLACK = 0xff000000; constexpr uint32_t COLOR_WHITE = 0xffffffff; + +#ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE +constexpr float HALF_PERCENT_TAG = 0.5f; +constexpr float BASE_X_OFFSET = 0.25f; +constexpr float BASE_Y_OFFSET = 0.4f; +constexpr float ROTATION_ANGLE = 360.0f; +constexpr uint32_t TEXT_NODE_HEIGHT = 42; +constexpr uint32_t TEXT_OFFSET_Y = 44; +constexpr uint32_t TEXT_NODE_FONT_SIZE = 16; +constexpr uint32_t TEXT_MAX_LINE = 2; +constexpr uint32_t IMAGE_NODE_SIZE = 72; +constexpr uint32_t ANIMATION_DURATION = 1750; +constexpr Dimension IMAGE_NODE_OFFSET = Dimension(-36, DimensionUnit::VP); +const Rosen::RSAnimationTimingCurve NODE_ANIMATION_TIMING_CURVE = + Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.40f, 0.08f, 0.60f, 0.92f); +#endif + constexpr uint32_t COLOR_TRANSLUCENT_WHITE = 0x66ffffff; constexpr Dimension SNAPSHOT_RADIUS = 16.0_vp; } // namespace @@ -194,8 +217,159 @@ void WindowPattern::CreateAppWindow() } } +#ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE +RefPtr WindowPattern::BuildTextNode(const std::string& appNameInfo) +{ + auto textNode = FrameNode::CreateFrameNode( + V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + CHECK_NULL_RETURN(textNode, nullptr); + // set size + auto textLayoutProperty = textNode->GetLayoutProperty(); + CHECK_NULL_RETURN(textLayoutProperty, nullptr); + auto textNodeHeight = CalcLength(Dimension(TEXT_NODE_HEIGHT, DimensionUnit::VP)); + auto textNodeWidth = CalcLength(Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT)); + textLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(textNodeWidth, textNodeHeight)); + // set basic attributions + textLayoutProperty->UpdateContent(appNameInfo); + textLayoutProperty->UpdateAlignment(Alignment::TOP_CENTER); + textLayoutProperty->UpdateFontSize(Dimension(TEXT_NODE_FONT_SIZE, DimensionUnit::FP)); + textLayoutProperty->UpdateFontWeight(FontWeight::MEDIUM); + textLayoutProperty->UpdateMaxLines(TEXT_MAX_LINE); + textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS); + textLayoutProperty->UpdateTextAlign(TextAlign::CENTER); + // set position + double textOffsetY = Dimension(TEXT_OFFSET_Y, DimensionUnit::VP).ConvertToPx(); + auto basePositionX = Dimension(BASE_X_OFFSET, DimensionUnit::PERCENT); + auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT); + auto textContext = AceType::DynamicCast(textNode->GetRenderContext()); + CHECK_NULL_RETURN(textContext, nullptr); + textContext->UpdatePosition(OffsetT(basePositionX, basePositionY)); + textContext->SetTranslate(0, textOffsetY, 0); + textNode->MarkModifyDone(); + return textNode; +} + +RefPtr WindowPattern::BuildAnimateNode(const std::string& base64Resource) +{ + CHECK_NULL_RETURN(session_, nullptr); + const auto& sessionInfo = session_->GetSessionInfo(); + auto testImageSource = ImageSourceInfo( + base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_); + auto animateNode = FrameNode::CreateFrameNode( + V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + CHECK_NULL_RETURN(animateNode, nullptr); + auto animateLayoutProperty = animateNode->GetLayoutProperty(); + CHECK_NULL_RETURN(animateLayoutProperty, nullptr); + animateLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); + animateLayoutProperty->UpdateImageSourceInfo(testImageSource); + animateLayoutProperty->UpdateImageFit(ImageFit::FILL); + auto animateContext = AceType::DynamicCast(animateNode->GetRenderContext()); + CHECK_NULL_RETURN(animateContext, nullptr); + auto animateRSNode = animateContext->GetRSNode(); + CHECK_NULL_RETURN(animateRSNode, nullptr); + auto animatePaintProperty = animateNode->GetPaintProperty(); + CHECK_NULL_RETURN(animatePaintProperty, nullptr); + animatePaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH); + // set position + auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT); + auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT); + animateContext->UpdatePosition(OffsetT(basePositionX, basePositionY)); + animateContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0); + // set size + auto animateNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP)); + auto animateNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP)); + animateLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(animateNodeWidth, animateNodeHeight)); + // set animation + Rosen::RSAnimationTimingProtocol protocol; + animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f)); + protocol.SetDuration(ANIMATION_DURATION); + protocol.SetRepeatCount(-1); + Rosen::RSNode::Animate(protocol, NODE_ANIMATION_TIMING_CURVE, [animateContext] { + animateContext->UpdateTransformRotate(Vector5F(0.0f, 0.0f, 1.0f, ROTATION_ANGLE, 0.0f)); + }); + animateNode->MarkModifyDone(); + return animateNode; +} + +RefPtr WindowPattern::BuildStaticImageNode(const std::string& base64Resource) +{ + CHECK_NULL_RETURN(session_, nullptr); + const auto& sessionInfo = session_->GetSessionInfo(); + auto testImageSource = ImageSourceInfo( + base64Resource, sessionInfo.bundleName_, sessionInfo.moduleName_); + auto staticNode = FrameNode::CreateFrameNode( + V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + CHECK_NULL_RETURN(staticNode, nullptr); + auto staticLayoutProperty = staticNode->GetLayoutProperty(); + CHECK_NULL_RETURN(staticLayoutProperty, nullptr); + staticLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); + staticLayoutProperty->UpdateImageSourceInfo(testImageSource); + staticLayoutProperty->UpdateImageFit(ImageFit::CONTAIN); + // set size + auto staticNodeHeight = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP)); + auto staticNodeWidth = CalcLength(Dimension(IMAGE_NODE_SIZE, DimensionUnit::VP)); + staticLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(staticNodeWidth, staticNodeHeight)); + // get context and property + auto staticContext = AceType::DynamicCast(staticNode->GetRenderContext()); + CHECK_NULL_RETURN(staticContext, nullptr); + auto staticPaintProperty = staticNode->GetPaintProperty(); + CHECK_NULL_RETURN(staticPaintProperty, nullptr); + staticPaintProperty->UpdateImageInterpolation(ImageInterpolation::HIGH); + // set position + auto basePositionX = Dimension(HALF_PERCENT_TAG, DimensionUnit::PERCENT); + auto basePositionY = Dimension(BASE_Y_OFFSET, DimensionUnit::PERCENT); + staticContext->UpdatePosition(OffsetT(basePositionX, basePositionY)); + staticContext->SetTranslate(IMAGE_NODE_OFFSET.ConvertToPx(), IMAGE_NODE_OFFSET.ConvertToPx(), 0); + staticNode->MarkModifyDone(); + return staticNode; +} + +void WindowPattern::CreateASStartingWindow() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + ACE_SCOPED_TRACE("CreateASStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId()); + + CHECK_NULL_VOID(session_); + const auto& sessionInfo = session_->GetSessionInfo(); + // get atomic service resources + AtomicserviceIconInfo atomicserviceIconInfo; + HagServiceablityClient::GetInstance()->GetAtomicserviceIconInfo(sessionInfo.bundleName_, atomicserviceIconInfo); + const auto& appNameInfo = atomicserviceIconInfo.GetAppName(); + const auto& eyelashRingIcon = atomicserviceIconInfo.GetEyelashRingIcon(); + const auto& circleIcon = atomicserviceIconInfo.GetCircleIcon(); + + startingWindow_ = FrameNode::CreateFrameNode( + V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + CHECK_NULL_VOID(startingWindow_); + auto asStartingLayoutProperty = startingWindow_->GetLayoutProperty(); + CHECK_NULL_VOID(asStartingLayoutProperty); + asStartingLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT); + startingWindow_->SetHitTestMode(HitTestMode::HTMNONE); + startingWindow_->GetRenderContext()->UpdateBackgroundColor( + SystemProperties::GetColorMode() == ColorMode::DARK ? Color::BLACK : Color::WHITE); + + auto staticNode = BuildStaticImageNode(circleIcon); + auto animateNode = BuildAnimateNode(eyelashRingIcon); + auto textNode = BuildTextNode(appNameInfo); + + startingWindow_->AddChild(staticNode); + startingWindow_->AddChild(animateNode); + startingWindow_->AddChild(textNode); + startingWindow_->MarkModifyDone(); +} +#endif + void WindowPattern::CreateStartingWindow() { + const auto& sessionInfo = session_->GetSessionInfo(); +#ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE + if (sessionInfo.isAtomicService) { + CreateASStartingWindow(); + return; + } +#endif + auto host = GetHost(); CHECK_NULL_VOID(host); ACE_SCOPED_TRACE("CreateStartingWindow[id:%d][self:%d]", session_->GetPersistentId(), host->GetId()); @@ -207,9 +381,7 @@ void WindowPattern::CreateStartingWindow() std::string startupPagePath; auto backgroundColor = SystemProperties::GetColorMode() == ColorMode::DARK ? COLOR_BLACK : COLOR_WHITE; - const auto& sessionInfo = session_->GetSessionInfo(); Rosen::SceneSessionManager::GetInstance().GetStartupPage(sessionInfo, startupPagePath, backgroundColor); - startingWindow_->GetRenderContext()->UpdateBackgroundColor(Color(backgroundColor)); imageLayoutProperty->UpdateImageSourceInfo( ImageSourceInfo(startupPagePath, sessionInfo.bundleName_, sessionInfo.moduleName_)); diff --git a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.h b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.h index 5f6d378cb15de21d9c7395238fd16d67afa74774..755678dd7d51e659f97ebf98c45c92173bf4714d 100644 --- a/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.h +++ b/frameworks/core/components_ng/pattern/window_scene/scene/window_pattern.h @@ -53,6 +53,13 @@ protected: void RegisterLifecycleListener(); void UnregisterLifecycleListener(); +#ifdef ATOMIC_SERVICE_ATTRIBUTION_ENABLE + RefPtr BuildTextNode(const std::string& appNameInfo); + RefPtr BuildAnimateNode(const std::string& base64Resource); + RefPtr BuildStaticImageNode(const std::string& base64Resource); + void CreateASStartingWindow(); +#endif + void CreateAppWindow(); void CreateBlankWindow(); void CreateStartingWindow(); diff --git a/test/unittest/core/pattern/ui_extension/BUILD.gn b/test/unittest/core/pattern/ui_extension/BUILD.gn index 8d9426a662cbd6c39e2d755eab72bf4e8bd2fe83..29bbd6eee4ba0528c6ab2bc37737a2bda5806fee 100644 --- a/test/unittest/core/pattern/ui_extension/BUILD.gn +++ b/test/unittest/core/pattern/ui_extension/BUILD.gn @@ -59,4 +59,10 @@ ace_unittest("ui_extension_component_test_ng") { "window_manager:scene_session_manager", ] } + + if (defined(global_parts_info) && defined( + global_parts_info.atomicservicedistribution_atomicservice_basic_engine)) { + external_deps += [ "atomicservice_basic_engine:hagserviceability_client" ] + defines += [ "ATOMIC_SERVICE_ATTRIBUTION_ENABLE" ] + } }