From b2b8a2cce47874235d9e8ce973a04adfe1fd9383 Mon Sep 17 00:00:00 2001 From: zhirong <215782872@qq.com> Date: Wed, 13 Jul 2022 15:51:02 +0800 Subject: [PATCH] add animation config and keyboard animation Signed-off-by: zhirong <215782872@qq.com> Change-Id: I03dfed0401ff3fc62b07c62f8bfa5b7334048c9f Signed-off-by: zhirong <215782872@qq.com> --- interfaces/innerkits/wm/wm_common.h | 1 + .../config/other/window_manager_config.xml | 11 + .../config/rk3568/window_manager_config.xml | 41 +++- wm/src/window_impl.cpp | 2 + wmserver/include/animation_config.h | 40 ++++ wmserver/include/starting_window.h | 3 +- wmserver/include/window_manager_config.h | 203 +++++++++++++++++- wmserver/include/window_manager_service.h | 4 + wmserver/include/window_node_container.h | 4 +- wmserver/src/starting_window.cpp | 18 +- wmserver/src/window_controller.cpp | 32 +-- wmserver/src/window_manager_config.cpp | 203 +++++++++++------- wmserver/src/window_manager_service.cpp | 171 ++++++++++++--- wmserver/src/window_node_container.cpp | 26 ++- 14 files changed, 603 insertions(+), 156 deletions(-) create mode 100644 wmserver/include/animation_config.h diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index d01cab37..fb2084fb 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -284,6 +284,7 @@ enum class ColorSpace : uint32_t { enum class WindowAnimation : uint32_t { NONE, DEFAULT, + INPUTE, CUSTOM, }; diff --git a/resources/config/other/window_manager_config.xml b/resources/config/other/window_manager_config.xml index b4f8414f..0e5175b8 100644 --- a/resources/config/other/window_manager_config.xml +++ b/resources/config/other/window_manager_config.xml @@ -22,4 +22,15 @@ 0.1 0.9 0.5 0.33 0.67 + + + 0.7 0.7 + + + + 500 + 300 + 0.2 0.0 0.2 1.0 + + diff --git a/resources/config/rk3568/window_manager_config.xml b/resources/config/rk3568/window_manager_config.xml index db2b08f9..2addde4d 100644 --- a/resources/config/rk3568/window_manager_config.xml +++ b/resources/config/rk3568/window_manager_config.xml @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. --> - + @@ -28,4 +28,41 @@ 0.1 0.9 0.5 0.33 0.67 - \ No newline at end of file + + + + + 350 + + + + + + + + + + + + + + 0.7 0.7 + + 0 0 1 0 + + 0 0 + + 0 + + + + + + 500 + + 300 + + 0.2 0.0 0.2 1.0 + + + \ No newline at end of file diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 4b14f3c9..54f5bfb1 100755 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -2162,6 +2162,8 @@ void WindowImpl::AdjustWindowAnimationFlag(bool withAnimation) } else if (isAppWindow || (withAnimation && !animationTranistionController_)) { // use default animation property_->SetAnimationFlag(static_cast(WindowAnimation::DEFAULT)); + } else if (winType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) { + property_->SetAnimationFlag(static_cast(WindowAnimation::INPUTE)); } else { // with no animation property_->SetAnimationFlag(static_cast(WindowAnimation::NONE)); diff --git a/wmserver/include/animation_config.h b/wmserver/include/animation_config.h new file mode 100644 index 00000000..c20774ee --- /dev/null +++ b/wmserver/include/animation_config.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ROSEN_ANIMATION_CONFIG_H +#define OHOS_ROSEN_ANIMATION_CONFIG_H + +#include +namespace OHOS { +namespace Rosen { +struct AnimationConfig { + struct WindowAnimationConfig { + struct AnimationTiming { + RSAnimationTimingProtocol timingProtocol_ = 350; + RSAnimationTimingCurve timingCurve_ = RSAnimationTimingCurve::EASE_OUT; + } animationTiming_; + float opacity_ = 0; + Vector3f scale_ { 1, 1, 1 }; + Vector3f translate_ { 0, 0, 0 }; + Vector4f rotation_ { 0, 0, 1, 0 }; + } windowAnimationConfig_; + struct KeyboardAnimationConfig { + RSAnimationTimingCurve curve_ = RSAnimationTimingCurve::EASE_OUT; + RSAnimationTimingProtocol durationIn_ = 500; + RSAnimationTimingProtocol durationOut_ = 300; + } keyboardAnimationConfig_; +}; +} // Rosen +} // OHOS +#endif // OHOS_ROSEN_ANIMATION_CONFIG_H \ No newline at end of file diff --git a/wmserver/include/starting_window.h b/wmserver/include/starting_window.h index 6385e6cd..fdd6be20 100644 --- a/wmserver/include/starting_window.h +++ b/wmserver/include/starting_window.h @@ -18,6 +18,7 @@ #include #include "pixel_map.h" +#include "animation_config.h" #include "surface_draw.h" #include "wm_common.h" #include "window_node.h" @@ -36,7 +37,7 @@ public: int32_t pid, int32_t uid); static void DrawStartingWindow(sptr& node, sptr pixelMap, uint32_t bkgColor, bool isColdStart); - static void UpdateRSTree(sptr& node); + static void UpdateRSTree(sptr& node, const AnimationConfig& animationConfig); static void ReleaseStartWinSurfaceNode(sptr& node); static bool NeedToStopStartingWindow(WindowMode winMode, uint32_t modeSupportInfo, const sptr& info); diff --git a/wmserver/include/window_manager_config.h b/wmserver/include/window_manager_config.h index 02cec8d1..df377742 100644 --- a/wmserver/include/window_manager_config.h +++ b/wmserver/include/window_manager_config.h @@ -28,24 +28,207 @@ namespace OHOS { namespace Rosen { class WindowManagerConfig : public RefBase { public: + enum class ValueType { + UNDIFINED, + MAP, + BOOL, + STRING, + INTS, + FLOATS, + }; + struct ConfigItem { + std::map* property_ = nullptr; + ValueType type_ = ValueType::UNDIFINED; + union { + std::map* mapValue_ = nullptr; + bool boolValue_; + std::string stringValue_; + std::vector* intsValue_; + std::vector* floatsValue_; + }; + ConfigItem() {} + ~ConfigItem() + { + Destroy(); + }; + void Destroy() + { + ClearValue(); + if (property_) { + delete property_; + property_ = nullptr; + } + } + void ClearValue() + { + switch (type_) { + case ValueType::MAP: + delete mapValue_; + mapValue_ = nullptr; + break; + case ValueType::STRING: + stringValue_.~basic_string(); + break; + case ValueType::INTS: + delete intsValue_; + intsValue_ = nullptr; + break; + case ValueType::FLOATS: + delete floatsValue_; + floatsValue_ = nullptr; + break; + default: + break; + } + } + ConfigItem(const ConfigItem& value) + { + *this = value; + } + ConfigItem& operator=(const ConfigItem& value) + { + Destroy(); + switch (value.type_) { + case ValueType::MAP: + mapValue_ = new std::map(*value.mapValue_); + break; + case ValueType::BOOL: + boolValue_ = value.boolValue_; + break; + case ValueType::STRING: + new(&stringValue_)std::string(value.stringValue_); + break; + case ValueType::INTS: + intsValue_ = new std::vector(*value.intsValue_); + break; + case ValueType::FLOATS: + floatsValue_ = new std::vector(*value.floatsValue_); + break; + default: + break; + } + type_ = value.type_; + if (value.property_) { + property_ = new std::map(*value.property_); + } + return *this; + } + ConfigItem(ConfigItem&& value) noexcept + { + *this = std::move(value); + } + ConfigItem& operator=(ConfigItem&& value) noexcept + { + Destroy(); + switch (value.type_) { + case ValueType::MAP: + mapValue_ = value.mapValue_; + value.mapValue_ = nullptr; + break; + case ValueType::BOOL: + boolValue_ = value.boolValue_; + break; + case ValueType::STRING: + new(&stringValue_)std::string(std::move(value.stringValue_)); + break; + case ValueType::INTS: + intsValue_ = value.intsValue_; + value.intsValue_ = nullptr; + break; + case ValueType::FLOATS: + floatsValue_ = value.floatsValue_; + value.floatsValue_ = nullptr; + break; + default: + break; + } + type_ = value.type_; + property_ = value.property_; + value.type_ = ValueType::UNDIFINED; + value.property_ = nullptr; + return *this; + } + void SetProperty(const std::map& prop) + { + if (property_) { + delete property_; + } + property_ = new std::map(prop); + } + // set map value + void SetValue(const std::map& value) + { + ClearValue(); + type_ = ValueType::MAP; + mapValue_ = new std::map(value); + } + // set bool value + void SetValue(bool value) + { + ClearValue(); + type_ = ValueType::BOOL; + boolValue_ = value; + } + // set string value + void SetValue(const std::string& value) + { + ClearValue(); + type_ = ValueType::STRING; + new(&stringValue_)std::string(value); + } + // set ints value + void SetValue(const std::vector& value) + { + ClearValue(); + type_ = ValueType::INTS; + intsValue_ = new std::vector(value); + } + // set floats value + void SetValue(const std::vector& value) + { + ClearValue(); + type_ = ValueType::FLOATS; + floatsValue_ = new std::vector(value); + } + bool IsInts() const + { + return type_ == ValueType::INTS; + } + bool IsFloats() const + { + return type_ == ValueType::FLOATS; + } + bool IsString() const + { + return type_ == ValueType::STRING; + } + bool IsBool() const + { + return type_ == ValueType::BOOL; + } + bool IsMap() const + { + return type_ == ValueType::MAP; + } + }; WindowManagerConfig() = delete; ~WindowManagerConfig() = default; static bool LoadConfigXml(); - static const std::map& GetEnableConfig(); - static const std::map>& GetIntNumbersConfig(); - static const std::map>& GetFloatNumbersConfig(); - static void DumpConfig(); + static const std::map& GetConfig() + { + return config_; + } + static void DumpConfig(const std::map& config); private: - static std::map enableConfig_; - static std::map> intNumbersConfig_; - static std::map> floatNumbersConfig_; + static std::map config_; static bool IsValidNode(const xmlNode& currNode); - static void ReadEnableConfigInfo(const xmlNodePtr& currNode); - static void ReadIntNumbersConfigInfo(const xmlNodePtr& currNode); - static void ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode); + static void ReadProperty(const xmlNodePtr& currNode, std::map& property); + static void ReadIntNumbersConfigInfo(const xmlNodePtr& currNode, std::vector& intsValue); + static void ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode, std::vector& floatsValue); + static void ReadConfig(const xmlNodePtr& rootPtr, std::map& mapValue); static std::string GetConfigPath(const std::string& configFileName); }; } // namespace Rosen diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 4dd7f2fd..2df16d41 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -35,6 +35,7 @@ #include "window_controller.h" #include "zidl/window_manager_stub.h" #include "window_dumper.h" +#include "window_manager_config.h" #include "window_root.h" #include "snapshot_controller.h" @@ -139,6 +140,9 @@ private: } return ret; } + void ConfigWindowAnimation(const std::map& animeMap); + void ConfigKeyboardAnimation(const std::map& animeMap); + RSAnimationTimingCurve CreateCurve(const std::map& timingMap); static inline SingletonDelegator delegator; AtomicMap accessTokenIdMaps_; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index dcd5a3b5..973ea67d 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -16,7 +16,7 @@ #ifndef OHOS_ROSEN_WINDOW_NODE_CONTAINER_H #define OHOS_ROSEN_WINDOW_NODE_CONTAINER_H -#include +#include "animation_config.h" #include "avoid_area_controller.h" #include "display_info.h" #include "minimize_app.h" @@ -110,6 +110,7 @@ public: WindowLayoutMode GetCurrentLayoutMode() const; void RemoveSingleUserWindowNodes(int accountId); WMError IsTileRectSatisfiedWithSizeLimits(sptr& node); + static AnimationConfig& GetAnimationConfigRef(); private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; @@ -168,6 +169,7 @@ private: WindowLayoutMode layoutMode_ = WindowLayoutMode::CASCADE; std::vector currentCoveredArea_; std::vector removedIds_; + static AnimationConfig animationConfig_; sptr belowAppWindowNode_ = new WindowNode(); sptr appWindowNode_ = new WindowNode(); diff --git a/wmserver/src/starting_window.cpp b/wmserver/src/starting_window.cpp index ff0c636a..13825ddb 100644 --- a/wmserver/src/starting_window.cpp +++ b/wmserver/src/starting_window.cpp @@ -179,7 +179,7 @@ void StartingWindow::ReleaseStartWinSurfaceNode(sptr& node) RSTransaction::FlushImplicitTransaction(); } -void StartingWindow::UpdateRSTree(sptr& node) +void StartingWindow::UpdateRSTree(sptr& node, const AnimationConfig& animationConfig) { auto updateRSTreeFunc = [&]() { auto& dms = DisplayManagerServiceInner::GetInstance(); @@ -208,13 +208,15 @@ void StartingWindow::UpdateRSTree(sptr& node) } }; static const bool IsWindowAnimationEnabled = access(DISABLE_WINDOW_ANIMATION_PATH, F_OK) == 0 ? false : true; - if (IsWindowAnimationEnabled && !RemoteAnimation::CheckAnimationController()) { - // default transition duration: 350ms - static const RSAnimationTimingProtocol timingProtocol(350); - // default transition curve: EASE OUT - static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT; - // add window with transition animation - RSNode::Animate(timingProtocol, curve, updateRSTreeFunc); + if ((IsWindowAnimationEnabled && !RemoteAnimation::CheckAnimationController())) { + if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) { + // keyboard animation + RSNode::Animate(animationConfig.keyboardAnimationConfig_.durationIn_, + animationConfig.keyboardAnimationConfig_.curve_, updateRSTreeFunc); + } else { // window animation + RSNode::Animate(animationConfig.windowAnimationConfig_.animationTiming_.timingProtocol_, + animationConfig.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc); + } } else { // add or remove window without animation updateRSTreeFunc(); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 2f861aeb..8ad4bab8 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -772,26 +772,30 @@ void WindowController::UpdateWindowAnimation(const sptr& node) WLOGFE("windowNode or surfaceNode is nullptr"); return; } + const auto& windowAnimationConfig = WindowNodeContainer::GetAnimationConfigRef().windowAnimationConfig_; uint32_t animationFlag = node->GetWindowProperty()->GetAnimationFlag(); uint32_t windowId = node->GetWindowProperty()->GetWindowId(); WLOGFI("windowId: %{public}u, animationFlag: %{public}u", windowId, animationFlag); + std::shared_ptr effect = nullptr; if (animationFlag == static_cast(WindowAnimation::DEFAULT)) { - // set default transition effect for window: scale from 1.0 to 0.7, fade from 1.0 to 0.0 - static const auto effect = RSTransitionEffect::Create()->Scale(Vector3f(0.7f, 0.7f, 0.0f))->Opacity(0.0f); - if (node->leashWinSurfaceNode_) { - node->leashWinSurfaceNode_->SetTransitionEffect(effect); - } - if (node->surfaceNode_) { - node->surfaceNode_->SetTransitionEffect(effect); - } - } else { - if (node->leashWinSurfaceNode_) { - node->leashWinSurfaceNode_->SetTransitionEffect(nullptr); - } - if (node->surfaceNode_) { - node->surfaceNode_->SetTransitionEffect(nullptr); + effect = RSTransitionEffect::Create() + ->Scale(windowAnimationConfig.scale_) + ->Rotate(windowAnimationConfig.rotation_) + ->Translate(windowAnimationConfig.translate_) + ->Opacity(windowAnimationConfig.opacity_); + } else if (animationFlag == static_cast(WindowAnimation::INPUTE)) { + float translateY = static_cast(node->GetWindowRect().height_); + if (!node->GetWindowRect().height_) { + translateY = static_cast(node->GetRequestRect().height_); } + effect = RSTransitionEffect::Create()->Translate(Vector3f(0, translateY, 0))->Opacity(0.0f); + }; + if (node->leashWinSurfaceNode_) { + node->leashWinSurfaceNode_->SetTransitionEffect(effect); + } + if (node->surfaceNode_) { + node->surfaceNode_->SetTransitionEffect(effect); } } diff --git a/wmserver/src/window_manager_config.cpp b/wmserver/src/window_manager_config.cpp index cdc0d615..205d62f4 100644 --- a/wmserver/src/window_manager_config.cpp +++ b/wmserver/src/window_manager_config.cpp @@ -24,10 +24,7 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowManagerConfig"}; } -std::map WindowManagerConfig::enableConfig_; -std::map> WindowManagerConfig::intNumbersConfig_; -std::map> WindowManagerConfig::floatNumbersConfig_; - +std::map WindowManagerConfig::config_; std::string WindowManagerConfig::GetConfigPath(const std::string& configFileName) { @@ -41,6 +38,55 @@ std::string WindowManagerConfig::GetConfigPath(const std::string& configFileName return std::string(tmpPath); } +void WindowManagerConfig::ReadConfig(const xmlNodePtr& rootPtr, std::map& mapValue) +{ + for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) { + if (!IsValidNode(*curNodePtr)) { + WLOGFE("[WmConfig]: invalid node!"); + continue; + } + auto nodeName = curNodePtr->name; + if (!xmlStrcmp(nodeName, reinterpret_cast("maxAppWindowNumber")) || + !xmlStrcmp(nodeName, reinterpret_cast("modeChangeHotZones")) || + !xmlStrcmp(nodeName, reinterpret_cast("duration")) || + !xmlStrcmp(nodeName, reinterpret_cast("durationIn")) || + !xmlStrcmp(nodeName, reinterpret_cast("durationOut"))) { + std::vector v; + ReadIntNumbersConfigInfo(curNodePtr, v); + mapValue[reinterpret_cast(curNodePtr->name)].SetValue(v); + continue; + } + if (!xmlStrcmp(nodeName, reinterpret_cast("windowAnimation")) || + !xmlStrcmp(nodeName, reinterpret_cast("keyboardAnimation")) || + !xmlStrcmp(nodeName, reinterpret_cast("timing"))) { + std::map v; + ReadConfig(curNodePtr, v); + mapValue[reinterpret_cast(curNodePtr->name)].SetValue(v); + continue; + } + if (!xmlStrcmp(nodeName, reinterpret_cast("curve")) || + !xmlStrcmp(nodeName, reinterpret_cast("splitRatios")) || + !xmlStrcmp(nodeName, reinterpret_cast("exitSplitRatios")) || + !xmlStrcmp(nodeName, reinterpret_cast("scale")) || + !xmlStrcmp(nodeName, reinterpret_cast("rotation")) || + !xmlStrcmp(nodeName, reinterpret_cast("translate")) || + !xmlStrcmp(nodeName, reinterpret_cast("opacity")) || + !xmlStrcmp(nodeName, reinterpret_cast("decor")) || + !xmlStrcmp(nodeName, reinterpret_cast("minimizeByOther")) || + !xmlStrcmp(nodeName, reinterpret_cast("stretchable"))) { + std::map p; + ReadProperty(curNodePtr, p); + if (p.size() > 0) { + mapValue[reinterpret_cast(curNodePtr->name)].SetProperty(p); + } + std::vector v; + ReadFloatNumbersConfigInfo(curNodePtr, v); + mapValue[reinterpret_cast(curNodePtr->name)].SetValue(v); + continue; + } + } +} + bool WindowManagerConfig::LoadConfigXml() { auto configFilePath = GetConfigPath("etc/window/resources/window_manager_config.xml"); @@ -59,31 +105,8 @@ bool WindowManagerConfig::LoadConfigXml() return false; } - for (xmlNodePtr curNodePtr = rootPtr->xmlChildrenNode; curNodePtr != nullptr; curNodePtr = curNodePtr->next) { - if (!IsValidNode(*curNodePtr)) { - WLOGFE("[WmConfig]: invalid node!"); - continue; - } + ReadConfig(rootPtr, config_); - auto nodeName = curNodePtr->name; - if (!xmlStrcmp(nodeName, reinterpret_cast("decor")) || - !xmlStrcmp(nodeName, reinterpret_cast("minimizeByOther")) || - !xmlStrcmp(nodeName, reinterpret_cast("stretchable"))) { - ReadEnableConfigInfo(curNodePtr); - continue; - } - if (!xmlStrcmp(nodeName, reinterpret_cast("maxAppWindowNumber")) || - !xmlStrcmp(nodeName, reinterpret_cast("modeChangeHotZones"))) { - ReadIntNumbersConfigInfo(curNodePtr); - continue; - } - - if (!xmlStrcmp(nodeName, reinterpret_cast("splitRatios")) || - !xmlStrcmp(nodeName, reinterpret_cast("exitSplitRatios"))) { - ReadFloatNumbersConfigInfo(curNodePtr); - continue; - } - } xmlFreeDoc(docPtr); return true; } @@ -96,24 +119,30 @@ bool WindowManagerConfig::IsValidNode(const xmlNode& currNode) return true; } -void WindowManagerConfig::ReadEnableConfigInfo(const xmlNodePtr& currNode) +void WindowManagerConfig::ReadProperty(const xmlNodePtr& currNode, + std::map& property) { - xmlChar* enable = xmlGetProp(currNode, reinterpret_cast("enable")); - if (enable == nullptr) { - WLOGFE("[WmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); - return; + ConfigItem item; + xmlChar* prop = xmlGetProp(currNode, reinterpret_cast("enable")); + if (prop != nullptr) { + if (!xmlStrcmp(prop, reinterpret_cast("true"))) { + item.SetValue(true); + } else if (!xmlStrcmp(prop, reinterpret_cast("false"))) { + item.SetValue(false); + } + property["enable"] = item; + xmlFree(prop); } - std::string nodeName = reinterpret_cast(currNode->name); - if (!xmlStrcmp(enable, reinterpret_cast("true"))) { - enableConfig_[nodeName] = true; - } else if (!xmlStrcmp(enable, reinterpret_cast("false"))) { - enableConfig_[nodeName] = false; + prop = xmlGetProp(currNode, reinterpret_cast("name")); + if (prop != nullptr) { + item.SetValue(std::string(reinterpret_cast(prop))); + property["name"] = item; + xmlFree(prop); } - xmlFree(enable); } -void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) +void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode, std::vector& intsValue) { xmlChar* context = xmlNodeGetContent(currNode); if (context == nullptr) { @@ -121,7 +150,6 @@ void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) return; } - std::vector numbersVec; std::string numbersStr = reinterpret_cast(context); if (numbersStr.size() == 0) { xmlFree(context); @@ -134,24 +162,19 @@ void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) xmlFree(context); return; } - - numbersVec.emplace_back(std::stoi(num)); + intsValue.push_back(std::stoi(num)); } - - std::string nodeName = reinterpret_cast(currNode->name); - intNumbersConfig_[nodeName] = numbersVec; xmlFree(context); } -void WindowManagerConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode) +void WindowManagerConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode, + std::vector& floatsValue) { xmlChar* context = xmlNodeGetContent(currNode); if (context == nullptr) { WLOGFE("[WmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); return; } - - std::vector numbersVec; std::string numbersStr = reinterpret_cast(context); if (numbersStr.size() == 0) { xmlFree(context); @@ -164,46 +187,60 @@ void WindowManagerConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode) xmlFree(context); return; } - numbersVec.emplace_back(std::stof(num)); + floatsValue.push_back(std::stof(num)); } - - std::string nodeName = reinterpret_cast(currNode->name); - floatNumbersConfig_[nodeName] = numbersVec; xmlFree(context); } -const std::map& WindowManagerConfig::GetEnableConfig() +void WindowManagerConfig::DumpConfig(const std::map& config) { - return enableConfig_; -} - -const std::map>& WindowManagerConfig::GetIntNumbersConfig() -{ - return intNumbersConfig_; -} - -const std::map>& WindowManagerConfig::GetFloatNumbersConfig() -{ - return floatNumbersConfig_; -} - -void WindowManagerConfig::DumpConfig() -{ - for (auto& enable : enableConfig_) { - WLOGFI("[WmConfig] Enable: %{public}s %{public}u", enable.first.c_str(), enable.second); - } - - for (auto& numbers : intNumbersConfig_) { - WLOGFI("[WmConfig] Int numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); - for (auto& num : numbers.second) { - WLOGFI("[WmConfig] Num: %{public}d", num); + for (auto& conf : config) { + WLOGFI("[WmConfig] %{public}s", conf.first.c_str()); + std::map propMap; + if (conf.second.property_) { + propMap = *conf.second.property_; } - } - - for (auto& numbers : floatNumbersConfig_) { - WLOGFI("[WmConfig] Float numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); - for (auto& num : numbers.second) { - WLOGFI("[WmConfig] Num: %{public}f", num); + for (auto prop : propMap) { + switch (prop.second.type_) { + case ValueType::BOOL: + WLOGFI("[WmConfig] Prop: %{public}s %{public}u", prop.first.c_str(), prop.second.boolValue_); + break; + case ValueType::STRING: + WLOGFI("[WmConfig] Prop: %{public}s %{public}s", prop.first.c_str(), + prop.second.stringValue_.c_str()); + break; + default: + break; + } + } + switch (conf.second.type_) { + case ValueType::MAP: + if (conf.second.mapValue_) { + DumpConfig(*conf.second.mapValue_); + } + break; + case ValueType::BOOL: + WLOGFI("[WmConfig] %{public}u", conf.second.boolValue_); + break; + case ValueType::STRING: + WLOGFI("[WmConfig] %{public}s", conf.second.stringValue_.c_str()); + break; + case ValueType::INTS: + if (conf.second.intsValue_) { + for (auto& num : *conf.second.intsValue_) { + WLOGFI("[WmConfig] Num: %{public}d", num); + } + } + break; + case ValueType::FLOATS: + if (conf.second.floatsValue_) { + for (auto& num : *conf.second.floatsValue_) { + WLOGFI("[WmConfig] Num: %{public}f", num); + } + } + break; + default: + break; } } } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 84704794..20dcd362 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -37,7 +37,6 @@ #include "window_helper.h" #include "window_inner_manager.h" #include "window_manager_agent_controller.h" -#include "window_manager_config.h" #include "window_manager_hilog.h" #include "wm_common.h" @@ -272,7 +271,7 @@ bool WindowManagerService::Init() return false; } if (WindowManagerConfig::LoadConfigXml()) { - WindowManagerConfig::DumpConfig(); + WindowManagerConfig::DumpConfig(WindowManagerConfig::GetConfig()); ConfigureWindowManagerService(); } WLOGFI("WindowManagerService::Init success"); @@ -292,33 +291,35 @@ int WindowManagerService::Dump(int fd, const std::vector& args) void WindowManagerService::ConfigureWindowManagerService() { - const auto& enableConfig = WindowManagerConfig::GetEnableConfig(); - const auto& intNumbersConfig = WindowManagerConfig::GetIntNumbersConfig(); - const auto& floatNumbersConfig = WindowManagerConfig::GetFloatNumbersConfig(); - - if (enableConfig.count("decor") != 0) { - systemConfig_.isSystemDecorEnable_ = enableConfig.at("decor"); + const auto& config = WindowManagerConfig::GetConfig(); + if (config.count("decor") != 0 && config.at("decor").property_) { + if (config.at("decor").property_->count("enable")) { + systemConfig_.isSystemDecorEnable_ = + config.at("decor").property_->at("enable").boolValue_; + } } - - if (enableConfig.count("minimizeByOther") != 0) { - MinimizeApp::SetMinimizedByOtherConfig(enableConfig.at("minimizeByOther")); + if (config.count("minimizeByOther") != 0 && config.at("minimizeByOther").property_) { + if (config.at("minimizeByOther").property_->count("enable")) { + MinimizeApp::SetMinimizedByOtherConfig( + config.at("minimizeByOther").property_->at("enable").boolValue_); + } } - - if (enableConfig.count("stretchable") != 0) { - systemConfig_.isStretchable_ = enableConfig.at("stretchable"); + if (config.count("stretchable") != 0 && config.at("stretchable").property_) { + if (config.at("stretchable").property_->count("enable")) { + systemConfig_.isStretchable_ = + config.at("stretchable").property_->at("enable").boolValue_; + } } - - if (intNumbersConfig.count("maxAppWindowNumber") != 0) { - auto numbers = intNumbersConfig.at("maxAppWindowNumber"); + if (config.count("maxAppWindowNumber") != 0 && config.at("maxAppWindowNumber").IsInts()) { + auto numbers = *config.at("maxAppWindowNumber").intsValue_; if (numbers.size() == 1) { if (numbers[0] > 0) { windowRoot_->SetMaxAppWindowNumber(static_cast(numbers[0])); } } } - - if (intNumbersConfig.count("modeChangeHotZones") != 0) { - auto numbers = intNumbersConfig.at("modeChangeHotZones"); + if (config.count("modeChangeHotZones") != 0 && config.at("modeChangeHotZones").IsInts()) { + auto numbers = *config.at("modeChangeHotZones").intsValue_; if (numbers.size() == 3) { // 3 hot zones hotZonesConfig_.fullscreenRange_ = static_cast(numbers[0]); // 0 fullscreen hotZonesConfig_.primaryRange_ = static_cast(numbers[1]); // 1 primary @@ -326,14 +327,132 @@ void WindowManagerService::ConfigureWindowManagerService() hotZonesConfig_.isModeChangeHotZoneConfigured_ = true; } } - - if (floatNumbersConfig.count("splitRatios") != 0) { - windowRoot_->SetSplitRatios(floatNumbersConfig.at("splitRatios")); + if (config.count("splitRatios") != 0 && config.at("splitRatios").IsFloats()) { + windowRoot_->SetSplitRatios(*config.at("splitRatios").floatsValue_); } - - if (floatNumbersConfig.count("exitSplitRatios") != 0) { - windowRoot_->SetExitSplitRatios(floatNumbersConfig.at("exitSplitRatios")); + if (config.count("exitSplitRatios") != 0 && config.at("exitSplitRatios").IsFloats()) { + windowRoot_->SetExitSplitRatios(*config.at("exitSplitRatios").floatsValue_); } + if (config.count("windowAnimation") && config.at("windowAnimation").IsMap()) { + const auto& animeMap = *config.at("windowAnimation").mapValue_; + ConfigWindowAnimation(animeMap); + } + if (config.count("keyboardAnimation") && config.at("keyboardAnimation").IsMap()) { + const auto& animeMap = *config.at("keyboardAnimation").mapValue_; + ConfigKeyboardAnimation(animeMap); + } +} + +void WindowManagerService::ConfigWindowAnimation(const std::map& animeMap) +{ + auto& windowAnimationConfig = WindowNodeContainer::GetAnimationConfigRef().windowAnimationConfig_; + if (animeMap.count("timing") && animeMap.at("timing").IsMap()) { + const auto& timingMap = *animeMap.at("timing").mapValue_; + if (timingMap.count("duration") && timingMap.at("duration").IsInts()) { + auto numbers = *timingMap.at("duration").intsValue_; + if (numbers.size() == 1) { // duration + windowAnimationConfig.animationTiming_.timingProtocol_ = + RSAnimationTimingProtocol(numbers[0]); + } + } + windowAnimationConfig.animationTiming_.timingCurve_ = CreateCurve(timingMap); + } + if (animeMap.count("scale") && animeMap.at("scale").IsFloats()) { + auto numbers = *animeMap.at("scale").floatsValue_; + if (numbers.size() == 1) { // 1 xy scale + windowAnimationConfig.scale_.x_ = + windowAnimationConfig.scale_.y_ = numbers[0]; // 0 xy scale + } else if (numbers.size() == 2) { // 2 x,y sclae + windowAnimationConfig.scale_.x_ = numbers[0]; // 0 x scale + windowAnimationConfig.scale_.y_ = numbers[1]; // 1 y scale + } else if (numbers.size() == 3) { // 3 x,y,z scale + windowAnimationConfig.scale_ = Vector3f(&numbers[0]); + } + } + if (animeMap.count("rotation") && animeMap.at("rotation").IsFloats()) { + auto numbers = *animeMap.at("rotation").floatsValue_; + if (numbers.size() == 4) { // 4 (axix,angle) + windowAnimationConfig.rotation_ = Vector4f(&numbers[0]); + } + } + if (animeMap.count("translate") && animeMap.at("translate").IsFloats()) { + auto numbers = *animeMap.at("translate").floatsValue_; + if (numbers.size() == 2) { // 2 translate xy + windowAnimationConfig.translate_.x_ = numbers[0]; // 0 translate x + windowAnimationConfig.translate_.y_ = numbers[1]; // 1 translate y + } else if (numbers.size() == 3) { // 3 translate xyz + windowAnimationConfig.translate_.x_ = numbers[0]; // 0 translate x + windowAnimationConfig.translate_.y_ = numbers[1]; // 1 translate y + windowAnimationConfig.translate_.z_ = numbers[2]; // 2 translate z + } + } + if (animeMap.count("opacity") && animeMap.at("opacity").IsFloats()) { + auto numbers = *animeMap.at("opacity").floatsValue_; + if (numbers.size() == 1) { + windowAnimationConfig.opacity_ = numbers[0]; // 0 opacity + } + } +} + +void WindowManagerService::ConfigKeyboardAnimation(const std::map& animeMap) +{ + auto& animationConfig = WindowNodeContainer::GetAnimationConfigRef(); + if (animeMap.count("timing") && animeMap.at("timing").IsMap()) { + const auto& timingMap = *animeMap.at("timing").mapValue_; + if (timingMap.count("durationIn") && timingMap.at("durationIn").IsInts()) { + auto numbers = *timingMap.at("durationIn").intsValue_; + if (numbers.size() == 1) { // duration + animationConfig.keyboardAnimationConfig_.durationIn_ = + RSAnimationTimingProtocol(numbers[0]); + } + } + if (timingMap.count("durationOut") && timingMap.at("durationOut").IsInts()) { + auto numbers = *timingMap.at("durationOut").intsValue_; + if (numbers.size() == 1) { // duration + animationConfig.keyboardAnimationConfig_.durationOut_ = + RSAnimationTimingProtocol(numbers[0]); + } + } + animationConfig.keyboardAnimationConfig_.curve_ = CreateCurve(timingMap); + } +} + +RSAnimationTimingCurve WindowManagerService::CreateCurve( + const std::map& timingMap) +{ + if (timingMap.count("curve") && timingMap.at("curve").property_) { + auto curveProp = *timingMap.at("curve").property_; + std::string name; + if (curveProp.count("name") && curveProp.at("name").IsString()) { + name = curveProp.at("name").stringValue_; + } + if (name == "easeOut") { + return RSAnimationTimingCurve::EASE_OUT; + } else if (name == "ease") { + return RSAnimationTimingCurve::EASE; + } else if (name == "easeIn") { + return RSAnimationTimingCurve::EASE_IN; + } else if (name == "easeInOut") { + return RSAnimationTimingCurve::EASE_IN_OUT; + } else if (name == "default") { + return RSAnimationTimingCurve::DEFAULT; + } else if (name == "linear") { + return RSAnimationTimingCurve::LINEAR; + } else if (name == "spring") { + return RSAnimationTimingCurve::SPRING; + } else if (name == "interactiveSpring") { + return RSAnimationTimingCurve::INTERACTIVE_SPRING; + } else if (name == "cubic" && timingMap.at("curve").IsFloats() && + timingMap.at("curve").floatsValue_->size() == 4) { // 4 curve parameter + auto numbers = *timingMap.at("curve").floatsValue_; + return RSAnimationTimingCurve::CreateCubicCurve(numbers[0], // 0 ctrlX1 + numbers[1], // 1 ctrlY1 + numbers[2], // 2 ctrlX2 + numbers[3]); // 3 ctrlY2 + } + } + return RSAnimationTimingCurve::EASE_OUT; } void WindowManagerService::OnStop() diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index a9d2645b..dc03a908 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -48,6 +48,7 @@ namespace { constexpr int UID_TRANSFROM_DIVISOR = 20000; constexpr int UID_MIN = 100; } +AnimationConfig WindowNodeContainer::animationConfig_; WindowNodeContainer::WindowNodeContainer(const sptr& displayInfo, ScreenId displayGroupId) { @@ -132,7 +133,7 @@ WMError WindowNodeContainer::ShowStartingWindow(sptr& node) } UpdateWindowTree(node); displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED); - StartingWindow::UpdateRSTree(node); + StartingWindow::UpdateRSTree(node, animationConfig_); AssignZOrder(); layoutPolicy_->AddWindowNode(node); WLOGFI("ShowStartingWindow windowId: %{public}u end", node->GetWindowId()); @@ -150,6 +151,11 @@ WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr& return WMError::WM_OK; } +AnimationConfig& WindowNodeContainer::GetAnimationConfigRef() +{ + return animationConfig_; +} + WMError WindowNodeContainer::AddWindowNode(sptr& node, sptr& parentNode) { if (!node->startingWindowShown_) { @@ -401,8 +407,7 @@ void WindowNodeContainer::UpdateWindowTree(sptr& node) bool WindowNodeContainer::UpdateRSTree(sptr& node, DisplayId displayId, bool isAdd, bool animationPlayed) { HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - uint32_t animationFlag = node->GetWindowProperty()->GetAnimationFlag(); - if (animationFlag == static_cast(WindowAnimation::CUSTOM)) { + if (node->GetWindowProperty()->GetAnimationFlag() == static_cast(WindowAnimation::CUSTOM)) { WLOGFI("not need to update RsTree since SystemWindow CustomAnimation is playing"); return true; } @@ -435,19 +440,18 @@ bool WindowNodeContainer::UpdateRSTree(sptr& node, DisplayId display } } }; - if (node->EnableDefaultAnimation(IsWindowAnimationEnabled, animationPlayed)) { WLOGFI("add or remove window with animation"); - // default transition duration: 350ms - static const RSAnimationTimingProtocol timingProtocol(350); - // default transition curve: EASE OUT - static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT; - // add window with transition animation StartTraceArgs(HITRACE_TAG_WINDOW_MANAGER, "Animate(%u)", node->GetWindowId()); - RSNode::Animate(timingProtocol, curve, updateRSTreeFunc); + RSNode::Animate(animationConfig_.windowAnimationConfig_.animationTiming_.timingProtocol_, + animationConfig_.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc); FinishTrace(HITRACE_TAG_WINDOW_MANAGER); + } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && IsWindowAnimationEnabled && + !animationPlayed) { // add or remove keyboard with animation + auto timingProtocol = isAdd ? animationConfig_.keyboardAnimationConfig_.durationIn_ : + animationConfig_.keyboardAnimationConfig_.durationOut_; + RSNode::Animate(timingProtocol, animationConfig_.keyboardAnimationConfig_.curve_, updateRSTreeFunc); } else { - // add or remove window without animation WLOGFI("add or remove window without animation"); updateRSTreeFunc(); }