diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..2ab7ff6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,106 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: None +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +BreakAfterJavaFieldAnnotations: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^"(base|core|elements|rendering|adapter|dsl|frameworks|resource|accessibility|bridge)/' + Priority: 3 + - Regex: '<*>' + Priority: 1 + - Regex: '.*' + Priority: 2 +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 39 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 80 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000..95e6cdc --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +group("ui_appearance_packages") { + deps = [ + "etc/para:ui_appearance.para", + "etc/para:ui_appearance.para.dac", + "sa_profile:arkui_ui_appearance_sa_profiles", + "interfaces/kits/napi:uiappearance", + "services:ui_appearance_service", + ] +} + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4947287 --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/OAT.xml b/OAT.xml new file mode 100644 index 0000000..27154b0 --- /dev/null +++ b/OAT.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 5de2863..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# arkui_ui_appearance - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 6449b7e..0000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# arkui_ui_appearance - -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000..ea762ba --- /dev/null +++ b/README_zh.md @@ -0,0 +1,57 @@ +# 用户界面外观 + + +## 简介 + +**内容介绍**:用户界面外观目前仅支持深色模式服务,提供了系统应用API,用于获取和设置系统的深浅色模式,同时可持久化保存当前配置的深浅色模式。 + +**架构图**: + +![](figures/uiAppearance-architecture_zh.png) + + +## 目录 + +深色模式服务源代码在/foundation/arkui/ui\_appearance下,目录结构如下图所示: + +``` +/foundation/arkui/ui_appearance +├── etc +│ └── para # 持久化配置文件存放目录 +│── interfaces/kits +│ └── napi # napi外部接口存放目录 +│── sa_profile # 深色模式系统服务的配置文件 +│── services # 深色模式系统服务实现 +├── test # 接口单元测试 +``` + + +## 使用场景 + +仅支持具有权限的系统应用通过API接口控制和切换当前用户界面的外观模式。 + + +## 说明 + +### 接口说明 + +| 接口名 | 描述 | +| -------- | -------- | +| setDarkMode(mode: DarkMode, callback: AsyncCallback\): void | 设置用户界面模式(深色或浅色),Callback方式。 | +| setDarkMode(mode: DarkMode): Promise\ | 设置用户界面模式(深色或浅色),Promise方式。 | +| getDarkMode(): DarkMode | 获取当前用户界面的模式(深色或浅色)。 | + +### 使用说明 + +功能模块开发指导可参考[**开发指南**](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-uiappearance.md) + + +## 相关仓 + +[ArkUI框架子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/ArkUI%E6%A1%86%E6%9E%B6%E5%AD%90%E7%B3%BB%E7%BB%9F.md) + +[arkui\_napi](https://gitee.com/openharmony/arkui_napi) + +[arkui\_ace\_engine](https://gitee.com/openharmony/arkui_ace_engine/blob/master/README_zh.md) + +**arkui\_ui\_appearance** \ No newline at end of file diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000..c71b9a7 --- /dev/null +++ b/bundle.json @@ -0,0 +1,50 @@ +{ + "name": "@ohos/ui_appearance", + "description": "Provide ui_appearance management.", + "version": "3.2", + "license": "Apache License 2.0", + "publishAs": "code-segment", + "segment": { + "destpath": "foundation/arkui/ui_appearance" + }, + "dirs": {}, + "scripts": {}, + "component": { + "name": "ui_appearance", + "subsystem": "arkui", + "syscap": [ + "SystemCapability.ArkUI.UiAppearance" + ], + "features": [ + ], + "adapted_system_type": [ + "standard" + ], + "rom":"300KB", + "ram":"1024KB", + "deps": { + "components": [ + "ipc", + "hiviewdfx_hilog_native", + "appexecfwk_standard", + "aafwk_standard", + "safwk", + "ability_runtime", + "ability_base", + "bundle_framework", + "samgr" + ], + "third_party": [] + }, + "build": { + "sub_component": [ + "//foundation/arkui/ui_appearance:ui_appearance_packages" + ], + "inner_kits": [ + ], + "test": [ + "//foundation/arkui/ui_appearance/test/unittest:ui_appearance_test" + ] + } + } +} \ No newline at end of file diff --git a/etc/para/BUILD.gn b/etc/para/BUILD.gn new file mode 100644 index 0000000..aa1a972 --- /dev/null +++ b/etc/para/BUILD.gn @@ -0,0 +1,29 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import("//build/ohos.gni") + +ohos_prebuilt_etc("ui_appearance.para") { + source = "ui_appearance.para" + subsystem_name = "arkui" + part_name = "ui_appearance" + module_install_dir = "etc/param" +} + +ohos_prebuilt_etc("ui_appearance.para.dac") { + source = "ui_appearance.para.dac" + subsystem_name = "arkui" + part_name = "ui_appearance" + module_install_dir = "etc/param" +} diff --git a/etc/para/ui_appearance.para b/etc/para/ui_appearance.para new file mode 100644 index 0000000..937d083 --- /dev/null +++ b/etc/para/ui_appearance.para @@ -0,0 +1,14 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +persist.darkmode=light diff --git a/etc/para/ui_appearance.para.dac b/etc/para/ui_appearance.para.dac new file mode 100644 index 0000000..8581137 --- /dev/null +++ b/etc/para/ui_appearance.para.dac @@ -0,0 +1,15 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +persist.darkmode = uiserver:uiserver:0600 + diff --git a/figures/uiAppearance-architecture_zh.png b/figures/uiAppearance-architecture_zh.png new file mode 100644 index 0000000..f97fbb1 Binary files /dev/null and b/figures/uiAppearance-architecture_zh.png differ diff --git a/interfaces/kits/napi/BUILD.gn b/interfaces/kits/napi/BUILD.gn new file mode 100644 index 0000000..c89294e --- /dev/null +++ b/interfaces/kits/napi/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("ui_appearance_interfaces_kits_napi_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("uiappearance") { + include_dirs = [ "include" ] + public_configs = [ ":ui_appearance_interfaces_kits_napi_config" ] + sources = [ "src/js_ui_appearance.cpp" ] + + deps = [ "../../../services:ui_appearance_client" ] + external_deps = [ + "napi:ace_napi", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + + relative_install_dir = "module" + subsystem_name = "arkui" + part_name = "ui_appearance" +} \ No newline at end of file diff --git a/interfaces/kits/napi/include/js_ui_appearance.h b/interfaces/kits/napi/include/js_ui_appearance.h new file mode 100644 index 0000000..b7753d8 --- /dev/null +++ b/interfaces/kits/napi/include/js_ui_appearance.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JS_UI_APPEARANCE_H +#define JS_UI_APPEARANCE_H + +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "ui_appearance_ability_client.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +struct AsyncContext { + napi_env env = nullptr; + napi_async_work work = nullptr; + napi_deferred deferred = nullptr; + napi_ref callbackRef = nullptr; + int32_t jsSetArg = -1; + int32_t status = 0; + bool isArgsValid = true; + UiAppearanceAbilityInterface::DarkMode mode; +}; + +class JsDarkMode final { +public: + enum EnumNapiResults { ERROR = 0, COMMON, BUTT }; + + static void OnExecute(napi_env env, void* data); + static void OnComplete(napi_env env, napi_status status, void* data); + static napi_status CheckArgs(napi_env env, size_t argc, napi_value* argv); + static UiAppearanceAbilityInterface::DarkMode ConvertJsDarkMode2Enum(int32_t jsVal); +}; + +napi_value JSSetDarkModeSync(napi_env env, napi_callback_info info); +napi_value JSGetDarkModeSync(napi_env env, napi_callback_info info); +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // JS_UI_APPEARANCE_H \ No newline at end of file diff --git a/interfaces/kits/napi/src/js_ui_appearance.cpp b/interfaces/kits/napi/src/js_ui_appearance.cpp new file mode 100644 index 0000000..8a8936b --- /dev/null +++ b/interfaces/kits/napi/src/js_ui_appearance.cpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_ui_appearance.h" + +#include "ui_appearance_log.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +void JsDarkMode::OnExecute(napi_env env, void* data) +{ + JS_HILOG_INFO("OnExecute begin."); + AsyncContext* asyncContext = static_cast(data); + if (asyncContext->isArgsValid) { + auto res = UiAppearanceAbilityClient::GetInstance()->SetDarkMode(asyncContext->mode); + asyncContext->status = res; + } +} + +void JsDarkMode::OnComplete(napi_env env, napi_status status, void* data) +{ + JS_HILOG_INFO("OnComplete begin."); + AsyncContext* asyncContext = static_cast(data); + napi_value result[EnumNapiResults::BUTT] = { 0 }; + + // set result + if (asyncContext->isArgsValid && asyncContext->status == UiAppearanceAbilityInterface::ErrCode::SUCCEEDED) { + napi_get_undefined(env, &result[EnumNapiResults::ERROR]); + napi_get_undefined(env, &result[EnumNapiResults::COMMON]); + } else { + std::string err; + napi_value message = nullptr; + if (!asyncContext->isArgsValid || asyncContext->status == UiAppearanceAbilityInterface::ErrCode::INVALID_ARG) { + err.assign("invalid argument."); + } else if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) { + err.assign("permission verification failed."); + } else { + err.assign("system error."); + } + napi_create_string_utf8(env, err.c_str(), NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result[EnumNapiResults::ERROR]); + napi_get_undefined(env, &result[EnumNapiResults::COMMON]); + } + + if (asyncContext->deferred) { // promise + if (asyncContext->isArgsValid && asyncContext->status == UiAppearanceAbilityInterface::ErrCode::SUCCEEDED) { + napi_resolve_deferred(env, asyncContext->deferred, result[EnumNapiResults::COMMON]); + } else { + napi_reject_deferred(env, asyncContext->deferred, result[EnumNapiResults::ERROR]); + } + } else { // AsyncCallback + JS_HILOG_INFO("napi call function start."); + napi_value callback = nullptr; + napi_value returnValue = nullptr; + auto errCode = + (asyncContext->isArgsValid) ? asyncContext->status : UiAppearanceAbilityInterface::ErrCode::INVALID_ARG; + napi_create_int32(env, errCode, result); + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_call_function(env, nullptr, callback, EnumNapiResults::BUTT, result, &returnValue); + napi_delete_reference(env, asyncContext->callbackRef); + } + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; +} + +napi_status JsDarkMode::CheckArgs(napi_env env, size_t argc, napi_value* argv) +{ + if (argc < 1 || argc > 2) { // 1 and 2 is the number of arguments + return napi_invalid_arg; + } + + napi_valuetype valueType = napi_undefined; + switch (argc) { + case 2: // 2 is the number of arguments + napi_typeof(env, argv[1], &valueType); + if (valueType != napi_function) { + return napi_invalid_arg; + } + [[fallthrough]]; + case 1: + napi_typeof(env, argv[0], &valueType); + if (valueType != napi_number) { + return napi_invalid_arg; + } + break; + default: + return napi_invalid_arg; + } + return napi_ok; +} + +UiAppearanceAbilityInterface::DarkMode JsDarkMode::ConvertJsDarkMode2Enum(int32_t jsVal) +{ + switch (jsVal) { + case 0: + return UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK; + case 1: + return UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT; + default: + return UiAppearanceAbilityInterface::DarkMode::UNKNOWN; + } +} + +static napi_value JSSetDarkMode(napi_env env, napi_callback_info info) +{ + JS_HILOG_INFO("JSSetDarkMode begin."); + + size_t argc = 2; + napi_value argv[2] = { 0 }; + napi_status napiStatus = napi_ok; + do { + napiStatus = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (napiStatus != napi_ok) { + JS_HILOG_ERROR("get callback info failed."); + break; + } + napiStatus = JsDarkMode::CheckArgs(env, argc, argv); + if (napiStatus != napi_ok) { + JS_HILOG_ERROR("invalid argument."); + break; + } + } while (0); + + auto asyncContext = new (std::nothrow) AsyncContext(); + if (asyncContext == nullptr) { + JS_HILOG_ERROR("new AsyncContext failed."); + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; + } + + asyncContext->isArgsValid = (napiStatus == napi_ok); + if (asyncContext->isArgsValid) { + napi_get_value_int32(env, argv[0], &asyncContext->jsSetArg); + asyncContext->mode = JsDarkMode::ConvertJsDarkMode2Enum(asyncContext->jsSetArg); + } + if (argc == 2) { // 2: the number of arguments + napi_create_reference(env, argv[1], 1, &asyncContext->callbackRef); + } + + napi_value result = nullptr; + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "JSSetDarkMode", NAPI_AUTO_LENGTH, &resource); + napi_create_async_work(env, nullptr, resource, JsDarkMode::OnExecute, JsDarkMode::OnComplete, + reinterpret_cast(asyncContext), &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + + return result; +} + +static napi_value JSGetDarkMode(napi_env env, napi_callback_info info) +{ + JS_HILOG_INFO("JSGetDarkMode begin."); + + size_t argc = 0; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr)); + NAPI_ASSERT(env, argc == 0, "requires no parameter"); + + UiAppearanceAbilityInterface::DarkMode mode = UiAppearanceAbilityClient::GetInstance()->GetDarkMode(); + napi_value result; + NAPI_CALL(env, napi_create_int32(env, mode, &result)); + return result; +} + +EXTERN_C_START +static napi_value UiAppearanceExports(napi_env env, napi_value exports) +{ + napi_value DarkMode = nullptr; + napi_value alwaysDark = nullptr; + napi_value alwaysLight = nullptr; + NAPI_CALL(env, napi_create_int32(env, 0, &alwaysDark)); + NAPI_CALL(env, napi_create_int32(env, 1, &alwaysLight)); + NAPI_CALL(env, napi_create_object(env, &DarkMode)); + NAPI_CALL(env, napi_set_named_property(env, DarkMode, "ALWAYS_DARK", alwaysDark)); + NAPI_CALL(env, napi_set_named_property(env, DarkMode, "ALWAYS_LIGHT", alwaysLight)); + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("setDarkMode", JSSetDarkMode), + DECLARE_NAPI_FUNCTION("getDarkMode", JSGetDarkMode), + DECLARE_NAPI_STATIC_PROPERTY("DarkMode", DarkMode), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties)); + return exports; +} +EXTERN_C_END + +static napi_module ui_appearance_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = UiAppearanceExports, + .nm_modname = "uiAppearance", // relative to the module name while import. + .nm_priv = nullptr, + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void UiAppearanceRegister() +{ + napi_module_register(&ui_appearance_module); +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS diff --git a/sa_profile/7002.xml b/sa_profile/7002.xml new file mode 100644 index 0000000..a6f2ba2 --- /dev/null +++ b/sa_profile/7002.xml @@ -0,0 +1,26 @@ + + + + ui_service + + 7002 + libui_appearance_service.z.so + true + false + 1 + + + diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 0000000..0890f58 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/sa_profile/sa_profile.gni") + +ohos_sa_profile("arkui_ui_appearance_sa_profiles") { + sources = [ "7002.xml" ] + part_name = "ui_appearance" +} diff --git a/services/BUILD.gn b/services/BUILD.gn new file mode 100644 index 0000000..d6a8cc2 --- /dev/null +++ b/services/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (C) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") + +config("ui_appearance_service_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_shared_library("ui_appearance_service") { + sources = [ + "src/ui_appearance_ability.cpp", + "src/ui_appearance_ability_stub.cpp", + ] + + public_configs = [ ":ui_appearance_service_config" ] + include_dirs = [ "include/" ] + deps = [] + external_deps = [ + "ability_base:configuration", + "ability_runtime:app_manager", + "access_token:libaccesstoken_sdk", + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + "init:libbegetutil", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + subsystem_name = "arkui" + part_name = "ui_appearance" +} + +ohos_shared_library("ui_appearance_client") { + sources = [ + "src/ui_appearance_ability_client.cpp", + "src/ui_appearance_ability_proxy.cpp", + ] + + public_configs = [ ":ui_appearance_service_config" ] + include_dirs = [ "include/" ] + deps = [] + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_single", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + subsystem_name = "arkui" + part_name = "ui_appearance" +} diff --git a/services/include/ui_appearance_ability.h b/services/include/ui_appearance_ability.h new file mode 100644 index 0000000..f72fc4f --- /dev/null +++ b/services/include/ui_appearance_ability.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_APPEARANCE_ABILITY_H +#define UI_APPEARANCE_ABILITY_H + +#include "system_ability.h" +#include "appmgr/app_mgr_proxy.h" +#include "ui_appearance_ability_stub.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceAbility : public SystemAbility, public UiAppearanceAbilityStub { + DECLARE_SYSTEM_ABILITY(UiAppearanceAbility); + +public: + UiAppearanceAbility(int32_t saId, bool runOnCreate); + ~UiAppearanceAbility() = default; + + int32_t SetDarkMode(DarkMode mode) override; + DarkMode GetDarkMode() override; + +protected: + void OnStart() override; + void OnStop() override; + + void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; + void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; + +private: + sptr GetAppManagerInstance(); + bool VerifyAccessToken(const std::string& permissionName); + int32_t OnSetDarkMode(DarkMode mode); + DarkMode OnGetDarkMode(); + + DarkMode darkMode_ = DarkMode::ALWAYS_LIGHT; +}; +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // UI_APPEARANCE_ABILITY_H \ No newline at end of file diff --git a/services/include/ui_appearance_ability_client.h b/services/include/ui_appearance_ability_client.h new file mode 100644 index 0000000..fab3aa5 --- /dev/null +++ b/services/include/ui_appearance_ability_client.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_APPEARANCE_ABILITY_CLIENT_H +#define UI_APPEARANCE_ABILITY_CLIENT_H + +#include "iremote_object.h" +#include "refbase.h" +#include "ui_appearance_ability_interface.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceDeathRecipient : public IRemoteObject::DeathRecipient { +public: + explicit UiAppearanceDeathRecipient() = default; + ~UiAppearanceDeathRecipient() = default; + void OnRemoteDied(const wptr& object) override; +}; + +class UiAppearanceAbilityClient : public RefBase { +public: + UiAppearanceAbilityClient() = default; + ~UiAppearanceAbilityClient() = default; + static sptr GetInstance(); + + int32_t SetDarkMode(UiAppearanceAbilityInterface::DarkMode mode); + UiAppearanceAbilityInterface::DarkMode GetDarkMode(); + void OnRemoteSaDied(const wptr& object); + +private: + sptr GetUiAppearanceServiceProxy(); + static sptr CreateUiAppearanceServiceProxy(); + + static inline std::mutex instanceLock_; + static inline sptr instance_; + static inline sptr uiAppearanceServiceProxy_; + static inline sptr deathRecipient_; +}; +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // UI_APPEARANCE_ABILITY_CLIENT_H \ No newline at end of file diff --git a/services/include/ui_appearance_ability_interface.h b/services/include/ui_appearance_ability_interface.h new file mode 100644 index 0000000..fe4c1bb --- /dev/null +++ b/services/include/ui_appearance_ability_interface.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_APPEARANCE_ABILITY_INTERFACE_H +#define UI_APPEARANCE_ABILITY_INTERFACE_H + +#include + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceAbilityInterface : public IRemoteBroker { +public: + enum DarkMode { + ALWAYS_DARK = 0, + ALWAYS_LIGHT = 1, + UNKNOWN = 2, + }; + + enum IpcCode { + SET_DARK_MODE = 1, + GET_DARK_MODE = 2, + }; + + enum ErrCode { + SUCCEEDED = 0, + PERMISSION_ERR = 201, + INVALID_ARG = 401, + SYS_ERR = 1, + }; + + virtual int32_t SetDarkMode(DarkMode mode) = 0; + virtual DarkMode GetDarkMode() = 0; + +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.UiAppearance.UiAppearanceAbilityInterface"); +}; +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // UI_APPEARANCE_ABILITY_INTERFACE_H \ No newline at end of file diff --git a/services/include/ui_appearance_ability_proxy.h b/services/include/ui_appearance_ability_proxy.h new file mode 100644 index 0000000..e5e82c0 --- /dev/null +++ b/services/include/ui_appearance_ability_proxy.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef UI_APPEARANCE_ABILITY_PROXY_H +#define UI_APPEARANCE_ABILITY_PROXY_H + +#include "iremote_proxy.h" +#include "ui_appearance_ability_interface.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceAbilityProxy : public IRemoteProxy { +public: + int32_t SetDarkMode(DarkMode mode) override; + DarkMode GetDarkMode() override; + + explicit UiAppearanceAbilityProxy(const sptr& impl) + : IRemoteProxy(impl) + {} + ~UiAppearanceAbilityProxy() = default; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // UI_APPEARANCE_ABILITY_PROXY_H \ No newline at end of file diff --git a/services/include/ui_appearance_ability_stub.h b/services/include/ui_appearance_ability_stub.h new file mode 100644 index 0000000..ee61c87 --- /dev/null +++ b/services/include/ui_appearance_ability_stub.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_APPEARANCE_ABILITY_STUB_H +#define UI_APPEARANCE_ABILITY_STUB_H + +#include "iremote_stub.h" +#include "ui_appearance_ability_interface.h" +#include "message_parcel.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceAbilityStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; +}; +} // namespace ArkUi::UiAppearance +} // namespace OHOS +#endif // UI_APPEARANCE_ABILITY_STUB_H \ No newline at end of file diff --git a/services/include/ui_appearance_log.h b/services/include/ui_appearance_log.h new file mode 100644 index 0000000..78d79af --- /dev/null +++ b/services/include/ui_appearance_log.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UI_APPEARANCE_LOG_H +#define UI_APPEARANCE_LOG_H + +#define CONFIG_HILOG +#ifdef CONFIG_HILOG +#include "hilog/log.h" + +#ifdef HILOG_FATAL +#undef HILOG_FATAL +#endif + +#ifdef HILOG_ERROR +#undef HILOG_ERROR +#endif + +#ifdef HILOG_WARN +#undef HILOG_WARN +#endif + +#ifdef HILOG_INFO +#undef HILOG_INFO +#endif + +#ifdef HILOG_DEBUG +#undef HILOG_DEBUG +#endif + +#ifdef LOG_LABEL +#undef LOG_LABEL +#endif + +static constexpr unsigned int FRAMEWORK_DOMAIN = 0xD003900; +static constexpr unsigned int JS_DOMAIN = 0xD003B00; +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL_FW = { LOG_CORE, FRAMEWORK_DOMAIN, "UiAppearance" }; +static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL_JS = { LOG_CORE, JS_DOMAIN, "JSApp" }; + +#define UIFILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define HILOG_FATAL(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Fatal( \ + LOG_LABEL_FW, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define HILOG_ERROR(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Error( \ + LOG_LABEL_FW, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define HILOG_WARN(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Warn( \ + LOG_LABEL_FW, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define HILOG_INFO(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Info( \ + LOG_LABEL_FW, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define HILOG_DEBUG(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Debug( \ + LOG_LABEL_FW, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define JS_HILOG_FATAL(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Fatal( \ + LOG_LABEL_JS, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define JS_HILOG_ERROR(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Error( \ + LOG_LABEL_JS, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define JS_HILOG_WARN(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Warn( \ + LOG_LABEL_JS, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define JS_HILOG_INFO(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Info( \ + LOG_LABEL_JS, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define JS_HILOG_DEBUG(fmt, ...) \ + (void)OHOS::HiviewDFX::HiLog::Debug( \ + LOG_LABEL_JS, "[%{public}s(%{public}s:%{public}d)]" fmt, UIFILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#else + +#define HILOG_FATAL(...) +#define HILOG_ERROR(...) +#define HILOG_WARN(...) +#define HILOG_INFO(...) +#define HILOG_DEBUG(...) + +#define JS_HILOG_FATAL(...) +#define JS_HILOG_ERROR(...) +#define JS_HILOG_WARN(...) +#define JS_HILOG_INFO(...) +#define JS_HILOG_DEBUG(...) + +#endif // CONFIG_HILOG + +#endif // UI_APPEARANCE_LOG_H \ No newline at end of file diff --git a/services/src/ui_appearance_ability.cpp b/services/src/ui_appearance_ability.cpp new file mode 100644 index 0000000..bd0f80b --- /dev/null +++ b/services/src/ui_appearance_ability.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_appearance_ability.h" + +#include + +#include "accesstoken_kit.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "syspara/parameter.h" +#include "system_ability_definition.h" +#include "ui_appearance_log.h" + +namespace { +static const std::string LIGHT = "light"; +static const std::string DARK = "dark"; +static const std::string PERSIST_DARKMODE_KEY = "persist.darkmode"; +static const std::string PERMISSION_UPDATE_CONFIGURATION = "ohos.permission.UPDATE_CONFIGURATION"; +} // namespace + +namespace OHOS { +namespace ArkUi::UiAppearance { +REGISTER_SYSTEM_ABILITY_BY_ID(UiAppearanceAbility, ARKUI_UI_APPEARANCE_SERVICE_ID, true); + +UiAppearanceAbility::UiAppearanceAbility(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) {} + +sptr UiAppearanceAbility::GetAppManagerInstance() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + HILOG_ERROR("Getting systemAbilityManager failed."); + return nullptr; + } + + sptr appObject = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID); + if (appObject == nullptr) { + HILOG_ERROR("Get systemAbility failed."); + return nullptr; + } + + sptr systemAbility = iface_cast(appObject); + if (systemAbility == nullptr) { + HILOG_ERROR("Get AppMgrProxy from SA failed."); + return nullptr; + } + return systemAbility; +} + +bool UiAppearanceAbility::VerifyAccessToken(const std::string& permissionName) +{ + auto callerToken = IPCSkeleton::GetCallingTokenID(); + int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName); + if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) { + HILOG_ERROR("permission %{private}s: PERMISSION_DENIED", permissionName.c_str()); + return false; + } + return true; +} + +int32_t UiAppearanceAbility::OnSetDarkMode(DarkMode mode) +{ + HILOG_INFO("OnSetDarkMode start."); + bool ret = false; + std::string paramValue; + AppExecFwk::Configuration config; + switch (mode) { + case ALWAYS_LIGHT: { + ret = config.AddItem( + AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT); + paramValue.assign(LIGHT); + break; + } + case ALWAYS_DARK: { + ret = config.AddItem( + AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE, AppExecFwk::ConfigurationInner::COLOR_MODE_DARK); + paramValue.assign(DARK); + break; + } + default: + break; + } + if (!ret) { + HILOG_ERROR("AddItem failed, mode = %{public}d", mode); + return INVALID_ARG; + } + + auto appManagerInstance = GetAppManagerInstance(); + if (appManagerInstance == nullptr) { + HILOG_ERROR("Get app manager proxy failed."); + return SYS_ERR; + } + auto errcode = appManagerInstance->UpdateConfiguration(config); + if (errcode != 0) { + HILOG_ERROR("update configuration failed."); + return SYS_ERR; + } + darkMode_ = mode; + + HILOG_INFO("set parameter begin, persist param = %{public}s.", paramValue.c_str()); + // persist to file: etc/para/ui_appearance.para + auto isSetPara = SetParameter(PERSIST_DARKMODE_KEY.c_str(), paramValue.c_str()); + if (isSetPara < 0) { + HILOG_ERROR("set parameter failed"); + return SYS_ERR; + } + return SUCCEEDED; +} + +int32_t UiAppearanceAbility::SetDarkMode(DarkMode mode) +{ + // Verify permissions + auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); + if (!isCallingPerm) { + HILOG_ERROR("permission verification failed"); + return PERMISSION_ERR; + } + if (mode != darkMode_) { + return OnSetDarkMode(mode); + } + return SUCCEEDED; +} + +UiAppearanceAbilityInterface::DarkMode UiAppearanceAbility::OnGetDarkMode() +{ + HILOG_INFO("OnGetDarkMode start."); + constexpr int buffSize = 64; // buff len: 64 + char valueGet[buffSize] = { 0 }; + + // LIGHT is the default. + auto res = GetParameter(PERSIST_DARKMODE_KEY.c_str(), LIGHT.c_str(), valueGet, buffSize); + if (res <= 0) { + HILOG_ERROR("get parameter failed."); + return UNKNOWN; + } + if (strcmp(valueGet, DARK.c_str()) == 0) { + return ALWAYS_DARK; + } else if (strcmp(valueGet, LIGHT.c_str()) == 0) { + return ALWAYS_LIGHT; + } + return UNKNOWN; +} + +UiAppearanceAbilityInterface::DarkMode UiAppearanceAbility::GetDarkMode() +{ + auto isCallingPerm = VerifyAccessToken(PERMISSION_UPDATE_CONFIGURATION); + if (!isCallingPerm) { + HILOG_ERROR("permission verification failed"); + return UNKNOWN; + } + return darkMode_; +} + +void UiAppearanceAbility::OnStart() +{ + HILOG_INFO("publish start."); + + bool res = Publish(this); // SA registers with SAMGR + if (!res) { + HILOG_ERROR("publish failed."); + return; + } + + HILOG_INFO("AddSystemAbilityListener start."); + AddSystemAbilityListener(APP_MGR_SERVICE_ID); + return; +} + +void UiAppearanceAbility::OnStop() +{ + HILOG_INFO("UiAppearanceAbility SA stop."); +} + +void UiAppearanceAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) +{ + HILOG_INFO("systemAbilityId = %{public}d added.", systemAbilityId); + if (systemAbilityId == APP_MGR_SERVICE_ID) { + darkMode_ = OnGetDarkMode(); + if (darkMode_ == UiAppearanceAbilityInterface::DarkMode::UNKNOWN) { + HILOG_ERROR("get darkmode init error."); + darkMode_ = UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT; + } + auto res = OnSetDarkMode(darkMode_); + if (res < 0) { + HILOG_ERROR("set darkmode init error."); + } + } +} + +void UiAppearanceAbility::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) +{ + HILOG_INFO("systemAbilityId = %{public}d removed.", systemAbilityId); +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS \ No newline at end of file diff --git a/services/src/ui_appearance_ability_client.cpp b/services/src/ui_appearance_ability_client.cpp new file mode 100644 index 0000000..b3698a1 --- /dev/null +++ b/services/src/ui_appearance_ability_client.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_appearance_ability_client.h" + +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "ui_appearance_ability_proxy.h" +#include "ui_appearance_log.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +sptr UiAppearanceAbilityClient::GetInstance() +{ + if (!instance_) { + std::lock_guard autoLock(instanceLock_); + if (!instance_) { + instance_ = new UiAppearanceAbilityClient; + uiAppearanceServiceProxy_ = CreateUiAppearanceServiceProxy(); + } + } + return instance_; +} + +sptr UiAppearanceAbilityClient::GetUiAppearanceServiceProxy() +{ + if (uiAppearanceServiceProxy_ == nullptr) { + HILOG_ERROR("Redo CreateUiAppearanceServiceProxy"); + uiAppearanceServiceProxy_ = CreateUiAppearanceServiceProxy(); + } + return uiAppearanceServiceProxy_; +} + +int32_t UiAppearanceAbilityClient::SetDarkMode(UiAppearanceAbilityInterface::DarkMode mode) +{ + if (!GetUiAppearanceServiceProxy()) { + HILOG_ERROR("SetDarkMode quit because redoing CreateUiAppearanceServiceProxy failed."); + return UiAppearanceAbilityInterface::ErrCode::SYS_ERR; + } + return uiAppearanceServiceProxy_->SetDarkMode(mode); +} + +UiAppearanceAbilityInterface::DarkMode UiAppearanceAbilityClient::GetDarkMode() +{ + if (!GetUiAppearanceServiceProxy()) { + HILOG_ERROR("GetDarkMode quit because redoing CreateUiAppearanceServiceProxy failed."); + return UiAppearanceAbilityInterface::DarkMode::UNKNOWN; + } + return uiAppearanceServiceProxy_->GetDarkMode(); +} + +sptr UiAppearanceAbilityClient::CreateUiAppearanceServiceProxy() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + HILOG_ERROR("Get SystemAbilityManager failed."); + return nullptr; + } + + sptr systemAbility = systemAbilityManager->GetSystemAbility(ARKUI_UI_APPEARANCE_SERVICE_ID); + if (systemAbility == nullptr) { + HILOG_ERROR("Get SystemAbility failed."); + return nullptr; + } + + deathRecipient_ = new UiAppearanceDeathRecipient; + systemAbility->AddDeathRecipient(deathRecipient_); + sptr uiAppearanceServiceProxy = + iface_cast(systemAbility); + if (uiAppearanceServiceProxy == nullptr) { + HILOG_ERROR("Get uiAppearanceServiceProxy from SA failed."); + return nullptr; + } + HILOG_INFO("Get uiAppearanceServiceProxy successful."); + return uiAppearanceServiceProxy; +} + +void UiAppearanceAbilityClient::OnRemoteSaDied(const wptr& remote) +{ + // Used for new connections after the service may be disconnected. + uiAppearanceServiceProxy_ = CreateUiAppearanceServiceProxy(); +} + +void UiAppearanceDeathRecipient::OnRemoteDied(const wptr& object) +{ + HILOG_INFO("UiAppearanceDeathRecipient on remote systemAbility died."); + UiAppearanceAbilityClient::GetInstance()->OnRemoteSaDied(object); +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS diff --git a/services/src/ui_appearance_ability_proxy.cpp b/services/src/ui_appearance_ability_proxy.cpp new file mode 100644 index 0000000..798e235 --- /dev/null +++ b/services/src/ui_appearance_ability_proxy.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_appearance_ability_proxy.h" + +#include + +#include "message_parcel.h" +#include "ui_appearance_log.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +int32_t UiAppearanceAbilityProxy::SetDarkMode(UiAppearanceAbilityInterface::DarkMode mode) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOG_ERROR("Write descriptor failed!"); + return SYS_ERR; + } + if (!data.WriteInt32(mode)) { + HILOG_ERROR("Write mode failed!"); + return SYS_ERR; + } + + auto res = Remote()->SendRequest(SET_DARK_MODE, data, reply, option); + if (res != ERR_NONE) { + HILOG_ERROR("SendRequest failed."); + return SYS_ERR; + } + + return reply.ReadInt32(); +} + +UiAppearanceAbilityInterface::DarkMode UiAppearanceAbilityProxy::GetDarkMode() +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOG_ERROR("Write descriptor failed!"); + return UNKNOWN; + } + + auto res = Remote()->SendRequest(GET_DARK_MODE, data, reply, option); + if (res != ERR_NONE) { + HILOG_ERROR("SendRequest failed."); + return UNKNOWN; + } + + return static_cast(reply.ReadInt32()); +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS \ No newline at end of file diff --git a/services/src/ui_appearance_ability_stub.cpp b/services/src/ui_appearance_ability_stub.cpp new file mode 100644 index 0000000..9ec0d78 --- /dev/null +++ b/services/src/ui_appearance_ability_stub.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ui_appearance_ability_stub.h" + +#include "ui_appearance_log.h" + +namespace OHOS { +namespace ArkUi::UiAppearance { +int32_t UiAppearanceAbilityStub::OnRemoteRequest( + uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + bool ret = false; + std::u16string interfaceToken = data.ReadInterfaceToken(); + if (interfaceToken != GetDescriptor()) { + HILOG_ERROR("error permission denied."); + return -1; + } + switch (code) { + case SET_DARK_MODE: { + UiAppearanceAbilityInterface::DarkMode mode = + static_cast(data.ReadInt32()); + ret = reply.WriteInt32(SetDarkMode(mode)); + return (ret ? 0 : -1); + } + case GET_DARK_MODE: { + ret = reply.WriteInt32(GetDarkMode()); + return (ret ? 0 : -1); + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS \ No newline at end of file diff --git a/test/mock/include/accesstoken_kit.h b/test/mock/include/accesstoken_kit.h new file mode 100644 index 0000000..3f9d534 --- /dev/null +++ b/test/mock/include/accesstoken_kit.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FOUNDATION_ARKUI_UI_APPEARANCE_TEST_MOCK_ACCESSTOKEN_KIT +#define FOUNDATION_ARKUI_UI_APPEARANCE_TEST_MOCK_ACCESSTOKEN_KIT + +#include + +namespace OHOS { +namespace Security::AccessToken { +typedef unsigned int AccessTokenID; +class AccessTokenKit { +public: + static int VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName); +}; +} // namespace Security::AccessToken +} // namespace OHOS +#endif // FOUNDATION_ARKUI_UI_APPEARANCE_TEST_MOCK_ACCESSTOKEN_KIT \ No newline at end of file diff --git a/test/mock/src/accesstoken_kit.cpp b/test/mock/src/accesstoken_kit.cpp new file mode 100644 index 0000000..1315ee8 --- /dev/null +++ b/test/mock/src/accesstoken_kit.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "accesstoken_kit.h" + +namespace OHOS { +namespace Security::AccessToken { +int AccessTokenKit::VerifyAccessToken(AccessTokenID tokenID, const std::string& permissionName) +{ + return 0; +} +} // namespace Security::AccessToken +} // namespace OHOS \ No newline at end of file diff --git a/test/mock/src/mock_app_mgr_proxy.cpp b/test/mock/src/mock_app_mgr_proxy.cpp new file mode 100644 index 0000000..b87fab1 --- /dev/null +++ b/test/mock/src/mock_app_mgr_proxy.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "app_mgr_proxy.h" + +namespace OHOS { +namespace AppExecFwk { +int32_t AppMgrProxy::UpdateConfiguration(const Configuration& config) +{ + return 0; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/test/mock/src/mock_parameter.cpp b/test/mock/src/mock_parameter.cpp new file mode 100644 index 0000000..c5ebae3 --- /dev/null +++ b/test/mock/src/mock_parameter.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "syspara/parameter.h" + +namespace { +constexpr int32_t buffSize = 10; // buff len: 64 +char value_[buffSize] = "light"; +} // namespace + +int GetParameter(const char* key, const char* def, char* value, unsigned int len) +{ + (void)key; + (void)def; + (void)strncpy_s(value, len, value_, buffSize); + return 1; +} + +int SetParameter(const char* key, const char* value) +{ + (void)key; + (void)strncpy_s(value_, buffSize, value, strlen(value) + 1); + return 0; +} diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100644 index 0000000..1540de2 --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,57 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build/test.gni") + +ohos_unittest("ui_appearance_test") { + module_out_path = "ui_appearance/ui_appearance_test" + + include_dirs = [ + "../mock/include", + ] + + sources = [ + "ui_appearance_test.cpp", + "../mock/src/accesstoken_kit.cpp", + "../mock/src/mock_app_mgr_proxy.cpp", + "../mock/src/mock_parameter.cpp", + ] + + configs = [] + cflags = [] + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + deps = [ + "../../services:ui_appearance_service", + ] + + external_deps = [ + "bundle_framework:appexecfwk_core", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "hiviewdfx_hilog_native:libhilog", + "init:libbegetutil", + "c_utils:utils", + "ability_base:configuration", + "ability_base:want", + "ability_runtime:app_manager", + "samgr:samgr_proxy", + "safwk:system_ability_fwk", + "ipc:ipc_core", + ] +} + +group("unittest") { + testonly = true + deps = [ ":ui_appearance_test" ] +} diff --git a/test/unittest/ui_appearance_test.cpp b/test/unittest/ui_appearance_test.cpp new file mode 100644 index 0000000..98ed516 --- /dev/null +++ b/test/unittest/ui_appearance_test.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "accesstoken_kit.h" +#include "syspara/parameter.h" +#include "system_ability_definition.h" +#include "ui_appearance_ability.h" +#include "ui_appearance_log.h" + +using namespace testing::ext; +static constexpr int UISERVER_UID = 3050; + +namespace OHOS { +namespace ArkUi::UiAppearance { +class UiAppearanceAbilityTest : public UiAppearanceAbility { +public: + UiAppearanceAbilityTest() : UiAppearanceAbility(ARKUI_UI_APPEARANCE_SERVICE_ID, true) {} + ~UiAppearanceAbilityTest() {} + void OnStart() override + { + return; + } +}; + +class DarkModeTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + static sptr GetUiAppearanceAbilityTest() + { + return new UiAppearanceAbilityTest; + } + +private: + int userId_; +}; + +void DarkModeTest::SetUpTestCase(void) {} + +void DarkModeTest::TearDownTestCase(void) {} + +void DarkModeTest::SetUp(void) +{ + userId_ = geteuid(); + seteuid(UISERVER_UID); +} + +void DarkModeTest::TearDown(void) +{ + seteuid(userId_); +} + +/** + * @tc.name: ui_appearance_test_001 + * @tc.desc: Test SetDarkMode and GetDarkMode APIs when setting dark/light. + * @tc.type: FUNC + */ +HWTEST_F(DarkModeTest, ui_appearance_test_001, TestSize.Level0) +{ + HILOG_INFO("Test SetDarkMode and GetDarkMode APIs when setting dark/light."); + + auto test = DarkModeTest::GetUiAppearanceAbilityTest(); + auto result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + EXPECT_EQ(result, 0); + UiAppearanceAbilityInterface::DarkMode mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + + result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); + EXPECT_EQ(result, 0); + mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); +} + +/** + * @tc.name: ui_appearance_test_002 + * @tc.desc: Test SetDarkMode and GetDarkMode APIs when repeatedly setting dark/light. + * @tc.type: FUNC + */ +HWTEST_F(DarkModeTest, ui_appearance_test_002, TestSize.Level0) +{ + HILOG_INFO("Test SetDarkMode and GetDarkMode APIs when repeatedly setting dark/light."); + + auto test = DarkModeTest::GetUiAppearanceAbilityTest(); + auto result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + EXPECT_EQ(result, 0); + UiAppearanceAbilityInterface::DarkMode mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + + result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + EXPECT_EQ(result, 0); + mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK); + + result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); + EXPECT_EQ(result, 0); + mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); + + result = test->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); + EXPECT_EQ(result, 0); + mode = test->GetDarkMode(); + EXPECT_EQ(mode, UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT); +} + +/** + * @tc.name: ui_appearance_test_003 + * @tc.desc: Test the SetDarkMode API when setting an unexpected value + * @tc.type: FUNC + */ +HWTEST_F(DarkModeTest, ui_appearance_test_003, TestSize.Level0) +{ + HILOG_INFO("Test the SetDarkMode API when setting an unexpected value."); + + int result = + DarkModeTest::GetUiAppearanceAbilityTest()->SetDarkMode(UiAppearanceAbilityInterface::DarkMode::UNKNOWN); + EXPECT_NE(result, 0); +} +} // namespace ArkUi::UiAppearance +} // namespace OHOS \ No newline at end of file