* Copyright (c) 2023 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.
*/
#include <gtest/gtest.h>
#include <libxml/globals.h>
#include <libxml/xmlstring.h>
#include "window_scene_config.h"
#include "window_manager_hilog.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
using ConfigItem = WindowSceneConfig::ConfigItem;
const std::string XML_STR = R"(<?xml version='1.0' encoding="utf-8"?>
<!--
* 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.
-->
<Configs>
<!--decor enable is true means app main window show decoration-->
<decor enable="false"></decor>
<!--max number of main window that could be shown on display-->
<maxAppWindowNumber>100</maxAppWindowNumber>
<!--minimizeByOther enable is true means fullscreen window will be minmized by other fullscreen window-->
<minimizeByOther enable="true"></minimizeByOther>
<!--window mdoe change hot zones config, fullscreen primary secondary-->
<modeChangeHotZones>50 50 50</modeChangeHotZones>
<!--stretchable enable is true means all window be stretchable-->
<stretchable enable="false"></stretchable>
<!--exit split screen mode ratio config-->
<exitSplitRatios>0.1 0.9</exitSplitRatios>
<!--split screen ratios config-->
<splitRatios>0.5 0.33 0.67</splitRatios>
<!--default window mode config-->
<defaultWindowMode>1</defaultWindowMode>
<!--window animation config-->
<windowAnimation>
<timing>
<!--duration of animation when add/remove window, unit is ms-->
<duration>350</duration>
<!--timing curve of animation, config it as below:
name=ease, easeIn, easeOut, easeInOut, default, linear,
spring, interactiveSpring, cubic(float float float float)-->
<curve name="easeOut"></curve>
</timing>
<!--scaleX and scaleY of animation start state-->
<scale>0.7 0.7</scale>
<!--rotation of animation start state, 4 numbers is axis and angle-->
<rotation>0 0 1 0</rotation>
<!--translateX and translateY of animation start state-->
<translate>0 0</translate>
<!--opacity of animation start state-->
<opacity>0</opacity>
</windowAnimation>
<!--keyboard animation config-->
<keyboardAnimation>
<animationIn>
<timing>
<!--duration of animation when add keyboard, unit is ms-->
<duration>500</duration>
<!--friction curve-->
<curve name="cubic">0.2 0.0 0.2 1.0</curve>
</timing>
</animationIn>
<animationOut>
<timing>
<!--duration of animation when remove keyboard, unit is ms-->
<duration>300</duration>
<!--friction curve-->
<curve name="cubic">0.2 0.0 0.2 1.0</curve>
</timing>
</animationOut>
</keyboardAnimation>
<!--enable/disable remote animation-->
<remoteAnimation enable="true"></remoteAnimation>
<!--window effect config-->
<windowEffect>
<appWindows>
<cornerRadius>
<!--off: no corner, defaultCornerRadiusXS: 4vp, defaultCornerRadiusS: 8vp-->
<!--defaultCornerRadiusM: 12vp, defaultCornerRadiusL: 16vp, defaultCornerRadiusXL: 24vp-->
<fullScreen>off</fullScreen>
<split>off</split>
<float>off</float>
</cornerRadius>
<shadow>
<focused>
<elevation>0</elevation>
<color>#000000</color>
<offsetX>0</offsetX>
<offsetY>0</offsetY>
<alpha>0</alpha>
</focused>
<unfocused>
<elevation>0</elevation>
<color>#000000</color>
<offsetX>0</offsetX>
<offsetY>0</offsetY>
<alpha>0</alpha>
</unfocused>
</shadow>
</appWindows>
</windowEffect>
</Configs>
)";
class WindowSceneConfigTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
ConfigItem ReadConfig(const std::string& xmlStr);
};
void WindowSceneConfigTest::SetUpTestCase() {}
void WindowSceneConfigTest::TearDownTestCase() {}
void WindowSceneConfigTest::SetUp() {}
void WindowSceneConfigTest::TearDown() {}
ConfigItem WindowSceneConfigTest::ReadConfig(const std::string& xmlStr)
{
ConfigItem cfgItem;
xmlDocPtr docPtr = xmlParseMemory(xmlStr.c_str(), xmlStr.length());
if (docPtr == nullptr) {
return cfgItem;
}
xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
if (rootPtr == nullptr || rootPtr->name == nullptr ||
xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
xmlFreeDoc(docPtr);
return cfgItem;
}
std::map<std::string, ConfigItem> configMap;
cfgItem.SetValue(configMap);
WindowSceneConfig::ReadConfig(rootPtr, *cfgItem.mapValue_);
xmlFreeDoc(docPtr);
return cfgItem;
}
namespace {
* @tc.name: AnimationConfig
* @tc.desc: animation config test
* @tc.type: FUNC
* @tc.require issueI5N26H
*/
HWTEST_F(WindowSceneConfigTest, AnimationConfig, TestSize.Level1)
{
WindowSceneConfig::config_ = ReadConfig(XML_STR);
ConfigItem item = WindowSceneConfig::config_["windowAnimation"];
ASSERT_EQ(true, item.IsMap());
item = WindowSceneConfig::config_["windowAnimation"]["timing"]["duration"];
ASSERT_EQ(true, item.IsInts());
auto value = *item.intsValue_;
ASSERT_EQ(true, value.size() == 1);
ASSERT_EQ(350, value[0]);
item = WindowSceneConfig::config_["windowAnimation"]["timing"]["curve"].GetProp("name");
ASSERT_EQ(true, item.IsString());
ASSERT_EQ("easeOut", item.stringValue_);
item = WindowSceneConfig::config_["windowAnimation"]["scale"];
ASSERT_EQ(true, item.IsFloats());
ASSERT_EQ(true, item.floatsValue_->size() == 2);
item = WindowSceneConfig::config_["windowAnimation"]["rotation"];
ASSERT_EQ(true, item.IsFloats());
ASSERT_EQ(true, item.floatsValue_->size() == 4);
item = WindowSceneConfig::config_["windowAnimation"]["translate"];
ASSERT_EQ(true, item.IsFloats());
ASSERT_EQ(true, item.floatsValue_->size() == 2);
item = WindowSceneConfig::config_["windowAnimation"]["opacity"];
ASSERT_EQ(true, item.IsFloats());
ASSERT_EQ(true, item.floatsValue_->size() == 1);
}
* @tc.name: maxAppWindowNumber
* @tc.desc: maxAppWindowNumber test
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneConfigTest, MaxAppWindowNumber, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<maxAppWindowNumber>0</maxAppWindowNumber>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
WindowSceneConfig::ConfigItem item;
std::vector<int> value;
item = WindowSceneConfig::config_["maxAppWindowNumber"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(true, item.IsInts());
value = *item.intsValue_;
ASSERT_EQ(true, value.size() >= 1);
ASSERT_EQ(0, value[0]);
xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<maxAppWindowNumber>-2</maxAppWindowNumber>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
item = WindowSceneConfig::config_["maxAppWindowNumber"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(true, item.IsInts());
ASSERT_EQ(true, item.intsValue_->size() == 0);
xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<maxAppWindowNumber>4</maxAppWindowNumber>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
item = WindowSceneConfig::config_["maxAppWindowNumber"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(true, item.IsInts());
ASSERT_EQ(1, item.intsValue_->size());
value = *item.intsValue_;
ASSERT_EQ(4, value[0]);
xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<maxAppWindowNumber>1000</maxAppWindowNumber>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
item = WindowSceneConfig::config_["maxAppWindowNumber"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(true, item.IsInts());
ASSERT_EQ(1, item.intsValue_->size());
value = *item.intsValue_;
ASSERT_EQ(1000, value[0]);
}
* @tc.name: DecorConfig01
* @tc.desc: set decor true and false without mode support.
* @tc.type: FUNC
* @tc.require: issueI68QCO
*/
HWTEST_F(WindowSceneConfigTest, DecorConfig01, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<decor enable=\"true\"/>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ASSERT_EQ(true, WindowSceneConfig::config_["decor"].GetProp("enable").boolValue_);
xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<decor enable=\"false\"/>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ASSERT_EQ(false, WindowSceneConfig::config_["decor"].GetProp("enable").boolValue_);
}
* @tc.name: DecorConfig02
* @tc.desc: set decor true and mode support fullscreen.
* @tc.type: FUNC
* @tc.require: issueI68QCO
*/
HWTEST_F(WindowSceneConfigTest, DecorConfig02, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<decor enable=\"true\">"
"<supportedMode>fullscreen</supportedMode>"
"</decor>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
WindowSceneConfig::ConfigItem item = WindowSceneConfig::config_["decor"]["supportedMode"];
ASSERT_EQ(true, item.IsStrings());
ASSERT_EQ(1, item.stringsValue_->size());
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(false, item.IsString());
std::vector<std::string> supportedModes;
supportedModes = *item.stringsValue_;
ASSERT_EQ("fullscreen", supportedModes[0]);
}
* @tc.name: DecorConfig03
* @tc.desc: set decor true and mode support floating.
* @tc.type: FUNC
* @tc.require: issueI68QCO
*/
HWTEST_F(WindowSceneConfigTest, DecorConfig03, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<decor enable=\"true\">"
"<supportedMode>floating</supportedMode>"
"</decor>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
WindowSceneConfig::ConfigItem item = WindowSceneConfig::config_["decor"]["supportedMode"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(false, item.IsString());
ASSERT_EQ(true, item.IsStrings());
ASSERT_EQ(1, item.stringsValue_->size());
std::vector<std::string> supportedModes;
supportedModes = *item.stringsValue_;
ASSERT_EQ("floating", supportedModes[0]);
}
* @tc.name: DecorConfig04
* @tc.desc: set decor true and mode support fullscreen|floating.
* @tc.type: FUNC
* @tc.require: issueI68QCO
*/
HWTEST_F(WindowSceneConfigTest, DecorConfig04, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<decor enable=\"true\">"
"<supportedMode>fullscreen floating</supportedMode>"
"</decor>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
WindowSceneConfig::ConfigItem item = WindowSceneConfig::config_["decor"]["supportedMode"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(false, item.IsString());
ASSERT_EQ(true, item.IsStrings());
ASSERT_EQ(2, item.stringsValue_->size());
std::vector<std::string> supportedModes;
supportedModes = *item.stringsValue_;
ASSERT_NE("fullscreen floating", supportedModes[0]);
}
* @tc.name: MoveResampleSecondaryPhaseConfig
* @tc.desc: Parse secondary phase configuration and lead time from XML
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneConfigTest, MoveResampleSecondaryPhaseConfig, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<windowLayout>"
"<moveDrag>"
"<moveResample enable=\"true\">"
"<secondaryPhase enable=\"true\">"
"<leadTimeMs>2</leadTimeMs>"
"</secondaryPhase>"
"</moveResample>"
"</moveDrag>"
"</windowLayout>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
auto secondaryPhase = WindowSceneConfig::config_["windowLayout"]["moveDrag"]["moveResample"]["secondaryPhase"];
ASSERT_TRUE(secondaryPhase.IsMap());
ASSERT_TRUE(secondaryPhase.GetProp("enable").IsBool());
EXPECT_TRUE(secondaryPhase.GetProp("enable").boolValue_);
auto leadTime = secondaryPhase["leadTimeMs"];
ASSERT_TRUE(leadTime.IsInts());
ASSERT_EQ(leadTime.intsValue_->size(), 1);
EXPECT_EQ((*leadTime.intsValue_)[0], 2);
}
* @tc.name: LoadconfigXml
* @tc.desc: load config xml
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(WindowSceneConfigTest, LoadConfigXml, TestSize.Level1)
{
auto result = WindowSceneConfig::LoadConfigXml();
ASSERT_EQ(true, result);
}
* @tc.name: ReadFloatNumbersConfigInfo
* @tc.desc: ReadFloatNumbersConfigInfo test
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneConfigTest, ReadFloatNumbersConfigInfo, TestSize.Level1)
{
xmlNodePtr currNode = xmlNewNode(NULL, BAD_CAST "nodeName");
auto result = WindowSceneConfig::ReadFloatNumbersConfigInfo(currNode, false);
ASSERT_EQ(0, result.size());
}
* @tc.name: ReadStringConfigInfo
* @tc.desc: ReadStringConfigInfo test
* @tc.type: FUNC
*/
HWTEST_F(WindowSceneConfigTest, ReadStringConfigInfo, TestSize.Level1)
{
xmlNodePtr currNode = xmlNewNode(NULL, BAD_CAST "nodeName");
auto result = WindowSceneConfig::ReadStringConfigInfo(currNode);
ASSERT_EQ(0, result.size());
}
* @tc.name: MaxMidSceneNumConfig01
* @tc.desc: set maxMidSceneNum with 3.
* @tc.type: FUNC
* @tc.require: issueI68QCO
*/
HWTEST_F(WindowSceneConfigTest, MaxMidSceneNumConfig01, Function | SmallTest | Level2)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<maxMidSceneNum>3</maxMidSceneNum>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
WindowSceneConfig::ConfigItem item = WindowSceneConfig::config_["maxMidSceneNum"];
ASSERT_EQ(false, item.IsMap());
ASSERT_EQ(true, item.IsInts());
auto value = *item.intsValue_;
ASSERT_EQ(true, value.size() >= 1);
ASSERT_EQ(3, value[0]);
}
}
}
}