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 "ability_info.h"
17 #include "ani_common_start_options.h"
18 #include "hilog_tag_wrapper.h"
19 #include "ani_enum_convert.h"
20 #include "int_wrapper.h"
21 #include "process_options.h"
22 #include "start_window_option.h"
23 #include "parcel.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
27
UnwrapStartOptionsWithProcessOption(ani_env * env,ani_object param,AAFwk::StartOptions & startOptions)28 bool UnwrapStartOptionsWithProcessOption(ani_env* env, ani_object param, AAFwk::StartOptions &startOptions)
29 {
30 TAG_LOGD(AAFwkTag::ANI, "UnwrapStartOptionsWithProcessOption called");
31 if (env == nullptr) {
32 TAG_LOGE(AAFwkTag::ANI, "null env");
33 return false;
34 }
35 if (!UnwrapStartOptions(env, param, startOptions)) {
36 TAG_LOGE(AAFwkTag::ANI, "Unwrap UnwrapStartOptions failed");
37 return false;
38 }
39 if (!UnwrapProcessOptions(env, param, startOptions.processOptions)) {
40 TAG_LOGE(AAFwkTag::ANI, "Unwrap processOptions failed");
41 return false;
42 }
43 if (!UnwrapStartWindowOption(env, param, startOptions.startWindowOption)) {
44 TAG_LOGE(AAFwkTag::ANI, "Unwrap startWindowOption failed");
45 return false;
46 }
47 return true;
48 }
49
UnwrapStartOptionsWindowOptions(ani_env * env,ani_object param,AAFwk::StartOptions & startOptions)50 void UnwrapStartOptionsWindowOptions(ani_env *env, ani_object param, AAFwk::StartOptions &startOptions)
51 {
52 ani_double windowLeft = 0.0;
53 if (GetFieldDoubleByName(env, param, "windowLeft", windowLeft)) {
54 TAG_LOGD(AAFwkTag::ANI, "windowLeft:%{public}f", windowLeft);
55 startOptions.SetWindowLeft(windowLeft);
56 startOptions.windowLeftUsed_ = true;
57 }
58
59 ani_double windowTop = 0.0;
60 if (GetFieldDoubleByName(env, param, "windowTop", windowTop)) {
61 TAG_LOGD(AAFwkTag::ANI, "windowTop:%{public}f", windowTop);
62 startOptions.SetWindowTop(windowTop);
63 startOptions.windowTopUsed_ = true;
64 }
65
66 ani_double windowWidth = 0.0;
67 if (GetFieldDoubleByName(env, param, "windowWidth", windowWidth)) {
68 TAG_LOGD(AAFwkTag::ANI, "windowWidth:%{public}f", windowWidth);
69 startOptions.SetWindowWidth(windowWidth);
70 startOptions.windowWidthUsed_ = true;
71 }
72
73 ani_double windowHeight = 0.0;
74 if (GetFieldDoubleByName(env, param, "windowHeight", windowHeight)) {
75 TAG_LOGD(AAFwkTag::ANI, "windowHeight:%{public}f", windowHeight);
76 startOptions.SetWindowHeight(windowHeight);
77 startOptions.windowHeightUsed_ = true;
78 }
79
80 ani_double minWindowWidth = 0.0;
81 if (GetFieldDoubleByName(env, param, "minWindowWidth", minWindowWidth)) {
82 TAG_LOGD(AAFwkTag::ANI, "minWindowWidth:%{public}f", minWindowWidth);
83 startOptions.SetMinWindowWidth(minWindowWidth);
84 startOptions.minWindowWidthUsed_ = true;
85 }
86
87 ani_double minWindowHeight = 0.0;
88 if (GetFieldDoubleByName(env, param, "minWindowHeight", minWindowHeight)) {
89 TAG_LOGD(AAFwkTag::ANI, "minWindowHeight:%{public}f", minWindowHeight);
90 startOptions.SetMinWindowHeight(minWindowHeight);
91 startOptions.minWindowHeightUsed_ = true;
92 }
93
94 ani_double maxWindowWidth = 0.0;
95 if (GetFieldDoubleByName(env, param, "maxWindowWidth", maxWindowWidth)) {
96 TAG_LOGD(AAFwkTag::ANI, "maxWindowWidth:%{public}f", maxWindowWidth);
97 startOptions.SetMaxWindowWidth(maxWindowWidth);
98 startOptions.maxWindowWidthUsed_ = true;
99 }
100
101 ani_double maxWindowHeight = 0.0;
102 if (GetFieldDoubleByName(env, param, "maxWindowHeight", maxWindowHeight)) {
103 TAG_LOGD(AAFwkTag::ANI, "maxWindowHeight:%{public}f", maxWindowHeight);
104 startOptions.SetMaxWindowHeight(maxWindowHeight);
105 startOptions.maxWindowHeightUsed_ = true;
106 }
107 }
108
SetSupportWindowModes(ani_env * env,ani_object param,AAFwk::StartOptions & startOptions)109 bool SetSupportWindowModes(ani_env *env, ani_object param, AAFwk::StartOptions &startOptions)
110 {
111 ani_ref supportWindowModesRef = nullptr;
112 ani_boolean hasValue = true;
113 if (GetPropertyRef(env, param, "supportWindowModes", supportWindowModesRef, hasValue) && !hasValue) {
114 ani_array_ref supportWindowModesArr = reinterpret_cast<ani_array_ref>(supportWindowModesRef);
115 ani_size supportWindowModesLen = 0;
116 if (env->Array_GetLength(supportWindowModesArr, &supportWindowModesLen) != ANI_OK) {
117 TAG_LOGE(AAFwkTag::ANI, "Array_GetLength failed");
118 return false;
119 }
120 for (size_t i = 0; i < supportWindowModesLen; ++i) {
121 ani_ref supportWindowModeRef = nullptr;
122 int32_t supportWindowMode = 0;
123 if (env->Array_Get_Ref(supportWindowModesArr, i, &supportWindowModeRef) != ANI_OK) {
124 TAG_LOGE(AAFwkTag::ANI, "Array_Get_Ref failed");
125 return false;
126 }
127 AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(
128 env, reinterpret_cast<ani_object>(supportWindowModeRef), supportWindowMode);
129 TAG_LOGD(AAFwkTag::ANI, "supportWindowMode:%{public}d", supportWindowMode);
130 startOptions.supportWindowModes_.emplace_back(
131 static_cast<AppExecFwk::SupportWindowMode>(supportWindowMode));
132 }
133 }
134 return true;
135 }
136
137
UnwrapStartOptions(ani_env * env,ani_object param,AAFwk::StartOptions & startOptions)138 bool UnwrapStartOptions(ani_env *env, ani_object param, AAFwk::StartOptions &startOptions)
139 {
140 TAG_LOGD(AAFwkTag::ANI, "UnwrapStartOptions called");
141 if (env == nullptr) {
142 TAG_LOGE(AAFwkTag::ANI, "null env");
143 return false;
144 }
145
146 ani_double windowMode = 0.0;
147 if (GetFieldDoubleByName(env, param, "windowMode", windowMode)) {
148 TAG_LOGD(AAFwkTag::ANI, "windowMode:%{public}f", windowMode);
149 startOptions.SetWindowMode(windowMode);
150 }
151
152 ani_double displayId = 0.0;
153 if (GetFieldDoubleByName(env, param, "displayId", displayId)) {
154 startOptions.SetDisplayID(static_cast<int>(displayId));
155 }
156
157 bool withAnimation = true;
158 if (GetFieldBoolByName(env, param, "withAnimation", withAnimation)) {
159 TAG_LOGD(AAFwkTag::ANI, "withAnimation:%{public}hhu", withAnimation);
160 startOptions.SetWithAnimation(withAnimation);
161 }
162
163 UnwrapStartOptionsWindowOptions(env, param, startOptions);
164
165 bool windowFocused = true;
166 if (GetFieldBoolByName(env, param, "windowFocused", windowFocused)) {
167 TAG_LOGD(AAFwkTag::ANI, "windowFocused:%{public}hhu", windowFocused);
168 startOptions.SetWindowFocused(windowFocused);
169 }
170
171 if (!SetSupportWindowModes(env, param, startOptions)) {
172 TAG_LOGE(AAFwkTag::ANI, "SetSupportWindowModes failed");
173 return false;
174 }
175
176 return true;
177 }
178
UnwrapProcessOptions(ani_env * env,ani_object param,std::shared_ptr<AAFwk::ProcessOptions> & processOptions)179 bool UnwrapProcessOptions(ani_env* env, ani_object param, std::shared_ptr<AAFwk::ProcessOptions> &processOptions)
180 {
181 auto option = std::make_shared<AAFwk::ProcessOptions>();
182
183 ani_boolean isProcessModeUndefined = true;
184 ani_ref processModeRef = nullptr;
185 if (!GetPropertyRef(env, param, "processMode", processModeRef, isProcessModeUndefined)) {
186 TAG_LOGE(AAFwkTag::ANI, "Unwrap processMode failed");
187 return false;
188 }
189
190 ani_boolean isStartupVisibilityUndefined = true;
191 ani_ref startupVisibilityRef = nullptr;
192 if (!GetPropertyRef(env, param, "startupVisibility", startupVisibilityRef, isStartupVisibilityUndefined)) {
193 TAG_LOGE(AAFwkTag::ANI, "Unwrap startupVisibility failed");
194 return false;
195 }
196
197 if (isProcessModeUndefined && isStartupVisibilityUndefined) {
198 return true;
199 }
200
201 int32_t processMode = 0;
202 if (isProcessModeUndefined) {
203 TAG_LOGE(AAFwkTag::ANI, "Unwrap processMode failed");
204 return false;
205 }
206 AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(
207 env, reinterpret_cast<ani_enum_item>(processModeRef), processMode);
208 TAG_LOGD(AAFwkTag::ANI, "processMode: %{public}d", processMode);
209 option->processMode = AAFwk::ProcessOptions::ConvertInt32ToProcessMode(processMode);
210 if (option->processMode == AAFwk::ProcessMode::UNSPECIFIED) {
211 TAG_LOGE(AAFwkTag::ANI, "Convert processMode failed");
212 return false;
213 }
214
215 int32_t startupVisibility = 0;
216 if (isStartupVisibilityUndefined) {
217 TAG_LOGE(AAFwkTag::ANI, "Unwrap startupVisibility failed");
218 return false;
219 }
220 AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(
221 env, reinterpret_cast<ani_enum_item>(startupVisibilityRef), startupVisibility);
222 TAG_LOGD(AAFwkTag::ANI, "startupVisibility: %{public}d", startupVisibility);
223 option->startupVisibility = AAFwk::ProcessOptions::ConvertInt32ToStartupVisibility(startupVisibility);
224 if (option->startupVisibility == AAFwk::StartupVisibility::UNSPECIFIED) {
225 TAG_LOGE(AAFwkTag::ANI, "Convert startupVisibility failed");
226 return false;
227 }
228
229 processOptions = option;
230 return true;
231 }
232
233 #ifdef START_WINDOW_OPTIONS_WITH_PIXELMAP
UnwrapPixelMapFromAni(ani_env * env,ani_object param,std::shared_ptr<Media::PixelMap> & value)234 bool UnwrapPixelMapFromAni(ani_env *env, ani_object param, std::shared_ptr<Media::PixelMap> &value)
235 {
236 auto pixelMap = OHOS::Media::ImageAniUtils::GetPixelMapFromEnvSp(env, param);
237 if (!pixelMap) {
238 TAG_LOGE(AAFwkTag::ANI, "Unwrap pixelMap failed");
239 return false;
240 }
241
242 value = pixelMap;
243 return true;
244 }
245
UnwrapPixelMapByPropertyName(ani_env * env,ani_object param,const char * propertyName,std::shared_ptr<Media::PixelMap> & value)246 bool UnwrapPixelMapByPropertyName(
247 ani_env *env, ani_object param, const char *propertyName, std::shared_ptr<Media::PixelMap> &value)
248 {
249 ani_ref envValue = nullptr;
250 if (!GetFieldRefByName(env, param, propertyName, envValue)) {
251 TAG_LOGE(AAFwkTag::ANI, "Get PixelMap failed");
252 return false;
253 }
254 if (envValue == nullptr) {
255 TAG_LOGE(AAFwkTag::ANI, "UnwrapPixelMapByPropertyName failed");
256 return false;
257 }
258 return UnwrapPixelMapFromAni(env, reinterpret_cast<ani_object>(envValue), value);
259 }
260 #endif
261
UnwrapStartWindowOption(ani_env * env,ani_object param,std::shared_ptr<AAFwk::StartWindowOption> & startWindowOption)262 bool UnwrapStartWindowOption(ani_env *env, ani_object param,
263 std::shared_ptr<AAFwk::StartWindowOption> &startWindowOption)
264 {
265 auto option = std::make_shared<AAFwk::StartWindowOption>();
266 std::string startWindowBackgroundColor;
267 if (IsExistsField(env, param, "startWindowBackgroundColor")) {
268 if (!GetFieldStringByName(env, param, "startWindowBackgroundColor", startWindowBackgroundColor)) {
269 TAG_LOGE(AAFwkTag::JSNAPI, "Unwrap startWindowBackgroundColor failed");
270 return false;
271 }
272 option->startWindowBackgroundColor = startWindowBackgroundColor;
273 }
274 if (!startWindowBackgroundColor.empty()) {
275 option->hasStartWindow = true;
276 }
277 #ifdef START_WINDOW_OPTIONS_WITH_PIXELMAP
278 std::shared_ptr<Media::PixelMap> startWindowIcon = nullptr;
279 if (IsExistsField(env, param, "startWindowIcon")) {
280 if (!UnwrapPixelMapByPropertyName(env, param, "startWindowIcon", startWindowIcon)) {
281 TAG_LOGE(AAFwkTag::ANI, "Unwrap startWindowIcon failed");
282 return false;
283 }
284 option->startWindowIcon = startWindowIcon;
285 }
286
287 if (startWindowIcon != nullptr) {
288 option->hasStartWindow = true;
289 }
290 #endif
291 startWindowOption = option;
292 return true;
293 }
294 } // namespace AppExecFwk
295 } // namespace OHOS