1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ani_common_configuration.h"
17
18 #include "ani_enum_convert.h"
19 #include "configuration_convertor.h"
20 #include "hilog_tag_wrapper.h"
21
22 namespace OHOS {
23 namespace AppExecFwk {
24 namespace {
25 constexpr double FONT_SIZE_MIN_SCALE = 0.0;
26 constexpr double FONT_SIZE_MAX_SCALE = 3.2;
27 constexpr double FONT_WEIGHT_MIN_SCALE = 0.0;
28 constexpr double FONT_WEIGHT_MAX_SCALE = 1.25;
29 constexpr const char* COLOR_MODE_ENUM_NAME =
30 "L@ohos/app/ability/ConfigurationConstant/ConfigurationConstant/ColorMode;";
31 constexpr const char* DIRECTION_ENUM_NAME =
32 "L@ohos/app/ability/ConfigurationConstant/ConfigurationConstant/Direction;";
33 constexpr const char* DENSITY_ENUM_NAME =
34 "L@ohos/app/ability/ConfigurationConstant/ConfigurationConstant/ScreenDensity;";
35 constexpr const char* CONFIGURATION_IMPL_CLASS_NAME = "L@ohos/app/ability/Configuration/ConfigurationImpl;";
36
SetBasicConfiguration(ani_env * env,ani_object object,const AppExecFwk::Configuration & configuration)37 void SetBasicConfiguration(ani_env *env, ani_object object, const AppExecFwk::Configuration &configuration)
38 {
39 if (env == nullptr || object == nullptr) {
40 TAG_LOGE(AAFwkTag::ANI, "null env or object");
41 return;
42 }
43 std::string str = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE);
44 env->Object_SetPropertyByName_Ref(object, "language", GetAniString(env, str));
45
46 ani_enum_item colorModeItem = nullptr;
47 OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env,
48 COLOR_MODE_ENUM_NAME,
49 ConvertColorMode(configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE)), colorModeItem);
50 env->Object_SetPropertyByName_Ref(object, "colorMode", colorModeItem);
51
52 int32_t displayId = ConvertDisplayId(configuration.GetItem(ConfigurationInner::APPLICATION_DISPLAYID));
53 env->Object_SetPropertyByName_Ref(object, "displayId", CreateDouble(env, static_cast<ani_double>(displayId)));
54
55 std::string direction = configuration.GetItem(displayId, ConfigurationInner::APPLICATION_DIRECTION);
56 ani_enum_item directionItem = nullptr;
57 OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env,
58 DIRECTION_ENUM_NAME, ConvertDirection(direction),
59 directionItem);
60 env->Object_SetPropertyByName_Ref(object, "direction", directionItem);
61
62 std::string density = configuration.GetItem(displayId, ConfigurationInner::APPLICATION_DENSITYDPI);
63 ani_enum_item densityItem = nullptr;
64 OHOS::AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env,
65 DENSITY_ENUM_NAME, ConvertDensity(density), densityItem);
66 env->Object_SetPropertyByName_Ref(object, "screenDensity", densityItem);
67 }
68
SetAdditionalConfiguration(ani_env * env,ani_object object,const AppExecFwk::Configuration & configuration)69 void SetAdditionalConfiguration(ani_env *env, ani_object object, const AppExecFwk::Configuration &configuration)
70 {
71 std::string hasPointerDevice = configuration.GetItem(AAFwk::GlobalConfigurationKey::INPUT_POINTER_DEVICE);
72 env->Object_SetPropertyByName_Ref(
73 object, "hasPointerDevice", CreateBoolean(env, hasPointerDevice == "true" ? true : false));
74
75 std::string str = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_ID);
76 env->Object_SetPropertyByName_Ref(object, "fontId", GetAniString(env, str));
77
78 std::string fontSizeScale = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE);
79 try {
80 env->Object_SetPropertyByName_Ref(
81 object, "fontSizeScale", CreateDouble(env, fontSizeScale != "" ? std::stod(fontSizeScale) : 1.0));
82 } catch (...) {
83 TAG_LOGE(AAFwkTag::ANI, "stod(%{public}s) failed", fontSizeScale.c_str());
84 return;
85 }
86
87 std::string fontWeightScale = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE);
88 try {
89 env->Object_SetPropertyByName_Ref(
90 object, "fontWeightScale", CreateDouble(env, fontWeightScale != "" ? std::stod(fontWeightScale) : 1.0));
91 } catch (...) {
92 TAG_LOGE(AAFwkTag::ANI, "stod(%{public}s) failed", fontWeightScale.c_str());
93 return;
94 }
95
96 str = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MCC);
97 env->Object_SetPropertyByName_Ref(object, "mcc", GetAniString(env, str));
98
99 str = configuration.GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_MNC);
100 env->Object_SetPropertyByName_Ref(object, "mnc", GetAniString(env, str));
101 }
102 } // namespace
103
WrapConfiguration(ani_env * env,const AppExecFwk::Configuration & configuration)104 ani_object WrapConfiguration(ani_env *env, const AppExecFwk::Configuration &configuration)
105 {
106 if (env == nullptr) {
107 TAG_LOGE(AAFwkTag::ANI, "null env");
108 return nullptr;
109 }
110 ani_class cls = nullptr;
111 ani_status status = env->FindClass(CONFIGURATION_IMPL_CLASS_NAME, &cls);
112 if (status != ANI_OK) {
113 TAG_LOGE(AAFwkTag::ANI, "FindClass status: %{public}d", status);
114 return nullptr;
115 }
116 if (cls == nullptr) {
117 TAG_LOGE(AAFwkTag::ANI, "null Configuration");
118 return nullptr;
119 }
120 ani_method method = nullptr;
121 if ((status = env->Class_FindMethod(cls, "<ctor>", ":V", &method)) != ANI_OK) {
122 TAG_LOGE(AAFwkTag::ANI, "Class_FindMethod status: %{public}d", status);
123 return nullptr;
124 }
125 ani_object object = nullptr;
126 if ((status = env->Object_New(cls, method, &object)) != ANI_OK) {
127 TAG_LOGE(AAFwkTag::ANI, "Object_New status: %{public}d", status);
128 return nullptr;
129 }
130 if (object == nullptr) {
131 TAG_LOGE(AAFwkTag::ANI, "null object");
132 return nullptr;
133 }
134 SetBasicConfiguration(env, object, configuration);
135 SetAdditionalConfiguration(env, object, configuration);
136 return object;
137 }
138
UnwrapConfiguration(ani_env * env,ani_object param,Configuration & config)139 bool UnwrapConfiguration(ani_env *env, ani_object param, Configuration &config)
140 {
141 if (env == nullptr) {
142 TAG_LOGE(AAFwkTag::ANI, "null env");
143 return false;
144 }
145 std::string language { "" };
146 if (GetFieldStringByName(env, param, "language", language)) {
147 TAG_LOGD(AAFwkTag::ANI, "The parsed language part %{public}s", language.c_str());
148 if (!config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, language)) {
149 TAG_LOGE(AAFwkTag::ANI, "language Parsing failed");
150 return false;
151 }
152 }
153
154 ani_double fontSizeScale = 0.0;
155 if (GetFieldDoubleByName(env, param, "fontSizeScale", fontSizeScale)) {
156 if (fontSizeScale < FONT_SIZE_MIN_SCALE || fontSizeScale > FONT_SIZE_MAX_SCALE) {
157 TAG_LOGE(AAFwkTag::ANI, "invalid fontSizeScale");
158 return false;
159 }
160 if (!config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_SIZE_SCALE, std::to_string(fontSizeScale))) {
161 return false;
162 }
163 }
164
165 ani_double fontWeightScale = 0.0;
166 if (GetFieldDoubleByName(env, param, "fontWeightScale", fontWeightScale)) {
167 if (fontWeightScale < FONT_WEIGHT_MIN_SCALE || fontWeightScale > FONT_WEIGHT_MAX_SCALE) {
168 TAG_LOGE(AAFwkTag::ANI, "invalid fontWeightScale");
169 return false;
170 }
171 if (!config.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_FONT_WEIGHT_SCALE, std::to_string(fontWeightScale))) {
172 return false;
173 }
174 }
175 return true;
176 }
177 } // namespace AppExecFwk
178 } // namespace OHOS
179