From 0a152ea882f2474809ae71ee2a7cfd2ccab6856f Mon Sep 17 00:00:00 2001 From: jiadexiang Date: Fri, 15 Oct 2021 15:48:22 +0800 Subject: [PATCH] Description: support lite media query IssueNo: I4DSDQ Feature or Bugfix: Feature Binary Source:No Signed-off-by: jiadexiang --- ace_lite.gni | 2 + frameworks/include/base/product_adapter.h | 2 + frameworks/src/core/base/product_adapter.cpp | 19 + frameworks/src/core/base/scope_js_value.h | 65 ++ frameworks/src/core/base/string_util.cpp | 30 + frameworks/src/core/base/string_util.h | 1 + frameworks/src/core/base/system_info.cpp | 70 ++ frameworks/src/core/base/system_info.h | 65 ++ .../src/core/base/test/unittest/BUILD.gn | 27 + .../unittest/common/system_info_tdd_test.cpp | 192 ++++ .../unittest/common/system_info_tdd_test.h | 52 ++ .../src/core/context/js_app_environment.cpp | 2 + frameworks/src/core/stylemgr/app_style.cpp | 23 + frameworks/src/core/stylemgr/app_style.h | 5 +- .../src/core/stylemgr/app_style_item.cpp | 30 +- frameworks/src/core/stylemgr/app_style_item.h | 1 + .../src/core/stylemgr/app_style_list.cpp | 40 +- frameworks/src/core/stylemgr/app_style_list.h | 4 +- .../src/core/stylemgr/app_style_sheet.cpp | 102 +- .../src/core/stylemgr/app_style_sheet.h | 7 +- .../core/stylemgr/condition_arbitrator.cpp | 306 ++++++ .../src/core/stylemgr/condition_arbitrator.h | 70 ++ .../src/core/stylemgr/test/unittest/BUILD.gn | 22 +- .../common/condition_arbitrator_test.cpp | 533 +++++++++++ .../common/condition_arbitrator_test.h | 57 ++ .../common/stylemgr_media_query_tdd_test.cpp | 876 ++++++++++++++++++ .../common/stylemgr_media_query_tdd_test.h | 67 ++ frameworks/tools/qt/simulator/jsfwk/jsfwk.pro | 2 + test/BUILD.gn | 2 + 29 files changed, 2642 insertions(+), 32 deletions(-) create mode 100644 frameworks/src/core/base/scope_js_value.h create mode 100644 frameworks/src/core/base/system_info.cpp create mode 100644 frameworks/src/core/base/system_info.h create mode 100644 frameworks/src/core/base/test/unittest/BUILD.gn create mode 100644 frameworks/src/core/base/test/unittest/common/system_info_tdd_test.cpp create mode 100644 frameworks/src/core/base/test/unittest/common/system_info_tdd_test.h create mode 100644 frameworks/src/core/stylemgr/condition_arbitrator.cpp create mode 100644 frameworks/src/core/stylemgr/condition_arbitrator.h create mode 100644 frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.cpp create mode 100644 frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.h create mode 100644 frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.cpp create mode 100644 frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.h diff --git a/ace_lite.gni b/ace_lite.gni index 0fa93480..32cda30c 100755 --- a/ace_lite.gni +++ b/ace_lite.gni @@ -111,6 +111,7 @@ ace_lite_sources = [ "$ACE_LITE_PATH/src/core/base/number_parser.cpp", "$ACE_LITE_PATH/src/core/base/product_adapter.cpp", "$ACE_LITE_PATH/src/core/base/string_util.cpp", + "$ACE_LITE_PATH/src/core/base/system_info.cpp", "$ACE_LITE_PATH/src/core/base/time_util.cpp", "$ACE_LITE_PATH/src/core/components/analog_clock_component.cpp", "$ACE_LITE_PATH/src/core/components/camera_component.cpp", @@ -186,6 +187,7 @@ ace_lite_sources = [ "$ACE_LITE_PATH/src/core/stylemgr/app_style_list.cpp", "$ACE_LITE_PATH/src/core/stylemgr/app_style_manager.cpp", "$ACE_LITE_PATH/src/core/stylemgr/app_style_sheet.cpp", + "$ACE_LITE_PATH/src/core/stylemgr/condition_arbitrator.cpp", "$ACE_LITE_PATH/src/core/wrapper/js.cpp", "$ACE_LITE_PATH/targets/platform_adapter.cpp", ] diff --git a/frameworks/include/base/product_adapter.h b/frameworks/include/base/product_adapter.h index c0681924..4ada150c 100644 --- a/frameworks/include/base/product_adapter.h +++ b/frameworks/include/base/product_adapter.h @@ -113,6 +113,7 @@ public: static void InitNativeMemPoolHook(NativeMemInfoGetter getter); static void InitExtraModulesGetter(ProductModulesGetter productModuleGetter, PrivateModulesGetter privateModuleGetter); + static void InitDeviceInfo(const char *deviceType); static void RegTerminatingHandler(TerminateAbilityHandler handler); static void RegTEHandlers(const TEHandlingHooks &teHandlingHooks); static TEDispatchingResult DispatchTEMessage(); @@ -135,6 +136,7 @@ public: static uint8_t GetDefaultFontSize(); static void UpdateRenderTickAcceptable(bool acceptable); static void GetScreenSize(uint16_t &width, uint16_t &height); + static const char *GetDeviceType(); static bool SetScreenOnVisible(bool visible); static void LoadExtraPresetModules(); static void UnloadExtraPresetModules(); diff --git a/frameworks/src/core/base/product_adapter.cpp b/frameworks/src/core/base/product_adapter.cpp index 4cf2dbdd..a650c822 100644 --- a/frameworks/src/core/base/product_adapter.cpp +++ b/frameworks/src/core/base/product_adapter.cpp @@ -64,6 +64,12 @@ static uint16_t g_screenHeight = 454; const static char *DEFAULT_APP_DATA_PATH = "user/ace/data/"; static const char *g_defaultDataRootPath = DEFAULT_APP_DATA_PATH; +// default device info +const static uint8_t DEVICE_TYPE_STR_LEN = 24; +const static char *DEFAULT_DEVICE_TYPE_NAME = "smartVision"; +// smartVision as default +static const char *g_deviceType = DEFAULT_DEVICE_TYPE_NAME; + // indicating if the ace application is on forground static bool g_isRenderTickAcceptable = false; @@ -275,5 +281,18 @@ const char *ProductAdapter::GetPrivateDataRootPath() { return g_defaultDataRootPath; } + +void ProductAdapter::InitDeviceInfo(const char *deviceType) +{ + if (deviceType == nullptr || (strlen(deviceType) == 0) || strlen(deviceType) >= DEVICE_TYPE_STR_LEN) { + return; + } + g_deviceType = deviceType; +} + +const char *ProductAdapter::GetDeviceType() +{ + return g_deviceType; +} } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/base/scope_js_value.h b/frameworks/src/core/base/scope_js_value.h new file mode 100644 index 00000000..1d28945c --- /dev/null +++ b/frameworks/src/core/base/scope_js_value.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 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_ACELITE_SCOPE_JS_VALUE_H +#define OHOS_ACELITE_SCOPE_JS_VALUE_H + +#include "jerryscript.h" +#include "non_copyable.h" + +#include "stdlib.h" + +namespace OHOS { +namespace ACELite { +// Local scope JS value, which can be released (decrease the ref count) automaticly +// when leaving its scope, do not transfer one ScopeJSValue out of its outtest scope. +class ScopeJSValue final { +public: + ACE_DISALLOW_COPY_AND_MOVE(ScopeJSValue); + ScopeJSValue(jerry_value_t value) : value_(value) {} + ~ScopeJSValue() + { + if (value_ == 0) { + return; + } + jerry_release_value(value_); + value_ = 0; + } + + jerry_value_t Obain() const + { + return value_; + } + +private: + // disallow create the object on the heap, only can use on the stack + void *operator new(size_t size) + { + (void)(size); + // return buffer to dismiss the compolier warning, + // actually no-fact as this function never be used + const size_t bufferLen = 4; + return malloc(bufferLen); + } + void operator delete(void *ptr) + { + (void)(ptr); + } + + jerry_value_t value_ = 0; +}; +} // namespace ACELite +} // namespace OHOS +#endif // OHOS_ACELITE_SCOPE_JS_VALUE_H diff --git a/frameworks/src/core/base/string_util.cpp b/frameworks/src/core/base/string_util.cpp index e1ebae38..6337c7e5 100755 --- a/frameworks/src/core/base/string_util.cpp +++ b/frameworks/src/core/base/string_util.cpp @@ -14,6 +14,7 @@ */ #include "ace_mem_base.h" +#include "ctype.h" #include "js_config.h" #include "securec.h" #include "string_util.h" @@ -92,5 +93,34 @@ bool StringUtil::StartsWith(const char *sequence, const char *subsequence) } return strncmp(sequence, subsequence, strlen(subsequence)) == 0; } + +char *StringUtil::Trim(char *sequence) +{ + if (sequence == nullptr) { + return nullptr; + } + if (strlen(sequence) == 0) { + return sequence; + } + char *leftP = sequence; + char *rightP = sequence; + char *endP = sequence; + // find the first no-space position + while (*leftP != '\0' && isspace(*leftP)) { + leftP++; + } + // copy all charaters one by one from the first no-space position to the start of the buffer + while (*leftP != '\0') { + *rightP = *leftP; + if (!isspace(*rightP)) { + // record the next position of the last no-space character + endP = rightP + 1; + } + leftP++; + rightP++; + } + *endP = '\0'; + return sequence; +} } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/base/string_util.h b/frameworks/src/core/base/string_util.h index 93ac95e2..ce8ddea5 100644 --- a/frameworks/src/core/base/string_util.h +++ b/frameworks/src/core/base/string_util.h @@ -28,6 +28,7 @@ public: static char *Slice(const char *sequence, const int32_t start); static char *Slice(const char *sequence, const int32_t start, const int32_t end); static bool StartsWith(const char *sequence, const char *subsequence); + static char *Trim(char *sequence); }; } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/base/system_info.cpp b/frameworks/src/core/base/system_info.cpp new file mode 100644 index 00000000..781bd4f5 --- /dev/null +++ b/frameworks/src/core/base/system_info.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 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 "system_info.h" + +#include "ace_log.h" +#include "product_adapter.h" +#include "screen.h" +#include "securec.h" + +namespace OHOS { +namespace ACELite { +SystemInfo &SystemInfo::GetInstance() +{ + static SystemInfo systemInfo; + return systemInfo; +} + +void SystemInfo::Initialize() +{ + // reset + screenWidth_ = screenHeight_ = 0; + ProductAdapter::GetScreenSize(screenWidth_, screenHeight_); + if (screenWidth_ != 0 && screenHeight_ != 0) { + aspectRatio_ = (float)screenWidth_ / (float)screenHeight_; + } else { + aspectRatio_ = 0; + } + isRoundScreen_ = (Screen::GetInstance().GetScreenShape() == ScreenShape::CIRCLE); + deviceType_ = ProductAdapter::GetDeviceType(); +} + +float SystemInfo::GetAspectRatio() const +{ + return aspectRatio_; +} + +uint16_t SystemInfo::GetScreenHeight() const +{ + return screenHeight_; +} + +uint16_t SystemInfo::GetScreenWidth() const +{ + return screenWidth_; +} + +const char *SystemInfo::GetDeviceType() const +{ + return deviceType_; +} + +bool SystemInfo::IsRoundScreen() const +{ + return isRoundScreen_; +} +} // namespace ACELite +} // namespace OHOS diff --git a/frameworks/src/core/base/system_info.h b/frameworks/src/core/base/system_info.h new file mode 100644 index 00000000..61707085 --- /dev/null +++ b/frameworks/src/core/base/system_info.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021 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_ACELITE_BASE_SYSTEM_INFO_H +#define OHOS_ACELITE_BASE_SYSTEM_INFO_H + +#include "acelite_config.h" +#include "memory_heap.h" +#include "non_copyable.h" + +namespace OHOS { +namespace ACELite { +class SystemInfo final : public MemoryHeap { +public: + ACE_DISALLOW_COPY_AND_MOVE(SystemInfo); + static SystemInfo &GetInstance(); + void Initialize(); + + /** + * @brief get the value of width/height + * @return the width/height value + */ + float GetAspectRatio() const; + + /** + * @brief get the device type, support liteWearable and smartVision now + * @return the device type + */ + const char *GetDeviceType() const; + + /** + * @brief charge the device is round screen or not + * @return the device is round scrren or not + */ + bool IsRoundScreen() const; + + uint16_t GetScreenHeight() const; + + uint16_t GetScreenWidth() const; + +private: + SystemInfo() : screenWidth_(0), screenHeight_(0), aspectRatio_(0.0), deviceType_(nullptr), isRoundScreen_(false) {} + ~SystemInfo() {} + static const uint8_t DEVICE_TYPE_STR_LEN = 32; + uint16_t screenWidth_; + uint16_t screenHeight_; + float aspectRatio_; + const char *deviceType_; + bool isRoundScreen_; +}; +} // namespace ACELite +} // namespace OHOS +#endif // OHOS_ACELITE_BASE_SYSTEM_INFO_H diff --git a/frameworks/src/core/base/test/unittest/BUILD.gn b/frameworks/src/core/base/test/unittest/BUILD.gn new file mode 100644 index 00000000..f94fec0a --- /dev/null +++ b/frameworks/src/core/base/test/unittest/BUILD.gn @@ -0,0 +1,27 @@ +#Copyright (c) 2021 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. + +import("//build/lite/config/test.gni") +import("//foundation/ace/ace_engine_lite/test/ace_test_config.gni") + +unittest("js_frameworks_test_system_info") { + output_extension = "bin" + output_dir = test_output_root + configs = [ "$ace_lite_root/test:test_common_config" ] + sources = [ "common/system_info_tdd_test.cpp" ] + deps = ace_test_deps +} + +group("base_utils_unittest") { + deps = [ ":js_frameworks_test_system_info" ] +} diff --git a/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.cpp b/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.cpp new file mode 100644 index 00000000..60726c6b --- /dev/null +++ b/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2021 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 "system_info_tdd_test.h" +#include "product_adapter.h" +#include "securec.h" +#include "system_info.h" +#include "test_common.h" + +namespace OHOS { +namespace ACELite { +constexpr static char DEVICE_TYPE_NAME_SMART_VISION[] = "smartVision"; + +/** + * @tc.name: ACELite_System_Info_001 + * @tc.desc: test the default device value + */ +HWTEST_F(SystemInfoTddTest, SystemInfoTest001, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1.init the device info + */ + SystemInfo::GetInstance().Initialize(); + + /** + * @tc.steps: step2. get the device width, height and aspect-ratio + * @tc.expected: step2. the device width is 454, height is 454, aspect-ratio is 1 + */ + const uint16_t screenHeight = 454; + const uint16_t screenWidth = 454; + EXPECT_TRUE(SystemInfo::GetInstance().GetScreenHeight() == screenHeight); + EXPECT_TRUE(SystemInfo::GetInstance().GetScreenWidth() == screenWidth); + EXPECT_EQ(SystemInfo::GetInstance().GetAspectRatio(), 1); + + /** + * @tc.steps: step3. get the device type and the round screen + * @tc.expected: step3. the device type is liteWearable, the round screen is true + */ + const char *deviceType = SystemInfo::GetInstance().GetDeviceType(); + EXPECT_NE(deviceType, nullptr); + if (deviceType != nullptr) { + EXPECT_EQ(strcmp(deviceType, "smartVision"), 0); + } + EXPECT_FALSE(SystemInfo::GetInstance().IsRoundScreen()); + TDD_CASE_END(); +} + +/** + * @tc.name ACELite_System_info_002 + * @tc.desc test width/height/aspect-ratio of device is saved or not + */ +HWTEST_F(SystemInfoTddTest, SystemInfoTest002, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + /** + * @tc.steps: step1. set the device width 960px, height 480px + */ + const uint16_t screenWidth = 960; + const uint16_t screenHeight = 480; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); + + /** + * @tc.steps: step2. get the device width + * @tc.expected: step2. the device width is 960px + */ + uint16_t width = SystemInfo::GetInstance().GetScreenWidth(); + EXPECT_TRUE(width == screenWidth); + + /** + * @tc.steps: step3. get the device height + * @tc.expected: step3. the device height is 480px + */ + uint16_t height = SystemInfo::GetInstance().GetScreenHeight(); + EXPECT_TRUE(height == screenHeight); + + /** + * @tc.steps: step4. get the aspect-ratio value + * @tc.expected: step4. the aspect-ratio value is 2 + */ + const float aspectRatioValue = 2.0; + float aspectRatio = SystemInfo::GetInstance().GetAspectRatio(); + EXPECT_EQ(aspectRatio, aspectRatioValue); + + TDD_CASE_END(); +} + +/** + * @tc.name: ACELite_System_Info_003 + * @tc.desc: test the device type and the round screen type + */ +HWTEST_F(SystemInfoTddTest, SystemInfoTest003, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + /** + * @tc.steps: step1. set the device type smartVision, and the round screen false + */ + ProductAdapter::InitDeviceInfo(DEVICE_TYPE_NAME_SMART_VISION); + SystemInfo::GetInstance().Initialize(); + + /** + * @tc.steps: step2. get the screen type + * @tc.expected: step2. the screen type is false + */ + EXPECT_FALSE(SystemInfo::GetInstance().IsRoundScreen()); + + /** + * @tc.steps: step3. get the device type + * @tc.expected: step3. the device type is smartVision + */ + const char *deviceType = SystemInfo::GetInstance().GetDeviceType(); + EXPECT_NE(deviceType, nullptr); + if (deviceType != nullptr) { + EXPECT_EQ(strcmp(deviceType, "smartVision"), 0); + } + + TDD_CASE_END(); +} + +/** + * @tc.name: ACELite_System_Info_004 + * @tc.desc: test the width or height is 0 + */ +HWTEST_F(SystemInfoTddTest, SystemInfoTest004, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + /** + * @tc.steps: step1. set the device width 0, device height 100 + */ + uint16_t screenWidth = 0; + uint16_t screenHeight = 100; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); + + /** + * @tc.steps: step2. get the device width, height and aspect-ratio + * @tc.expected: step2. the device width is 0, the device height is 100, the aspect-ratio is 0 + */ + uint16_t width = SystemInfo::GetInstance().GetScreenWidth(); + EXPECT_TRUE(width == screenWidth); + uint16_t height = SystemInfo::GetInstance().GetScreenHeight(); + EXPECT_TRUE(height == screenHeight); + float aspectRatio = SystemInfo::GetInstance().GetAspectRatio(); + EXPECT_EQ(aspectRatio, 0); + + /** + * @tc.steps: step3. set the device width 100, height 0 + */ + screenWidth = 100; + screenHeight = 0; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); + + /** + * @tc.steps: step4. get the device width, hright and aspect-ratio + * @tc.expected: step4. the device width is 100, height is 0, aspect-ratio is 0 + */ + width = SystemInfo::GetInstance().GetScreenWidth(); + EXPECT_TRUE(width == screenWidth); + height = SystemInfo::GetInstance().GetScreenHeight(); + EXPECT_TRUE(height == screenHeight); + aspectRatio = SystemInfo::GetInstance().GetAspectRatio(); + EXPECT_EQ(aspectRatio, 0); + + TDD_CASE_END(); +} + +#ifndef TDD_ASSERTIONS +void SystemInfoTddTest::RunTests() +{ + SystemInfoTest001(); + SystemInfoTest002(); + SystemInfoTest003(); + SystemInfoTest004(); +} +#endif +} // namespace ACELite +} // namespace OHOS diff --git a/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.h b/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.h new file mode 100644 index 00000000..bbb35cfb --- /dev/null +++ b/frameworks/src/core/base/test/unittest/common/system_info_tdd_test.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 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_ACELITE_SYSTEM_INFO_TDD_TEST +#define OHOS_ACELITE_SYSTEM_INFO_TDD_TEST +#ifdef TDD_ASSERTIONS +#include +#include +#else +#include +#endif +namespace OHOS { +namespace ACELite { +#ifdef TDD_ASSERTIONS +using namespace std; +using namespace testing::ext; +class SystemInfoTddTest : public testing::Test { +#else +class SystemInfoTddTest { +#endif +public: + void SetUp() {} + + void TearDown() {} + + void SystemInfoTest001(); + + void SystemInfoTest002(); + + void SystemInfoTest003(); + + void SystemInfoTest004(); + +#ifndef TDD_ASSERTIONS + void RunTests(); +#endif +}; +} +} +#endif diff --git a/frameworks/src/core/context/js_app_environment.cpp b/frameworks/src/core/context/js_app_environment.cpp index 57e3e410..7b7c03ac 100755 --- a/frameworks/src/core/context/js_app_environment.cpp +++ b/frameworks/src/core/context/js_app_environment.cpp @@ -34,6 +34,7 @@ #include "presets/timer_module.h" #include "presets/version_module.h" #include "product_adapter.h" +#include "system_info.h" #ifdef JS_ENGINE_STATIC_MULTI_CONTEXTS_ENABLED extern "C" { #include "generate-bytecode.h" @@ -83,6 +84,7 @@ void JsAppEnvironment::InitJsFramework() const ProductAdapter::LoadExtraPresetModules(); LoadFramework(); LocalModule::Load(); + SystemInfo::GetInstance().Initialize(); STOP_TRACING(); } diff --git a/frameworks/src/core/stylemgr/app_style.cpp b/frameworks/src/core/stylemgr/app_style.cpp index 0bb5cbe1..ce6a1232 100644 --- a/frameworks/src/core/stylemgr/app_style.cpp +++ b/frameworks/src/core/stylemgr/app_style.cpp @@ -326,5 +326,28 @@ AppStyle *AppStyle::GenerateFromJS(jerry_value_t styleKey, jerry_value_t styleVa return newStyle; } + +void AppStyle::CombineStyles(AppStyle &dest, const AppStyle &source, bool overwrite) +{ + const AppStyleItem *styleItem = source.GetFirst(); + while (styleItem != nullptr) { + const AppStyleItem *currentStyleItemInSource = styleItem; + styleItem = styleItem->GetNext(); + const AppStyleItem *existOneInDest = dest.GetStyleItemByNameId(currentStyleItemInSource->GetPropNameId()); + + if (existOneInDest == nullptr) { + dest.AddStyleItem(AppStyleItem::CopyFrom(currentStyleItemInSource)); + continue; + } + + if (!overwrite) { + // exist one has higher priority + continue; + } + + // the new one has higher priority, to over wirte exist one + const_cast(existOneInDest)->UpdateValueFrom(*currentStyleItemInSource); + } +} } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/stylemgr/app_style.h b/frameworks/src/core/stylemgr/app_style.h index ecf34c98..8e1d09b3 100644 --- a/frameworks/src/core/stylemgr/app_style.h +++ b/frameworks/src/core/stylemgr/app_style.h @@ -33,7 +33,7 @@ public: Reset(); } - const char* GetStyleName() + const char* GetStyleName() const { return styleName_; } @@ -65,7 +65,7 @@ public: next_ = nextStyle; } - const AppStyle* GetNext() + const AppStyle* GetNext() const { return next_; } @@ -75,6 +75,7 @@ public: const AppStyleItem* GetStyleItemByName(const char * const stylePropName) const; const AppStyleItem* GetStyleItemByNameId(uint16_t stylePropNameId) const; static AppStyle* GenerateFromJS(jerry_value_t styleKey, jerry_value_t styleValue, bool isKeyFrames); + static void CombineStyles(AppStyle &dest, const AppStyle &source, bool overwrite = false); private: void SetStyleName(const char * const name, size_t nameLen); diff --git a/frameworks/src/core/stylemgr/app_style_item.cpp b/frameworks/src/core/stylemgr/app_style_item.cpp index 455b4053..814af0c4 100644 --- a/frameworks/src/core/stylemgr/app_style_item.cpp +++ b/frameworks/src/core/stylemgr/app_style_item.cpp @@ -161,33 +161,41 @@ AppStyleItem *AppStyleItem::CopyFrom(const AppStyleItem *from) return nullptr; } - styleItem->propNameId_ = from->propNameId_; - styleItem->pseudoClassType_ = from->pseudoClassType_; - switch (from->GetValueType()) { + styleItem->UpdateValueFrom(*from); + + return styleItem; +} + +void AppStyleItem::UpdateValueFrom(const AppStyleItem &from) +{ + if (valueType_ == STYLE_PROP_VALUE_TYPE_STRING) { + ACE_FREE(styleValue_.string); + } + propNameId_ = from.propNameId_; + pseudoClassType_ = from.pseudoClassType_; + switch (from.GetValueType()) { case STYLE_PROP_VALUE_TYPE_STRING: { - const char *strValue = from->GetStrValue(); + const char *strValue = from.GetStrValue(); if (strValue != nullptr) { - styleItem->SetStringValue(strValue); + SetStringValue(strValue); } break; } case STYLE_PROP_VALUE_TYPE_BOOL: - styleItem->SetBoolValue(from->GetBoolValue()); + SetBoolValue(from.GetBoolValue()); break; case STYLE_PROP_VALUE_TYPE_NUMBER: - styleItem->SetNumValue(from->GetNumValue()); + SetNumValue(from.GetNumValue()); break; case STYLE_PROP_VALUE_TYPE_FLOATING: - styleItem->SetFloatingValue(from->GetFloatingValue()); + SetFloatingValue(from.GetFloatingValue()); break; case STYLE_PROP_VALUE_TYPE_PERCENT: - styleItem->SetPercentValue(from->GetPercentValue()); + SetPercentValue(from.GetPercentValue()); break; default: break; } - - return styleItem; } } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/stylemgr/app_style_item.h b/frameworks/src/core/stylemgr/app_style_item.h index 5862e6c8..2992a6bd 100644 --- a/frameworks/src/core/stylemgr/app_style_item.h +++ b/frameworks/src/core/stylemgr/app_style_item.h @@ -166,6 +166,7 @@ public: } bool UpdateNumValToStr(); + void UpdateValueFrom(const AppStyleItem &from); static AppStyleItem *GenerateFromJSValue(jerry_value_t stylePropName, jerry_value_t stylePropValue); static AppStyleItem *CreateStyleItem(uint16_t keyId, const jerry_value_t stylePropValue, diff --git a/frameworks/src/core/stylemgr/app_style_list.cpp b/frameworks/src/core/stylemgr/app_style_list.cpp index 4413b6a2..a5401fd4 100644 --- a/frameworks/src/core/stylemgr/app_style_list.cpp +++ b/frameworks/src/core/stylemgr/app_style_list.cpp @@ -29,20 +29,50 @@ void AppStyleList::Reset() lastStyle_ = nullptr; } -void AppStyleList::AddStyle(AppStyle* newStyle) +void AppStyleList::AddStyle(AppStyle *newStyle) { if (newStyle == nullptr) { return; } + // the first one if (firstStyle_ == nullptr) { firstStyle_ = newStyle; lastStyle_ = newStyle; - } else { - newStyle->SetPre(lastStyle_); - lastStyle_->SetNext(newStyle); - lastStyle_ = newStyle; + return; + } + + // fresh new one + newStyle->SetPre(lastStyle_); + lastStyle_->SetNext(newStyle); + lastStyle_ = newStyle; +} + +AppStyle *AppStyleList::GetExistStyle(const char *name) const +{ + if (firstStyle_ == nullptr) { + return nullptr; + } + if (name == nullptr || strlen(name) == 0) { + return nullptr; } + const AppStyle *current = firstStyle_; + while (current != nullptr) { + // point to next immediately + const AppStyle *existCurrentStyle = current; + current = existCurrentStyle->GetNext(); + const char *styleName = existCurrentStyle->GetStyleName(); + + if (styleName == nullptr || strlen(styleName) == 0) { + continue; + } + if ((strlen(styleName) == strlen(name)) && strcmp(styleName, name) == 0) { + // exist + return const_cast(existCurrentStyle); + } + } + + return nullptr; } } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/stylemgr/app_style_list.h b/frameworks/src/core/stylemgr/app_style_list.h index 1369396e..dbef2cd5 100644 --- a/frameworks/src/core/stylemgr/app_style_list.h +++ b/frameworks/src/core/stylemgr/app_style_list.h @@ -31,13 +31,15 @@ public: Reset(); } - const AppStyle* GetFirst() + const AppStyle* GetFirst() const { return firstStyle_; } void Reset(); void AddStyle(AppStyle* newStyle); + bool IsStyleExist(const AppStyle &newStyle); + AppStyle *GetExistStyle(const char *name) const; private: AppStyle* firstStyle_; diff --git a/frameworks/src/core/stylemgr/app_style_sheet.cpp b/frameworks/src/core/stylemgr/app_style_sheet.cpp index 878fbeba..c7ec6b4f 100644 --- a/frameworks/src/core/stylemgr/app_style_sheet.cpp +++ b/frameworks/src/core/stylemgr/app_style_sheet.cpp @@ -14,6 +14,9 @@ */ #include "stylemgr/app_style_sheet.h" +#include "condition_arbitrator.h" +#include "js_fwk_common.h" +#include "scope_js_value.h" namespace OHOS { namespace ACELite { @@ -44,15 +47,84 @@ void AppStyleSheet::InitSheet(jerry_value_t styleSheetObj) return; } + // clear previous style sheet list Reset(); + // initializa all media query selectors first, as all media query selectors have higher priority + InitMediaSelectors(styleSheetObj); + + // initialize all other normal selectors + InitNormalSelectors(styleSheetObj); +} + +void AppStyleSheet::InitMediaSelectors(const jerry_value_t styleSheetObj) +{ + // check if media query exists in style sheet + const char * const mediaQueryArrayKeyName = "@media"; + jerry_value_t propNameV = + jerry_create_string(reinterpret_cast(const_cast(mediaQueryArrayKeyName))); + ScopeJSValue propNameP(propNameV); + if (!HasOwnProperty(styleSheetObj, propNameV)) { + // no media querry items + return; + } + + ScopeJSValue mediaQueryArrayValue(jerry_get_property(styleSheetObj, propNameV)); + if (!jerry_value_is_array(mediaQueryArrayValue.Obain())) { + return; + } + + uint32_t conditionCounts = jerry_get_array_length(mediaQueryArrayValue.Obain()); + const uint32_t maxConditionCount = 256; + if (conditionCounts == 0 || conditionCounts > maxConditionCount) { + return; + } + for (uint32_t index = 0; index < conditionCounts; index++) { + // get the array item @ index position + jerry_value_t mediaArrayItemV = jerry_get_property_by_index(mediaQueryArrayValue.Obain(), index); + ScopeJSValue mediaArrayItemP(mediaArrayItemV); + // handle single one + HandleSingleMediaItem(mediaArrayItemV); + } +} + +void AppStyleSheet::HandleSingleMediaItem(const jerry_value_t mediaItem) +{ + const char * const conditionKeyName = "condition"; + jerry_value_t conditionKeyV = jerry_create_string(reinterpret_cast(conditionKeyName)); + ScopeJSValue conditionKeyP(conditionKeyV); + if (!JerryHasProperty(mediaItem, conditionKeyV)) { + return; + } + // get condition string + jerry_value_t conditionStrJSValue = jerry_get_property(mediaItem, conditionKeyV); + ScopeJSValue autoReleaseV(conditionStrJSValue); + char *conditionStr = MallocStringOf(conditionStrJSValue); + if (conditionStr == nullptr) { + return; + } + ConditionArbitrator arbitrator; + bool isMatched = arbitrator.Decide(conditionStr); + ace_free(conditionStr); + conditionStr = nullptr; + if (!isMatched) { + // the current media item is not matching with current device environment + return; + } + + // matched, parse the item through normal way + InitNormalSelectors(mediaItem, true); +} + +void AppStyleSheet::InitNormalSelectors(const jerry_value_t styleSheetObj, bool overwrite) +{ // init all id selectors const char * const attrIdSelectors = "idSelectors"; jerry_value_t propName = jerry_create_string(reinterpret_cast(const_cast(attrIdSelectors))); jerry_value_t propValue = UNDEFINED; if (HasOwnProperty(styleSheetObj, propName)) { propValue = jerry_get_property(styleSheetObj, propName); - InitSelectors(&idSelectors_, propValue, false); + InitSelectors(&idSelectors_, propValue, false, overwrite); jerry_release_value(propValue); } jerry_release_value(propName); @@ -62,7 +134,7 @@ void AppStyleSheet::InitSheet(jerry_value_t styleSheetObj) propName = jerry_create_string(reinterpret_cast(const_cast(attrClassSelectors))); if (HasOwnProperty(styleSheetObj, propName)) { propValue = jerry_get_property(styleSheetObj, propName); - InitSelectors(&classSelectors_, propValue, false); + InitSelectors(&classSelectors_, propValue, false, overwrite); jerry_release_value(propValue); } jerry_release_value(propName); @@ -72,13 +144,14 @@ void AppStyleSheet::InitSheet(jerry_value_t styleSheetObj) propName = jerry_create_string(reinterpret_cast(const_cast(keyFrames))); if (HasOwnProperty(styleSheetObj, propName)) { propValue = jerry_get_property(styleSheetObj, propName); - InitSelectors(&keyFrameSelectors_, propValue, true); + InitSelectors(&keyFrameSelectors_, propValue, true, overwrite); jerry_release_value(propValue); } jerry_release_value(propName); } -void AppStyleSheet::InitSelectors(AppStyleList** selectorsList, jerry_value_t selectorsObj, bool isKeyFrames) +void AppStyleSheet::InitSelectors(AppStyleList **selectorsList, jerry_value_t selectorsObj, + bool isKeyFrames, bool overwrite) { if (jerry_value_is_undefined(selectorsObj)) { return; @@ -98,9 +171,16 @@ void AppStyleSheet::InitSelectors(AppStyleList** selectorsList, jerry_value_t se /* convert style key into char */ jerry_value_t styleKey = jerry_get_property_by_index(styleKeys, index); jerry_value_t styleValue = jerry_get_property(selectorsObj, styleKey); - AppStyle* newStyle = AppStyle::GenerateFromJS(styleKey, styleValue, isKeyFrames); + AppStyle *newStyle = AppStyle::GenerateFromJS(styleKey, styleValue, isKeyFrames); if (newStyle != nullptr) { - (*selectorsList)->AddStyle(newStyle); + AppStyle *existOne = (*selectorsList)->GetExistStyle(newStyle->GetStyleName()); + if (existOne != nullptr) { + AppStyle::CombineStyles(*existOne, *newStyle, overwrite); + delete newStyle; // combined to exist one, no used + newStyle = nullptr; + } else { + (*selectorsList)->AddStyle(newStyle); + } } ReleaseJerryValue(styleKey, styleValue, VA_ARG_END_FLAG); } @@ -108,28 +188,28 @@ void AppStyleSheet::InitSelectors(AppStyleList** selectorsList, jerry_value_t se jerry_release_value(styleKeys); } -AppStyle* AppStyleSheet::GetStyleFromIDSelectors(const char * const name) const +AppStyle *AppStyleSheet::GetStyleFromIDSelectors(const char * const name) const { return GetStyleFromSelectors(idSelectors_, name); } -AppStyle* AppStyleSheet::GetStyleFromClassSelectors(const char * const name) const +AppStyle *AppStyleSheet::GetStyleFromClassSelectors(const char * const name) const { return GetStyleFromSelectors(classSelectors_, name); } -AppStyle* AppStyleSheet::GetStyleFromKeyFramesSelectors(const char * const name) const +AppStyle *AppStyleSheet::GetStyleFromKeyFramesSelectors(const char * const name) const { return GetStyleFromSelectors(keyFrameSelectors_, name); } -AppStyle* AppStyleSheet::GetStyleFromSelectors(AppStyleList* selectors, const char * const name) const +AppStyle *AppStyleSheet::GetStyleFromSelectors(AppStyleList *selectors, const char * const name) const { if ((selectors == nullptr) || (name == nullptr) || strlen(name) == 0) { return nullptr; } - AppStyle* first = const_cast(selectors->GetFirst()); + AppStyle *first = const_cast(selectors->GetFirst()); while (first != nullptr) { const char *styleName = first->GetStyleName(); if (styleName != nullptr && !strcmp(name, styleName)) { diff --git a/frameworks/src/core/stylemgr/app_style_sheet.h b/frameworks/src/core/stylemgr/app_style_sheet.h index e92ce1fa..f6a1dd97 100644 --- a/frameworks/src/core/stylemgr/app_style_sheet.h +++ b/frameworks/src/core/stylemgr/app_style_sheet.h @@ -17,6 +17,7 @@ #define OHOS_ACELITE_APP_STYLE_SHEET_H #include "non_copyable.h" +#include "scope_js_value.h" #include "stylemgr/app_style_item.h" #include "stylemgr/app_style_list.h" @@ -41,7 +42,11 @@ public: AppStyleList* keyFrameSelectors_; private: - void InitSelectors(AppStyleList** selectorsList, jerry_value_t selectorsObj, bool isKeyFrames); + void InitNormalSelectors(const jerry_value_t styleSheetObj, bool overwrite = false); + void InitMediaSelectors(const jerry_value_t styleSheetObj); + void HandleSingleMediaItem(const jerry_value_t mediaItem); + void InitSelectors(AppStyleList** selectorsList, jerry_value_t selectorsObj, + bool isKeyFrames, bool overwrite = false); }; } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/stylemgr/condition_arbitrator.cpp b/frameworks/src/core/stylemgr/condition_arbitrator.cpp new file mode 100644 index 00000000..ec607a65 --- /dev/null +++ b/frameworks/src/core/stylemgr/condition_arbitrator.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2021 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 "condition_arbitrator.h" + +#include "ace_log.h" +#include "js_fwk_common.h" +#include "securec.h" +#include "stdlib.h" +#include "string_util.h" +#include "strings.h" +#include "system_info.h" + +namespace OHOS { +namespace ACELite { +/** + * @brief Absolute value of x. + */ +#define ABS_VALUE(x) ((x) > 0 ? (x) : (-(x))) + +/** + * @brief parse the whole condition string into single condition items, and check if it matchs the current device + * environment, and gives the final result of the entire media query expression. + * @param conditions the input media query condition string + * @return the result representing if the media query matchs the current environment, true for positive result + * + * NOTE: only supports the pattern such as "screen and (device-type: liteWearable) and (width: 454)" + */ +bool ConditionArbitrator::Decide(const char *conditions) const +{ + if (conditions == nullptr || strlen(conditions) == 0) { + HILOG_ERROR(HILOG_MODULE_ACE, "the input condition str is invalid"); + return false; + } + + const char *lastCondition = conditions; + const char *remainCondition = lastCondition; + char *singleCondition = nullptr; + const uint8_t addedLen = 3; + bool result = true; + while (result && remainCondition) { + lastCondition = remainCondition; + remainCondition = strstr(remainCondition, "and"); + singleCondition = StringUtil::Slice( + lastCondition, 0, strlen(lastCondition) - ((remainCondition == nullptr) ? 0 : strlen(remainCondition))); + if (remainCondition != nullptr) { + remainCondition = remainCondition + addedLen; + } + char *condition = StringUtil::Trim(singleCondition); + if (condition == nullptr) { + continue; + } + result = JudgeCondition(condition); + ace_free(singleCondition); + singleCondition = nullptr; + } + ACE_FREE(singleCondition); + return result; +} + +bool ConditionArbitrator::JudgeCondition(const char *condition) const +{ + if (condition == nullptr || strlen(condition) == 0) { + HILOG_ERROR(HILOG_MODULE_ACE, "the condition is invalid"); + return false; + } + + // treat screen as one single media query feature, and it always is true for any devices + if (strcmp(condition, "screen") == 0) { + return true; + } + + uint8_t conditionLen = strlen(condition); + // the condition must start with '(', end with ')' + if (condition[0] != '(' || (conditionLen <= 1) || (condition[conditionLen - 1] != ')')) { + HILOG_ERROR(HILOG_MODULE_ACE, "error format, condition is not properly packed with ( )"); + return false; + } + const uint8_t minTargetLen = 2; + char *targetCondition = StringUtil::Slice(condition, 1, conditionLen - minTargetLen + 1); + if (targetCondition == nullptr) { + return false; + } + // devide the target condition into two parts : conditionName and value through ":" + char *targetValue = nullptr; + char *conditionNameStr = strtok_s(targetCondition, ":", &targetValue); + // judge the condition is success or not + ConditionName conditionId = GetConditionName(StringUtil::Trim(conditionNameStr)); + char *trimedTargetValue = StringUtil::Trim(targetValue); + if (conditionId == ConditionName::UNKOWN || trimedTargetValue == nullptr) { + ace_free(targetCondition); + targetCondition = nullptr; + return false; + } + bool result = JudgeConditionAction(conditionId, trimedTargetValue); + ace_free(targetCondition); + targetCondition = nullptr; + return result; +} + +bool ConditionArbitrator::JudgeConditionAction(ConditionName conditionId, const char *trimedTargetValue) const +{ + if (trimedTargetValue == nullptr || strlen(trimedTargetValue) == 0) { + return false; + } + switch (conditionId) { + case ConditionName::DEVICE_TYPE: // fall through + case ConditionName::ROUND_SCREEN: + return JudgeConditionByStrValue(conditionId, trimedTargetValue); + case ConditionName::WIDTH: // fall through + case ConditionName::MIN_WIDTH: // fall through + case ConditionName::MAX_WIDTH: // fall through + case ConditionName::HEIGHT: // fall through + case ConditionName::MIN_HEIGHT: // fall through + case ConditionName::MAX_HEIGHT: // fall through + case ConditionName::ASPECT_RATIO: // fall through + case ConditionName::MIN_ASPECT_RATIO: // fall through + case ConditionName::MAX_ASPECT_RATIO: { + return JudgeConditionByNumberValue(conditionId, trimedTargetValue); + } + default: { + HILOG_ERROR(HILOG_MODULE_ACE, "not supported condition feature %{public}d", conditionId); + return false; + } + } +} + +bool ConditionArbitrator::JudgeConditionByStrValue(ConditionName conditionId, const char *trimedTargetValue) const +{ + bool result = false; + switch (conditionId) { + case ConditionName::DEVICE_TYPE: { + result = (strcmp(trimedTargetValue, SystemInfo::GetInstance().GetDeviceType()) == 0); + break; + } + case ConditionName::ROUND_SCREEN: { + if (!strcmp(trimedTargetValue, "TRUE") || !strcmp(trimedTargetValue, "true") || + !strcmp(trimedTargetValue, "1")) { + result = (SystemInfo::GetInstance().IsRoundScreen() == true); + } else if (!strcmp(trimedTargetValue, "FALSE") || !strcmp(trimedTargetValue, "false") || + !(strcmp(trimedTargetValue, "0"))) { + result = (SystemInfo::GetInstance().IsRoundScreen() == false); + } else { + result = false; + } + break; + } + default: { + return false; + } + } + return result; +} + +bool ConditionArbitrator::JudgeConditionByNumberValue(ConditionName conditionId, const char *targetValue) const +{ + // must be started with number character + if (!(targetValue[0] >= 48 && targetValue[0] <= 57)) { + return false; + } + switch (conditionId) { + case ConditionName::WIDTH: // fall through + case ConditionName::MIN_WIDTH: // fall through + case ConditionName::MAX_WIDTH: // fall through + case ConditionName::HEIGHT: // fall through + case ConditionName::MIN_HEIGHT: // fall through + case ConditionName::MAX_HEIGHT: { + return CompareIntDimension(conditionId, targetValue); + } + case ConditionName::ASPECT_RATIO: // fall through + case ConditionName::MIN_ASPECT_RATIO: // fall through + case ConditionName::MAX_ASPECT_RATIO: { + return CompareFloatDimension(conditionId, targetValue); + } + default: { + return false; + } + } +} + +bool ConditionArbitrator::CompareIntDimension(ConditionName conditionId, const char *targetValue) const +{ + int dimensionValue = atoi(targetValue); + if (dimensionValue <= 0 || dimensionValue >= UINT16_MAX) { + return false; + } + switch (conditionId) { + case ConditionName::WIDTH: { + return SystemInfo::GetInstance().GetScreenWidth() == dimensionValue; + } + case ConditionName::MIN_WIDTH: { + // the device screen width must be larger than the requirement + return SystemInfo::GetInstance().GetScreenWidth() >= dimensionValue; + } + case ConditionName::MAX_WIDTH: { + // the device screen width must be smaller than the requirement + return SystemInfo::GetInstance().GetScreenWidth() <= dimensionValue; + } + case ConditionName::HEIGHT: { + return SystemInfo::GetInstance().GetScreenHeight() == dimensionValue; + } + case ConditionName::MIN_HEIGHT: { + // the device screen height must be larger than the requirement + return SystemInfo::GetInstance().GetScreenHeight() >= dimensionValue; + } + case ConditionName::MAX_HEIGHT: { + // the device screen height must be smaller than the requirement + return SystemInfo::GetInstance().GetScreenHeight() <= dimensionValue; + } + default: + return false; + } +} + +bool ConditionArbitrator::IsFloatValueEqual(float left, float right, float precision) const +{ + return (ABS_VALUE(left - right) < precision); +} + +bool ConditionArbitrator::CompareFloatDimension(ConditionName conditionId, const char *targetValue) const +{ + float floatValue = atof(targetValue); + switch (conditionId) { + case ConditionName::ASPECT_RATIO: // fall through + case ConditionName::MIN_ASPECT_RATIO: // fall through + case ConditionName::MAX_ASPECT_RATIO: { + return CompareAspectRatio(conditionId, floatValue); + } + default: { + return false; + } + } +} + +bool ConditionArbitrator::CompareAspectRatio(ConditionName conditionId, float targetRatioValue) const +{ + float currentAspectRatio = SystemInfo::GetInstance().GetAspectRatio(); + bool isEqual = IsFloatValueEqual(targetRatioValue, currentAspectRatio, CONDITION_FLOAT_VALUE_EPRECISION); + if (isEqual) { + // the equal case matchs for all ASPECT_RATIO media feature types + return true; + } + switch (conditionId) { + case ConditionName::ASPECT_RATIO: { + return isEqual; + } + case ConditionName::MIN_ASPECT_RATIO: { + return currentAspectRatio > targetRatioValue; + } + case ConditionName::MAX_ASPECT_RATIO: { + return currentAspectRatio < targetRatioValue; + } + default: { + return false; + } + } +} + +ConditionName ConditionArbitrator::GetConditionName(const char *conditionName) const +{ + if (conditionName == nullptr || strlen(conditionName) == 0) { + return ConditionName::UNKOWN; + } + static const struct { + const char *nameStr; + ConditionName name; + } conditionNamePair[ConditionName::MAX_COUNT] = { + {"width", ConditionName::WIDTH}, + {"height", ConditionName::HEIGHT}, + {"min-width", ConditionName::MIN_WIDTH}, + {"max-width", ConditionName::MAX_WIDTH}, + {"min-height", ConditionName::MIN_HEIGHT}, + {"max-height", ConditionName::MAX_HEIGHT}, + {"aspect-ratio", ConditionName::ASPECT_RATIO}, + {"min-aspect-ratio", ConditionName::MIN_ASPECT_RATIO}, + {"max-aspect-ratio", ConditionName::MAX_ASPECT_RATIO}, + {"device-type", ConditionName::DEVICE_TYPE}, + {"round-screen", ConditionName::ROUND_SCREEN} + }; + ConditionName targetName = ConditionName::UNKOWN; + uint8_t index = 0; + for (; index < ConditionName::UNKOWN; index++) { + if (strcmp(conditionName, conditionNamePair[index].nameStr) == 0) { + targetName = conditionNamePair[index].name; + break; + } + } + if (index == ConditionName::UNKOWN) { + HILOG_ERROR(HILOG_MODULE_ACE, "the condition name is not supported [%{public}s]", conditionName); + } + return targetName; +} +} // namespace ACELite +} // namespace OHOS diff --git a/frameworks/src/core/stylemgr/condition_arbitrator.h b/frameworks/src/core/stylemgr/condition_arbitrator.h new file mode 100644 index 00000000..5b209f2f --- /dev/null +++ b/frameworks/src/core/stylemgr/condition_arbitrator.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 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_ACELITE_STYLEMGR_CONDITION_ARBITRATOR +#define OHOS_ACELITE_STYLEMGR_CONDITION_ARBITRATOR + +#include "memory_heap.h" +#include "non_copyable.h" + +namespace OHOS { +namespace ACELite { +enum ConditionName : uint8_t { + WIDTH, + MIN_WIDTH, + MAX_WIDTH, + HEIGHT, + MIN_HEIGHT, + MAX_HEIGHT, + ASPECT_RATIO, + MIN_ASPECT_RATIO, + MAX_ASPECT_RATIO, + ROUND_SCREEN, + DEVICE_TYPE, + UNKOWN, + MAX_COUNT = UNKOWN +}; + +class ConditionArbitrator final : public MemoryHeap { +public: + ACE_DISALLOW_COPY_AND_MOVE(ConditionArbitrator); + ConditionArbitrator() = default; + virtual ~ConditionArbitrator() = default; + + /** + * @brief determine whether the media query conditions are met based on + * the current device environment + * @return the result whether the condition is met + */ + bool Decide(const char *conditions) const; + +private: + /** + * @brief judge the single condition is success or not + */ + bool JudgeCondition(const char *condition) const; + bool JudgeConditionAction(ConditionName conditionId, const char *trimedTargetValue) const; + bool JudgeConditionByStrValue(ConditionName conditionId, const char *trimedTargetValue) const; + bool JudgeConditionByNumberValue(ConditionName conditionId, const char *targetValue) const; + bool CompareIntDimension(ConditionName conditionId, const char *targetValue) const; + bool CompareFloatDimension(ConditionName conditionId, const char *targetValue) const; + bool CompareAspectRatio(ConditionName conditionId, float targetRatioValue) const; + ConditionName GetConditionName(const char *conditionName) const; + bool IsFloatValueEqual(float left, float right, float precision) const; + static constexpr float CONDITION_FLOAT_VALUE_EPRECISION = 1E-5; +}; +} // namespace ACELite +} // namespace OHOS +#endif // OHOS_ACELITE_STYLEMGR_CONDITION_ARBITRATOR diff --git a/frameworks/src/core/stylemgr/test/unittest/BUILD.gn b/frameworks/src/core/stylemgr/test/unittest/BUILD.gn index 7cbfa2db..cdd2c687 100755 --- a/frameworks/src/core/stylemgr/test/unittest/BUILD.gn +++ b/frameworks/src/core/stylemgr/test/unittest/BUILD.gn @@ -26,6 +26,26 @@ unittest("js_frameworks_test_stylemgr") { deps = ace_test_deps } +unittest("js_frameworks_test_condition_arbitrator") { + output_extension = "bin" + output_dir = test_output_root + configs = [ "$ace_lite_root/test:test_common_config" ] + sources = [ "common/condition_arbitrator_test.cpp" ] + deps = ace_test_deps +} + +unittest("js_frameworks_test_stylemgr_media_query") { + output_extension = "bin" + output_dir = test_output_root + configs = [ "$ace_lite_root/test:test_common_config" ] + sources = [ "common/stylemgr_media_query_tdd_test.cpp" ] + deps = ace_test_deps +} + group("stylemgr_unittest") { - deps = [ ":js_frameworks_test_stylemgr" ] + deps = [ + ":js_frameworks_test_condition_arbitrator", + ":js_frameworks_test_stylemgr", + ":js_frameworks_test_stylemgr_media_query", + ] } diff --git a/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.cpp b/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.cpp new file mode 100644 index 00000000..54e3cd38 --- /dev/null +++ b/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2021 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 "condition_arbitrator_test.h" +#include "condition_arbitrator.h" +#include "product_adapter.h" +#include "system_info.h" +#include "test_common.h" + +namespace OHOS { +namespace ACELite { +void ConditionArbitratorTest::SetUp() +{ + // set the device with 960px, height 480px + const uint16_t screenHeight = 480; + const uint16_t screenWidth = 960; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + ProductAdapter::InitDeviceInfo("smartVision"); + SystemInfo::GetInstance().Initialize(); +} + +/** + * @tc.name: MaxWidthTest001 + * @tc.desc: test the condition max-width + */ +HWTEST_F(ConditionArbitratorTest, MaxWidthTest001, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition max-width is 980 + * @tc.expected: step1. the condition check result is positive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("(max-width : 980)")); + + EXPECT_TRUE(conditionArbitrator.Decide("( max-width : 980px)")); + + /** + * @tc.steps: step2. the condition max-width is 900 + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-width : 900)")); + + /** + * @tc.steps: step3. the condition max-width is test + * @tc.expected: step3. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-width : test")); + TDD_CASE_END(); +} + +/** + * @tc.desc:MinWidthTest002 + * @tc.expected: test the min-width condition + */ +HWTEST_F(ConditionArbitratorTest, MinWidthTest002, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition min-width is 980 + * @tc.expected: step2. the condition check result is nagtive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(min-width : 980)")); + + /** + * @tc.steps: step1. the condition min-width is 900 + * @tc.expected: step1. the condition check result is positive + */ + EXPECT_TRUE(conditionArbitrator.Decide("(min-width: 900)")); + + /** + * @tc.steps: step2. the condition min-width is test + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(min-width: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: WidthTest003 + * @tc.desc: test the condition width + */ +HWTEST_F(ConditionArbitratorTest, WidthTest003, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition width is 980 + * @tc.expected: step2. the condition is false + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(width: 980)")); + + /** + * @tc.steps: step2. set the condition width is 900 + * @tc.steps: step2. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(width: 900)")); + + /** + * @tc.steps: step3. set the condition width is 960 + * @tc.expected: step3. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(width: 960)")); + + /** + * @tc.steps: step4. set the condition is test + * @tc.expected: step4. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(width: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: maxHeightTest004 + * @tc.desc: test the condition max-width + */ +HWTEST_F(ConditionArbitratorTest, MaxHeightTest004, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition max-height is 500 + * @tc.expected: step1. the condition check result is positive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("(max-height : 500)")); + + /** + * @tc.steps: step2. the condition max-width is 400 + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-height : 400)")); + + /** + * @tc.steps: step3. the condition max-height is test + * @tc.expected: step3. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-height : test")); + TDD_CASE_END(); +} + +/** + * @tc.desc:MinHeightTest005 + * @tc.expected: test the min-height condition + */ +HWTEST_F(ConditionArbitratorTest, MinHeightTest005, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition min-height is 480 + * @tc.expected: step2. the condition check result is nagtive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("(min-height : 480)")); + + /** + * @tc.steps: step1. the condition min-height is 400 + * @tc.expected: step1. the condition check result is positive + */ + EXPECT_TRUE(conditionArbitrator.Decide("(min-height: 400)")); + + /** + * @tc.steps: step2. the condition min-height is test + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(min-height: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: HeightTest006 + * @tc.desc: test the condition height + */ +HWTEST_F(ConditionArbitratorTest, HeightTest006, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition height is 500 + * @tc.expected: step2. the condition is false + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(height: 500)")); + + /** + * @tc.steps: step2. set the condition height is 400 + * @tc.steps: step2. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(height: 400)")); + + /** + * @tc.steps: step3. set the condition height is 480 + * @tc.expected: step3. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(height: 480)")); + + /** + * @tc.steps: step4. set the condition height is test + * @tc.expected: step4. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(height: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: MaxAspectRatioTest007 + * @tc.desc: test the condition max-aspect-ratio + */ +HWTEST_F(ConditionArbitratorTest, MaxAspectRatioTest007, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition max-aspect-ratio is 3 + * @tc.expected: step1. the condition check result is positive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("(max-aspect-ratio : 3)")); + + /** + * @tc.steps: step2. the condition max-aspect-ratio is 1 + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-aspect-ratio : 1)")); + + /** + * @tc.steps: step3. the condition max-aspect-ratio is test + * @tc.expected: step3. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(max-aspect-ratio : test")); + TDD_CASE_END(); +} + +/** + * @tc.desc:MinAspectRatioTest008 + * @tc.expected: test the min-aspect-ratio condition + */ +HWTEST_F(ConditionArbitratorTest, MinAspectRatioTest008, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition min-aspect-ratio is 980 + * @tc.expected: step2. the condition check result is nagtive + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(min-aspect-ratio : 3)")); + + /** + * @tc.steps: step1. the condition min-aspect-ratio is 1 + * @tc.expected: step1. the condition check result is positive + */ + EXPECT_TRUE(conditionArbitrator.Decide("(min-aspect-ratio: 1)")); + + /** + * @tc.steps: step2. the condition min-aspect-ratio is test + * @tc.expected: step2. the condition check result is nagtive + */ + EXPECT_FALSE(conditionArbitrator.Decide("(min-aspect-ratio: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: AspectRatioTest009 + * @tc.desc: test the condition width + */ +HWTEST_F(ConditionArbitratorTest, AspectRatioTest009, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition aspect-ratio is 3 + * @tc.expected: step2. the condition is false + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(aspect-ratio: 3)")); + + /** + * @tc.steps: step2. set the condition aspect-ratio is 1 + * @tc.steps: step2. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(aspect-ratio: 1)")); + + /** + * @tc.steps: step3. set the condition aspect-ratio is 2 + * @tc.expected: step3. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(aspect-ratio : 2)")); + + /** + * @tc.steps: step4. set the condition aspect-ratio is test + * @tc.expected: step4. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(aspect-ratio: test)")); + + TDD_CASE_END(); +} + +/** + * @tc.desc:AspectRatioTest010 + * @tc.expected: test the aspect-ratio condition checking base on float values + */ +HWTEST_F(ConditionArbitratorTest, AspectRatioTest010, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the condition min-aspect-ratio is 980 + * @tc.expected: step2. the condition check result is nagtive + */ + ConditionArbitrator conditionArbitrator; + // prepare one float screen aspect ratio, 0.6140350877192982 + uint16_t screenWidth = 280; + uint16_t screenHeight = 456; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); + EXPECT_FALSE(conditionArbitrator.Decide("(min-aspect-ratio : 0.615)")); + + /** + * @tc.steps: step1. the condition min-aspect-ratio is 1 + * @tc.expected: step1. the condition check result is positive + */ + screenWidth = 456; + screenHeight = 280; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); // aspect ratio: 1.628571428571429 + EXPECT_TRUE(conditionArbitrator.Decide("(max-aspect-ratio: 1.628566)")); + + /** + * @tc.steps: step2. the condition min-aspect-ratio is test + * @tc.expected: step2. the condition check result is nagtive + */ + screenWidth = 300; + screenHeight = 466; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); // aspect ratio: 0.6437768240343348 + EXPECT_FALSE(conditionArbitrator.Decide("(aspect-ratio: 0.6)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: DeviceTypeTest010 + * @tc.desc: test the device type + */ +HWTEST_F(ConditionArbitratorTest, DeviceTypeTest011, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. test the device type value smartVision + * @tc.expected: step1. the condition is success + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("(device-type: smartVision)")); + + /** + * @tc.steps: step2. set the condition device-type is liteWearable + * @tc.expected: step2. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(device-type: liteWearable)")); + + /** + * @tc.steps: step3. set the condition device-type is testDevice + * @tc.expected: step3. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(device-type: testDevice)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: RoundScreenTest011 + * @tc.desc: test the round screen condition + */ +HWTEST_F(ConditionArbitratorTest, RoundScreenTest012, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition round screen true + * @tc.expected: step1. the condition is false + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide("(round-screen: true)")); + + /** + * @tc.steps: step2. set the condition round screen false + * @tc.expected: step2. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(round-screen: false)")); + + /** + * @tc.steps: step3. set the condition round screen true + * @tc.expected: step3. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(round-screen: TRUE)")); + + /** + * @tc.steps: step4. set the condition round screen false + * @tc.expected: step4. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(round-screen: FALSE)")); + + /** + * @tc.steps: step5. set the condition round screen false + * @tc.expected: step5. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide("(round-screen: 0)")); + + /** + * @tc.steps: step6. set the condition round screen true + * @tc.expected: step6. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(round-screen: 1)")); + + /** + * @tc.steps: step7. the condition round screen testDevice + * @tc.expected: step7. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("(round-screen: testDevice)")); + + TDD_CASE_END(); +} + +/** + * @tc.name: CombineConditionTest012 + * @tc.desc:test the combine condition + */ +HWTEST_F(ConditionArbitratorTest, CombineConditionTest013, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition is screen and (width:960) and (min-height:480) + * @tc.expected: step1. the condition is true + */ + ConditionArbitrator conditionArbitrator; + EXPECT_TRUE(conditionArbitrator.Decide("screen and (width: 960) and (min-height: 480)")); + + /** + * @tc.steps: step2. set the condition is screen and (max-width : 1028) and (height:480) + * @tc.expected: step2. the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide(" (max-width: 1028) and (height: 480)")); + + /** + * @tc.steps: step3. set the condition is screen and (min-width : 480) and (max-height : 320) + * @tc.expected: step3. the condition is false + */ + EXPECT_FALSE(conditionArbitrator.Decide("and (min-width: 480) and (max-height: 320)")); + + TDD_CASE_END(); +} + +/** + * @tc.name:CombineConditionTest013 + * @tc.desc:test the combine condition + */ +HWTEST_F(ConditionArbitratorTest, CombineConditionTest014, TestSize.Level0) +{ + TDD_CASE_BEGIN(); + + /** + * @tc.steps: step1. set the condition screen and min-aspect-ratio 1 and round screen true + * and device-type liteWerable + * @tc.expected: step1. the condition is false + */ + ConditionArbitrator conditionArbitrator; + EXPECT_FALSE(conditionArbitrator.Decide( + "screen and (min-aspect-ratio: 1) and (round-screen: true) and (device-type: liteWearable)")); + + /** + * @tc.steps: step2. set the condition screen and aspect-ratio 2 and round-screen false + * and the device-type smartVision + * @tc.expected: step2. the condition is flase + */ + EXPECT_FALSE(conditionArbitrator.Decide( + "screen and (min-aspect-ratio: 1) and (round-screen: true) and (device-type: smartVision)")); + + /** + * @tc.steps: step3. set the condition screen and max-aspect-ratio 3 and round-screen false + * and device-type liteWearable + * @tc.expected: the condition is true + */ + EXPECT_TRUE(conditionArbitrator.Decide( + "screen and (max-aspect-ratio: 3) and (device-type: smartVision) and (round-screen: false)")); + TDD_CASE_END(); +} + +#ifndef TDD_ASSERTIONS +void ConditionArbitratorTest::RunTests() +{ + MaxWidthTest001(); + MinWidthTest002(); + WidthTest003(); + MaxHeightTest004(); + MinHeightTest005(); + HeightTest006(); + MaxAspectRatioTest007(); + MinAspectRatioTest008(); + AspectRatioTest009(); + AspectRatioTest010(); + DeviceTypeTest011(); + RoundScreenTest012(); + CombineConditionTest013(); + CombineConditionTest014(); +} +#endif +} +} diff --git a/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.h b/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.h new file mode 100644 index 00000000..1b2e255e --- /dev/null +++ b/frameworks/src/core/stylemgr/test/unittest/common/condition_arbitrator_test.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 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_ACELITE_CONDITION_ARBITRATOR_TEST_H +#define OHOS_ACELITE_CONDITION_ARBITRATOR_TEST_H +#ifdef TDD_ASSERTIONS +#include +#include +#else +#include +#endif +namespace OHOS { +namespace ACELite { +#ifdef TDD_ASSERTIONS +using namespace std; +using namespace testing::ext; +class ConditionArbitratorTest : public testing::Test { +#else +class ConditionArbitratorTest { +#endif +public: + void SetUp(); + void TearDown() {} + void MaxWidthTest001(); + void MinWidthTest002(); + void WidthTest003(); + void MaxHeightTest004(); + void MinHeightTest005(); + void HeightTest006(); + void MaxAspectRatioTest007(); + void MinAspectRatioTest008(); + void AspectRatioTest009(); + void AspectRatioTest010(); + void DeviceTypeTest011(); + void RoundScreenTest012(); + void CombineConditionTest013(); + void CombineConditionTest014(); + +#ifndef TDD_ASSERTIONS + void RunTests(); +#endif +}; +} +} +#endif diff --git a/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.cpp b/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.cpp new file mode 100644 index 00000000..eb82db85 --- /dev/null +++ b/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.cpp @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2021 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 "stylemgr_media_query_tdd_test.h" + +#include "js_debugger_config.h" +#include "key_parser.h" +#include "product_adapter.h" +#include "scope_js_value.h" +#include "system_info.h" + +namespace OHOS { +namespace ACELite { +namespace StyleSheetCSSData { +const char CSS_DATA_TEST_001[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 400," + " \"height\": 400" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: phone)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }," + " \"containerNew\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }," + " {" + " \"condition\": \"screen and (height: 1024)\"," + " \"classSelectors\": {" + " \"button\": {" + " \"borderTopWidth\": 5," + " \"borderRightWidth\": 5," + " \"borderBottomWidth\": 5," + " \"borderLeftWidth\": 5" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_002[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"justifyContent\": \"center\"," + " \"alignItems\": \"center\"," + " \"backgroundColor\": 32768" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80," + " \"borderTopWidth\": 2," + " \"borderRightWidth\": 2," + " \"borderBottomWidth\": 2," + " \"borderLeftWidth\": 2," + " \"color\": 16711680" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }," + " \"containerNew\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_003[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"containerNew\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_004[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"justifyContent\": \"center\"," + " \"alignItems\": \"center\"," + " \"backgroundColor\": 32768" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 215026" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_005[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_006[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"justifyContent\": \"center\"," + " \"alignItems\": \"center\"," + " \"backgroundColor\": 32768" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80," + " \"borderTopWidth\": 2," + " \"borderRightWidth\": 2," + " \"borderBottomWidth\": 2," + " \"borderLeftWidth\": 2," + " \"color\": 16711680" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }," + " \"button\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_007[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"backgroundColor\": 32768" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }," + " \"container\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_008[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"backgroundColor\": 32768" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80," + " \"borderTopWidth\": 2," + " \"borderRightWidth\": 2," + " \"borderBottomWidth\": 2," + " \"borderLeftWidth\": 2," + " \"color\": 16711680" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 121301" + " }" + " }" + " }," + " {" + " \"condition\": \"screen and (height: 466)\"," + " \"classSelectors\": {" + " \"button\": {" + " \"borderTopWidth\": 5," + " \"borderRightWidth\": 5," + " \"borderBottomWidth\": 5," + " \"borderLeftWidth\": 5" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_009[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"backgroundColor\": 32768" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }" + " }" + " }," + " {" + " \"condition\": \"screen and (height: 960)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 16711680" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_010[] = + "{" + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 123456" + " }" + " }" + " }" + " ]," + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 390," + " \"height\": 390," + " \"backgroundColor\": 8421504" + " }" + " }" + "}"; + +const char CSS_DATA_TEST_011[] = + "{" + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {" + " \"backgroundColor\": 8421504" + " }," + " \"containerNew\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }," + " {" + " \"condition\": \"screen and (height: 1024)\"," + " \"classSelectors\": {" + " \"button\": {" + " \"borderTopWidth\": 5," + " \"borderRightWidth\": 5," + " \"borderBottomWidth\": 5," + " \"borderLeftWidth\": 5" + " }" + " }" + " }" + " ]" + "}"; + +const char CSS_DATA_TEST_012[] = + "{" + " \"classSelectors\": {" + " \"container\": {" + " \"width\": 400," + " \"height\": 400" + " }," + " \"button\": {" + " \"width\": 300," + " \"height\": 80" + " }" + " }," + " \"@media\": [" + " {" + " \"condition\": \"screen and (device-type: smartVision)\"," + " \"classSelectors\": {" + " \"container\": {}," + " \"containerNew\": {" + " \"width\": 400," + " \"height\": 400" + " }" + " }" + " }" + " ]" + "}"; +} // namespace StyleSheetCSSData + +void StyleMgrMediaQueryTddTest::SetUp() +{ + SystemInfo::GetInstance().Initialize(); + Debugger::GetInstance().SetupJSContext(); + jerry_init(JERRY_INIT_EMPTY); +} + +void StyleMgrMediaQueryTddTest::TearDown() +{ + jerry_cleanup(); + Debugger::GetInstance().ReleaseJSContext(); +} + +int StyleMgrMediaQueryTddTest::GetAppStyleCount(const AppStyleList *list) const +{ + if (list == nullptr) { + return 0; + } + + int count = 0; + const AppStyle *style = list->GetFirst(); + while (style != nullptr) { + count++; + style = style->GetNext(); + } + + return count; +} + +int StyleMgrMediaQueryTddTest::CalcAppStyleCount(const AppStyleSheet *list) const +{ + if (list == nullptr) { + return 0; + } + return GetAppStyleCount(list->idSelectors_) + GetAppStyleCount(list->classSelectors_) + + GetAppStyleCount(list->keyFrameSelectors_); +} + +int StyleMgrMediaQueryTddTest::GetAppStyleItemCount(const AppStyle *list) const +{ + if (list == nullptr) { + return 0; + } + + int count = 0; + const AppStyleItem *styleItem = list->GetFirst(); + while (styleItem != nullptr) { + count++; + styleItem = styleItem->GetNext(); + } + + return count; +} + +const AppStyle *StyleMgrMediaQueryTddTest::GetStyleFromSelector(const AppStyleList *styleList, + const char *selectorName) const +{ + if (styleList == nullptr || selectorName == nullptr) { + return nullptr; + } + const AppStyle *style = styleList->GetFirst(); + while (style != nullptr) { + const char *styleName = style->GetStyleName(); + if (styleName != nullptr) { + if (strcmp(styleName, selectorName) == 0) { + return style; + } + } + style = style->GetNext(); + } + return nullptr; +} + +const AppStyle *StyleMgrMediaQueryTddTest::GetStyleFromSelectorList(const AppStyleSheet *list, + const char *selectorName) const +{ + if (list == nullptr || selectorName == nullptr) { + return nullptr; + } + + const AppStyle *selector = GetStyleFromSelector(list->classSelectors_, selectorName); + selector = (selector != nullptr) ? selector : GetStyleFromSelector(list->idSelectors_, selectorName); + selector = (selector != nullptr) ? selector : GetStyleFromSelector(list->keyFrameSelectors_, selectorName); + + return selector; +} + +int StyleMgrMediaQueryTddTest::GetItemCountOfSelector(const AppStyleSheet *list, const char *selectorName) const +{ + if (list == nullptr || selectorName == nullptr) { + return 0; + } + + const AppStyle *selector = GetStyleFromSelectorList(list, selectorName); + return GetAppStyleItemCount(selector); +} + +const AppStyleItem *StyleMgrMediaQueryTddTest::GetStyleItemFromStyle(const AppStyle *style, const char *itemName) const +{ + if (style == nullptr || itemName == nullptr) { + return nullptr; + } + uint16_t targetItemNameKey = KeyParser::ParseKeyId(itemName, strlen(itemName)); + if (targetItemNameKey == K_UNKNOWN) { + return nullptr; + } + const AppStyleItem *styleItem = style->GetFirst(); + while (styleItem != nullptr) { + if (styleItem->GetPropNameId() == targetItemNameKey) { + return styleItem; + } + styleItem = styleItem->GetNext(); + } + return nullptr; +} + +const AppStyleItem *StyleMgrMediaQueryTddTest::GetStyleItemByName(const AppStyleSheet *list, + const char *selectorName, + const char *itemName) const +{ + if (list == nullptr || selectorName == nullptr || itemName == nullptr) { + return nullptr; + } + + const AppStyle *style = GetStyleFromSelectorList(list, selectorName); + if (style == nullptr) { + return nullptr; + } + const AppStyleItem *styleItem = GetStyleItemFromStyle(style, itemName); + return styleItem; +} + +/** + * @tc.name: StyleMgrMediaQueryCSS001 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: SR000GCSKI + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS001, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t styleSheetObj = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_001), + strlen(StyleSheetCSSData::CSS_DATA_TEST_001)); + ScopeJSValue autoReleaseV(styleSheetObj); + AppStyleManager styleManager; + styleManager.InitStyleSheet(styleSheetObj); + const AppStyleSheet *styleSheet = styleManager.GetStyleSheet(); + /** + * @tc.steps: step2. check count + */ + const int targetCount = 2; + int count = CalcAppStyleCount(styleSheet); + EXPECT_EQ(count, targetCount); +} + +/** + * @tc.name: StyleMgrMediaQueryCSS002 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKJ + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS002, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + AppStyleManager styleMgr; + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_002), + strlen(StyleSheetCSSData::CSS_DATA_TEST_002)); + ScopeJSValue autoReleaseValue(styleSheetObject); + /** + * @tc.steps: step2. initialize style sheet list + */ + styleMgr.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = styleMgr.GetStyleSheet(); + /** + * @tc.steps: step3. check count + */ + int targetCount = 3; + int count = CalcAppStyleCount(styleSheet); + EXPECT_EQ(count, targetCount); + /** + * @tc.steps: step4. the matched media query styles should be added + */ + const AppStyle *containerNewSelector = GetStyleFromSelectorList(styleSheet, "containerNew"); + EXPECT_NE(containerNewSelector, nullptr); + + int containerSelectorItemCount = GetItemCountOfSelector(styleSheet, "container"); + targetCount = 5; + EXPECT_EQ(containerSelectorItemCount, targetCount); + + const AppStyleItem *backgroundColorItem = GetStyleItemByName(styleSheet, "container", "backgroundColor"); + EXPECT_NE(backgroundColorItem, nullptr); + if (backgroundColorItem != nullptr) { + int32_t targetValue = 8421504; + int32_t backgroundColorValue = backgroundColorItem->GetNumValue(); + EXPECT_EQ(targetValue, backgroundColorValue); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS003 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKK + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS003, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_003), + strlen(StyleSheetCSSData::CSS_DATA_TEST_003)); + ScopeJSValue scopeJSValue(styleSheetObject); + AppStyleManager styleManagerInstance; + styleManagerInstance.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = styleManagerInstance.GetStyleSheet(); + /** + * @tc.steps: step2. check total cound + */ + const int count = 3; + EXPECT_EQ(CalcAppStyleCount(styleSheet), count); +} + +/** + * @tc.name: StyleMgrMediaQueryCSS004 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKL + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS004, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + AppStyleManager appStyleManagerInner; + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_004), + strlen(StyleSheetCSSData::CSS_DATA_TEST_004)); + ScopeJSValue scopeValue(styleSheetObject); + appStyleManagerInner.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = appStyleManagerInner.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + const AppStyleItem *item = GetStyleItemByName(styleSheet, "container", "backgroundColor"); + EXPECT_NE(item, nullptr); + if (item != nullptr) { + int32_t targetValue = 215026; + int32_t backgroundColorValue = item->GetNumValue(); + EXPECT_EQ(targetValue, backgroundColorValue); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS005 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKM + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS005, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_005), + strlen(StyleSheetCSSData::CSS_DATA_TEST_005)); + ScopeJSValue jsValue(styleSheetObject); // auto release + AppStyleManager styleManagerInstance; + styleManagerInstance.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = styleManagerInstance.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 1; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); + int containerSelectorItemCount = GetItemCountOfSelector(styleSheet, "container"); + targetCount = 3; + EXPECT_EQ(containerSelectorItemCount, targetCount); +} + +/** + * @tc.name: StyleMgrMediaQueryCSS006 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS006, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t cssObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_006), + strlen(StyleSheetCSSData::CSS_DATA_TEST_006)); + ScopeJSValue scopeValue(cssObject); + AppStyleManager appStyleManager; + appStyleManager.InitStyleSheet(cssObject); + const AppStyleSheet *styleSheet = appStyleManager.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 2; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); + int containerItemCount = 5; + EXPECT_EQ(GetItemCountOfSelector(styleSheet, "container"), containerItemCount); + int buttonItemCount = 7; + EXPECT_EQ(GetItemCountOfSelector(styleSheet, "button"), buttonItemCount); +} + +/** + * @tc.name: StyleMgrMediaQueryCSS007 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS007, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t cssDataJSValue = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_007), + strlen(StyleSheetCSSData::CSS_DATA_TEST_007)); + ScopeJSValue autoReleaseValue(cssDataJSValue); + AppStyleManager appStyleManager; + appStyleManager.InitStyleSheet(cssDataJSValue); + const AppStyleSheet *styleSheet = appStyleManager.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 1; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); + int containerItemCount = 3; + EXPECT_EQ(GetItemCountOfSelector(styleSheet, "container"), containerItemCount); + const AppStyleItem *widthStyleItem = GetStyleItemByName(styleSheet, "container", "width"); + EXPECT_NE(widthStyleItem, nullptr); + if (widthStyleItem != nullptr) { + int32_t targetValue = 400; + int32_t widthValue = widthStyleItem->GetNumValue(); + EXPECT_EQ(targetValue, widthValue); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS008 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS008, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + const uint16_t screenSize = 466; + ProductAdapter::SetScreenSize(screenSize, screenSize); + SystemInfo::GetInstance().Initialize(); + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_008), + strlen(StyleSheetCSSData::CSS_DATA_TEST_008)); + ScopeJSValue autoReleaseValue(styleSheetObject); + AppStyleManager appStyleManagerObject; + appStyleManagerObject.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = appStyleManagerObject.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 2; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); + const AppStyleItem *backgroundColorStyleItem = GetStyleItemByName(styleSheet, "container", "backgroundColor"); + EXPECT_NE(backgroundColorStyleItem, nullptr); + if (backgroundColorStyleItem != nullptr) { + int32_t targetValue = 121301; + int32_t backgroundColorValue = backgroundColorStyleItem->GetNumValue(); + EXPECT_EQ(targetValue, backgroundColorValue); + } + const AppStyleItem *borderWidthItem = GetStyleItemByName(styleSheet, "button", "borderTopWidth"); + EXPECT_NE(borderWidthItem, nullptr); + if (borderWidthItem != nullptr) { + int32_t targetValue = 5; + int32_t borderWidthValue = borderWidthItem->GetNumValue(); + EXPECT_EQ(targetValue, borderWidthValue); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS009 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS009, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + const uint16_t screenWidth = 480; + const uint16_t screenHeight = 960; + ProductAdapter::SetScreenSize(screenWidth, screenHeight); + SystemInfo::GetInstance().Initialize(); + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_009), + strlen(StyleSheetCSSData::CSS_DATA_TEST_009)); + ScopeJSValue scopeValue(styleSheetObject); + AppStyleManager styleMgr; + styleMgr.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = styleMgr.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + const AppStyleItem *backgroundColorItem = GetStyleItemByName(styleSheet, "container", "backgroundColor"); + EXPECT_NE(backgroundColorItem, nullptr); + if (backgroundColorItem != nullptr) { + int32_t targetColorValue = 16711680; + int32_t backgroundColorValue = backgroundColorItem->GetNumValue(); + EXPECT_EQ(targetColorValue, backgroundColorValue); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS010 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS010, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t styleListJSValue = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_010), + strlen(StyleSheetCSSData::CSS_DATA_TEST_010)); + ScopeJSValue scopeValue(styleListJSValue); + AppStyleManager appStyleManager; + appStyleManager.InitStyleSheet(styleListJSValue); + const AppStyleSheet *styleSheet = appStyleManager.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + const AppStyleItem *backgroundColorItem = GetStyleItemByName(styleSheet, "container", "backgroundColor"); + EXPECT_NE(backgroundColorItem, nullptr); + if (backgroundColorItem != nullptr) { + int32_t targetColorValue = 123456; + EXPECT_EQ(targetColorValue, backgroundColorItem->GetNumValue()); + } +} + +/** + * @tc.name: StyleMgrMediaQueryCSS011 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS011, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + const uint16_t screenSizeWidth = 960; + const uint16_t screenSizeHeight = 960; + ProductAdapter::SetScreenSize(screenSizeWidth, screenSizeHeight); + AppStyleManager styleMgrInstance; + jerry_value_t styleSheetObject = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_011), + strlen(StyleSheetCSSData::CSS_DATA_TEST_011)); + ScopeJSValue autoReleaseValue(styleSheetObject); + styleMgrInstance.InitStyleSheet(styleSheetObject); + const AppStyleSheet *styleSheet = styleMgrInstance.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 2; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); +} + +/** + * @tc.name: StyleMgrMediaQueryCSS012 + * @tc.desc: Verify the style sheet with media query block initialization + * @tc.require: AR000GCSKN + */ +HWTEST_F(StyleMgrMediaQueryTddTest, StyleMgrMediaQueryCSS012, TestSize.Level0) +{ + /** + * @tc.steps: step1. prepare test resource + */ + jerry_value_t cssData = + jerry_json_parse(reinterpret_cast(StyleSheetCSSData::CSS_DATA_TEST_012), + strlen(StyleSheetCSSData::CSS_DATA_TEST_012)); + ScopeJSValue autoReleaseValue(cssData); + AppStyleManager appStyleManager; + appStyleManager.InitStyleSheet(cssData); + const AppStyleSheet *styleSheet = appStyleManager.GetStyleSheet(); + /** + * @tc.steps: step2. check the result + */ + int targetCount = 3; + EXPECT_EQ(CalcAppStyleCount(styleSheet), targetCount); + int containerItemCount = 2; + EXPECT_EQ(GetItemCountOfSelector(styleSheet, "container"), containerItemCount); +} +} // namespace ACELite +} // namespace OHOS diff --git a/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.h b/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.h new file mode 100644 index 00000000..738d40a3 --- /dev/null +++ b/frameworks/src/core/stylemgr/test/unittest/common/stylemgr_media_query_tdd_test.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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 ACELITE_STYLE_MANAGER_MEDIA_QUERY_TDD_TEST_H +#define ACELITE_STYLE_MANAGER_MEDIA_QUERY_TDD_TEST_H + +#include "acelite_config.h" +#ifdef TDD_ASSERTIONS +#include +#include +#else +#include +#endif +#include "stylemgr/app_style_manager.h" +#include "stylemgr/app_style_sheet.h" + +namespace OHOS { +namespace ACELite { +#ifdef TDD_ASSERTIONS +using namespace std; +using namespace testing::ext; +class StyleMgrMediaQueryTddTest : public testing::Test { +#else +class StyleMgrMediaQueryTddTest { +#endif +public: + StyleMgrMediaQueryTddTest() = default; + ~StyleMgrMediaQueryTddTest() = default; + void SetUp(); + void TearDown(); + + void StyleMgrMediaQueryCSS001(); + void StyleMgrMediaQueryCSS002(); + void StyleMgrMediaQueryCSS003(); + void StyleMgrMediaQueryCSS004(); + void StyleMgrMediaQueryCSS005(); + void StyleMgrMediaQueryCSS006(); + void StyleMgrMediaQueryCSS007(); + void StyleMgrMediaQueryCSS008(); + void StyleMgrMediaQueryCSS009(); + void StyleMgrMediaQueryCSS010(); + void StyleMgrMediaQueryCSS011(); + void StyleMgrMediaQueryCSS012(); + int CalcAppStyleCount(const AppStyleSheet *list) const; + int GetAppStyleCount(const AppStyleList *list) const; + int GetAppStyleItemCount(const AppStyle *list) const; + int GetItemCountOfSelector(const AppStyleSheet *list, const char *selectorName) const; + const AppStyle *GetStyleFromSelectorList(const AppStyleSheet *styleList, const char *selectorName) const; + const AppStyle *GetStyleFromSelector(const AppStyleList *styleList, const char *selectorName) const; + const AppStyleItem * + GetStyleItemByName(const AppStyleSheet *list, const char *selectorName, const char *itemName) const; + const AppStyleItem *GetStyleItemFromStyle(const AppStyle *style, const char *itemName) const; +}; +} // namespace ACELite +} // namespace OHOS +#endif // ACELITE_STYLE_MANAGER_MEDIA_QUERY_TDD_TEST_H diff --git a/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro b/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro index 2facc770..f8f7fbba 100644 --- a/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro +++ b/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro @@ -63,6 +63,7 @@ SOURCES += \ $${ACELITE_CORE_PATH}/base/number_parser.cpp \ $${ACELITE_CORE_PATH}/base/product_adapter.cpp \ $${ACELITE_CORE_PATH}/base/string_util.cpp \ + $${ACELITE_CORE_PATH}/base/system_info.cpp \ $${ACELITE_CORE_PATH}/base/time_util.cpp \ $${ACELITE_CORE_PATH}/components/analog_clock_component.cpp \ $${ACELITE_CORE_PATH}/components/camera_component.cpp \ @@ -140,6 +141,7 @@ SOURCES += \ $${ACELITE_CORE_PATH}/stylemgr/app_style_list.cpp \ $${ACELITE_CORE_PATH}/stylemgr/app_style_manager.cpp \ $${ACELITE_CORE_PATH}/stylemgr/app_style_sheet.cpp \ + $${ACELITE_CORE_PATH}/stylemgr/condition_arbitrator.cpp \ $${ACELITE_CORE_PATH}/wrapper/js.cpp \ $${ACELITE_FRAMEWORK_PATH}/targets/platform_adapter.cpp \ targets/simulator/utils/js_heap_stats_dumper.cpp \ diff --git a/test/BUILD.gn b/test/BUILD.gn index dbed2855..44efbce5 100755 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -27,6 +27,7 @@ modules_unittest_root = stylemgr_unittest_root = "$ace_lite_root/frameworks/src/core/stylemgr/test/unittest" router_unittest_root = "$ace_lite_root/frameworks/src/core/router/test/unittest" +base_unittest_root = "$ace_lite_root/frameworks/src/core/base/test/unittest" # common config for all test, append extra in self gn config("test_common_config") { @@ -46,6 +47,7 @@ group("unittest") { deps = [ "$ace_lite_root/test/moduletest/common:door_unittest", "$async_unittest_root:async_unittest", + "$base_unittest_root:base_utils_unittest", "$cache_manager_unittest_root:cache_manager_unittest", "$components_unittest_root:components_unittest", "$context_unittest_root:js_frameworks_unittest", -- Gitee