1 /*
2 * Copyright (c) 2021-2022 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 #include "js_window_utils.h"
16 #include <iomanip>
17 #include <regex>
18 #include <sstream>
19 #include "accesstoken_kit.h"
20 #include "bundle_constants.h"
21 #include "ipc_skeleton.h"
22 #include "js_runtime_utils.h"
23 #include "window_manager_hilog.h"
24 namespace OHOS {
25 namespace Rosen {
26 using namespace AbilityRuntime;
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowUtils"};
29 }
30
WindowTypeInit(NativeEngine * engine)31 NativeValue* WindowTypeInit(NativeEngine* engine)
32 {
33 WLOGFI("WindowTypeInit");
34
35 if (engine == nullptr) {
36 WLOGFE("Invalid input parameters");
37 return nullptr;
38 }
39
40 NativeValue *objValue = engine->CreateObject();
41 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
42
43 if (object == nullptr) {
44 WLOGFE("Failed to get object");
45 return nullptr;
46 }
47
48 object->SetProperty("TYPE_APP", CreateJsValue(*engine,
49 static_cast<int32_t>(ApiWindowType::TYPE_APP)));
50 object->SetProperty("TYPE_SYSTEM_ALERT", CreateJsValue(*engine,
51 static_cast<int32_t>(ApiWindowType::TYPE_SYSTEM_ALERT)));
52 object->SetProperty("TYPE_INPUT_METHOD", CreateJsValue(*engine,
53 static_cast<int32_t>(ApiWindowType::TYPE_INPUT_METHOD)));
54 object->SetProperty("TYPE_STATUS_BAR", CreateJsValue(*engine,
55 static_cast<int32_t>(ApiWindowType::TYPE_STATUS_BAR)));
56 object->SetProperty("TYPE_PANEL", CreateJsValue(*engine,
57 static_cast<int32_t>(ApiWindowType::TYPE_PANEL)));
58 object->SetProperty("TYPE_KEYGUARD", CreateJsValue(*engine,
59 static_cast<int32_t>(ApiWindowType::TYPE_KEYGUARD)));
60 object->SetProperty("TYPE_VOLUME_OVERLAY", CreateJsValue(*engine,
61 static_cast<int32_t>(ApiWindowType::TYPE_VOLUME_OVERLAY)));
62 object->SetProperty("TYPE_NAVIGATION_BAR", CreateJsValue(*engine,
63 static_cast<int32_t>(ApiWindowType::TYPE_NAVIGATION_BAR)));
64 object->SetProperty("TYPE_FLOAT", CreateJsValue(*engine,
65 static_cast<int32_t>(ApiWindowType::TYPE_FLOAT)));
66 return objValue;
67 }
68
AvoidAreaTypeInit(NativeEngine * engine)69 NativeValue* AvoidAreaTypeInit(NativeEngine* engine)
70 {
71 WLOGFI("AvoidAreaTypeInit");
72
73 if (engine == nullptr) {
74 WLOGFE("Invalid input parameters");
75 return nullptr;
76 }
77
78 NativeValue *objValue = engine->CreateObject();
79 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
80
81 if (object == nullptr) {
82 WLOGFE("Failed to get object");
83 return nullptr;
84 }
85
86 object->SetProperty("TYPE_SYSTEM", CreateJsValue(*engine,
87 static_cast<int32_t>(AvoidAreaType::TYPE_SYSTEM)));
88 object->SetProperty("TYPE_CUTOUT", CreateJsValue(*engine,
89 static_cast<int32_t>(AvoidAreaType::TYPE_CUTOUT)));
90 return objValue;
91 }
92
WindowModeInit(NativeEngine * engine)93 NativeValue* WindowModeInit(NativeEngine* engine)
94 {
95 WLOGFI("WindowModeInit");
96
97 if (engine == nullptr) {
98 WLOGFE("Invalid input parameters");
99 return nullptr;
100 }
101
102 NativeValue *objValue = engine->CreateObject();
103 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
104
105 if (object == nullptr) {
106 WLOGFE("Failed to get object");
107 return nullptr;
108 }
109
110 object->SetProperty("UNDEFINED", CreateJsValue(*engine,
111 static_cast<int32_t>(ApiWindowMode::UNDEFINED)));
112 object->SetProperty("FULLSCREEN", CreateJsValue(*engine,
113 static_cast<int32_t>(ApiWindowMode::FULLSCREEN)));
114 object->SetProperty("PRIMARY", CreateJsValue(*engine,
115 static_cast<int32_t>(ApiWindowMode::PRIMARY)));
116 object->SetProperty("SECONDARY", CreateJsValue(*engine,
117 static_cast<int32_t>(ApiWindowMode::SECONDARY)));
118 object->SetProperty("FLOATING", CreateJsValue(*engine,
119 static_cast<int32_t>(ApiWindowMode::FLOATING)));
120 return objValue;
121 }
122
ColorSpaceInit(NativeEngine * engine)123 NativeValue* ColorSpaceInit(NativeEngine* engine)
124 {
125 WLOGFI("ColorSpaceInit");
126
127 if (engine == nullptr) {
128 WLOGFE("Invalid input parameters");
129 return nullptr;
130 }
131
132 NativeValue *objValue = engine->CreateObject();
133 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
134
135 if (object == nullptr) {
136 WLOGFE("Failed to get object");
137 return nullptr;
138 }
139
140 object->SetProperty("DEFAULT", CreateJsValue(*engine,
141 static_cast<int32_t>(ColorSpace::COLOR_SPACE_DEFAULT)));
142 object->SetProperty("WIDE_GAMUT", CreateJsValue(*engine,
143 static_cast<int32_t>(ColorSpace::COLOR_SPACE_WIDE_GAMUT)));
144 return objValue;
145 }
146
WindowStageEventTypeInit(NativeEngine * engine)147 NativeValue* WindowStageEventTypeInit(NativeEngine* engine)
148 {
149 WLOGFI("WindowStageEventTypeInit");
150
151 if (engine == nullptr) {
152 WLOGFE("Invalid input parameters");
153 return nullptr;
154 }
155
156 NativeValue *objValue = engine->CreateObject();
157 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
158
159 if (object == nullptr) {
160 WLOGFE("Failed to get object");
161 return nullptr;
162 }
163
164 object->SetProperty("FOREGROUND", CreateJsValue(*engine,
165 static_cast<int32_t>(LifeCycleEventType::FOREGROUND)));
166 object->SetProperty("ACTIVE", CreateJsValue(*engine,
167 static_cast<int32_t>(LifeCycleEventType::ACTIVE)));
168 object->SetProperty("INACTIVE", CreateJsValue(*engine,
169 static_cast<int32_t>(LifeCycleEventType::INACTIVE)));
170 object->SetProperty("BACKGROUND", CreateJsValue(*engine,
171 static_cast<int32_t>(LifeCycleEventType::BACKGROUND)));
172 return objValue;
173 }
174
GetRectAndConvertToJsValue(NativeEngine & engine,const Rect rect)175 NativeValue* GetRectAndConvertToJsValue(NativeEngine& engine, const Rect rect)
176 {
177 NativeValue* objValue = engine.CreateObject();
178 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
179 if (object == nullptr) {
180 WLOGFE("Failed to convert rect to jsObject");
181 return nullptr;
182 }
183 object->SetProperty("left", CreateJsValue(engine, rect.posX_));
184 object->SetProperty("top", CreateJsValue(engine, rect.posY_));
185 object->SetProperty("width", CreateJsValue(engine, rect.width_));
186 object->SetProperty("height", CreateJsValue(engine, rect.height_));
187 return objValue;
188 }
189
CreateJsWindowPropertiesObject(NativeEngine & engine,sptr<Window> & window)190 NativeValue* CreateJsWindowPropertiesObject(NativeEngine& engine, sptr<Window>& window)
191 {
192 WLOGFI("JsWindowUtils::CreateJsWindowPropertiesObject is called");
193 NativeValue* objValue = engine.CreateObject();
194 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
195 if (object == nullptr) {
196 WLOGFE("Failed to convert windowProperties to jsObject");
197 return nullptr;
198 }
199
200 Rect rect = window->GetRect();
201 NativeValue* rectObj = GetRectAndConvertToJsValue(engine, rect);
202 if (rectObj == nullptr) {
203 WLOGFE("GetRect failed!");
204 }
205 object->SetProperty("windowRect", rectObj);
206 WindowType type = window->GetType();
207 if (NATIVE_JS_TO_WINDOW_TYPE_MAP.count(type) != 0) {
208 object->SetProperty("type", CreateJsValue(engine, NATIVE_JS_TO_WINDOW_TYPE_MAP.at(type)));
209 } else {
210 object->SetProperty("type", CreateJsValue(engine, type));
211 }
212 object->SetProperty("isLayoutFullScreen", CreateJsValue(engine, window->IsLayoutFullScreen()));
213 object->SetProperty("isFullScreen", CreateJsValue(engine, window->IsFullScreen()));
214 object->SetProperty("touchable", CreateJsValue(engine, window->GetTouchable()));
215 object->SetProperty("focusable", CreateJsValue(engine, window->GetFocusable()));
216 object->SetProperty("name", CreateJsValue(engine, window->GetWindowName()));
217 object->SetProperty("isPrivacyMode", CreateJsValue(engine, window->IsPrivacyMode()));
218 object->SetProperty("isKeepScreenOn", CreateJsValue(engine, window->IsKeepScreenOn()));
219 object->SetProperty("brightness", CreateJsValue(engine, window->GetBrightness()));
220 object->SetProperty("isTransparent", CreateJsValue(engine, window->IsTransparent()));
221 object->SetProperty("isRoundCorner", CreateJsValue(engine, false)); // empty method
222 object->SetProperty("dimBehindValue", CreateJsValue(engine, 0));
223 return objValue;
224 }
GetHexColor(uint32_t color)225 static std::string GetHexColor(uint32_t color)
226 {
227 std::stringstream ioss;
228 std::string temp;
229 ioss << std::setiosflags(std::ios::uppercase) << std::hex << color;
230 ioss >> temp;
231 int count = RGBA_LENGTH - static_cast<int>(temp.length());
232 std::string tmpColor(count, '0');
233 tmpColor += temp;
234 std::string finalColor("#");
235 finalColor += tmpColor;
236 return finalColor;
237 }
238
CreateJsSystemBarRegionTintObject(NativeEngine & engine,const SystemBarRegionTint & tint)239 static NativeValue* CreateJsSystemBarRegionTintObject(NativeEngine& engine, const SystemBarRegionTint& tint)
240 {
241 WLOGFI("JsWindowUtils::CreateJsSystemBarRegionTintObject is called");
242
243 NativeValue* objValue = engine.CreateObject();
244 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
245 if (object == nullptr) {
246 WLOGFE("Failed to convert SystemBarProperty to jsObject");
247 return nullptr;
248 }
249 object->SetProperty("type", CreateJsValue(engine, static_cast<uint32_t>(tint.type_)));
250 object->SetProperty("isEnable", CreateJsValue(engine, tint.prop_.enable_));
251 std::string bkgColor = GetHexColor(tint.prop_.backgroundColor_);
252 WLOGFI("JsWindowUtils::CreateJsSystemBarRegionTintObject backgroundColir: %{public}s", bkgColor.c_str());
253 object->SetProperty("backgroundColor", CreateJsValue(engine, bkgColor));
254 std::string contentColor = GetHexColor(tint.prop_.contentColor_);
255 WLOGFI("JsWindowUtils::CreateJsSystemBarRegionTintObject contentColor: %{public}s", contentColor.c_str());
256 object->SetProperty("contentColor", CreateJsValue(engine, contentColor));
257 Rect rect = tint.region_;
258 object->SetProperty("region", GetRectAndConvertToJsValue(engine, rect));
259 WLOGFI("JsWindowUtils::CreateJsSystemBarRegionTintObject rect: [%{public}d %{public}d %{public}d %{public}d]",
260 rect.posX_, rect.posY_, rect.width_, rect.height_);
261 return objValue;
262 }
263
CreateJsSystemBarRegionTintArrayObject(NativeEngine & engine,const SystemBarRegionTints & tints)264 NativeValue* CreateJsSystemBarRegionTintArrayObject(NativeEngine& engine, const SystemBarRegionTints& tints)
265 {
266 WLOGFI("JsWindowUtils::CreateJsSystemBarRegionTintArrayObject is called");
267 if (tints.empty()) {
268 return nullptr;
269 }
270 NativeValue* objValue = engine.CreateArray(tints.size());
271 NativeArray* array = ConvertNativeValueTo<NativeArray>(objValue);
272 if (array == nullptr) {
273 WLOGFE("Failed to convert SystemBarPropertys to jsArrayObject");
274 return nullptr;
275 }
276 uint32_t index = 0;
277 for (size_t i = 0; i < tints.size(); i++) {
278 array->SetElement(index++, CreateJsSystemBarRegionTintObject(engine, tints[i]));
279 }
280 return objValue;
281 }
282
GetSystemBarStatus(std::map<WindowType,SystemBarProperty> & systemBarProperties,NativeEngine & engine,NativeCallbackInfo & info,sptr<Window> & window)283 bool GetSystemBarStatus(std::map<WindowType, SystemBarProperty>& systemBarProperties,
284 NativeEngine& engine, NativeCallbackInfo& info, sptr<Window>& window)
285 {
286 NativeArray* nativeArray = nullptr;
287 uint32_t size = 0;
288 if (info.argc > 0 && info.argv[0]->TypeOf() != NATIVE_FUNCTION) {
289 nativeArray = ConvertNativeValueTo<NativeArray>(info.argv[0]);
290 if (nativeArray == nullptr) {
291 WLOGFE("[NAPI]Failed to convert parameter to SystemBarArray");
292 return false;
293 }
294 size = nativeArray->GetLength();
295 }
296 auto statusProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
297 auto navProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
298 statusProperty.enable_ = false;
299 navProperty.enable_ = false;
300 systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR] = statusProperty;
301 systemBarProperties[WindowType::WINDOW_TYPE_NAVIGATION_BAR] = navProperty;
302 for (uint32_t i = 0; i < size; i++) {
303 std::string name;
304 if (!ConvertFromJsValue(engine, nativeArray->GetElement(i), name)) {
305 WLOGFE("Failed to convert parameter to SystemBarName");
306 return false;
307 }
308 if (name.compare("status") == 0) {
309 systemBarProperties[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = true;
310 } else if (name.compare("navigation") == 0) {
311 systemBarProperties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = true;
312 }
313 }
314 return true;
315 }
316
GetColorFromJs(NativeEngine & engine,NativeObject * jsObject,const char * name,uint32_t defaultColor)317 static uint32_t GetColorFromJs(NativeEngine& engine, NativeObject* jsObject,
318 const char* name, uint32_t defaultColor)
319 {
320 NativeValue* jsColor = jsObject->GetProperty(name);
321 if (jsColor->TypeOf() != NATIVE_UNDEFINED) {
322 std::string colorStr;
323 if (!ConvertFromJsValue(engine, jsColor, colorStr)) {
324 WLOGFE("Failed to convert parameter to color");
325 return defaultColor;
326 }
327 std::regex pattern("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$");
328 if (!std::regex_match(colorStr, pattern)) {
329 WLOGFE("invalid color input");
330 return defaultColor;
331 }
332 WLOGFI("origin color: %{public}s", colorStr.c_str());
333 std::string color = colorStr.substr(1);
334 if (color.length() == RGB_LENGTH) {
335 color = "FF" + color; // ARGB
336 }
337 std::stringstream ss;
338 uint32_t hexColor;
339 ss << std::hex << color;
340 ss >> hexColor;
341 WLOGFI("color: %{public}s, Final Color is %{public}x", color.c_str(), hexColor);
342 return hexColor;
343 }
344 return defaultColor;
345 }
346
SetSystemBarPropertiesFromJs(NativeEngine & engine,NativeObject * jsObject,std::map<WindowType,SystemBarProperty> & properties,sptr<Window> & window)347 bool SetSystemBarPropertiesFromJs(NativeEngine& engine, NativeObject* jsObject,
348 std::map<WindowType, SystemBarProperty>& properties, sptr<Window>& window)
349 {
350 auto statusProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
351 auto navProperty = window->GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_NAVIGATION_BAR);
352 properties[WindowType::WINDOW_TYPE_STATUS_BAR] = statusProperty;
353 properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR] = navProperty;
354 properties[WindowType::WINDOW_TYPE_STATUS_BAR].backgroundColor_ = GetColorFromJs(engine,
355 jsObject, "statusBarColor", statusProperty.backgroundColor_);
356 properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].backgroundColor_ = GetColorFromJs(engine,
357 jsObject, "navigationBarColor", navProperty.backgroundColor_);
358 NativeValue* jsStatusContentColor = jsObject->GetProperty("statusBarContentColor");
359 NativeValue* jsStatusIcon = jsObject->GetProperty("isStatusBarLightIcon");
360 if (jsStatusContentColor->TypeOf() != NATIVE_UNDEFINED) {
361 properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = GetColorFromJs(engine,
362 jsObject, "statusBarContentColor", statusProperty.contentColor_);
363 } else if (jsStatusIcon->TypeOf() != NATIVE_UNDEFINED) {
364 bool isStatusBarLightIcon;
365 if (!ConvertFromJsValue(engine, jsStatusIcon, isStatusBarLightIcon)) {
366 WLOGFE("Failed to convert parameter to isStatusBarLightIcon");
367 return false;
368 }
369 if (isStatusBarLightIcon) {
370 properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = SYSTEM_COLOR_WHITE;
371 } else {
372 properties[WindowType::WINDOW_TYPE_STATUS_BAR].contentColor_ = SYSTEM_COLOR_BLACK;
373 }
374 }
375 NativeValue* jsNavigationContentColor = jsObject->GetProperty("navigationBarContentColor");
376 NativeValue* jsNavigationIcon = jsObject->GetProperty("isNavigationBarLightIcon");
377 if (jsNavigationContentColor->TypeOf() != NATIVE_UNDEFINED) {
378 properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = GetColorFromJs(engine,
379 jsObject, "navigationBarContentColor", navProperty.contentColor_);
380 } else if (jsNavigationIcon->TypeOf() != NATIVE_UNDEFINED) {
381 bool isNavigationBarLightIcon;
382 if (!ConvertFromJsValue(engine, jsNavigationIcon, isNavigationBarLightIcon)) {
383 WLOGFE("Failed to convert parameter to isNavigationBarLightIcon");
384 return false;
385 }
386 if (isNavigationBarLightIcon) {
387 properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = SYSTEM_COLOR_WHITE;
388 } else {
389 properties[WindowType::WINDOW_TYPE_NAVIGATION_BAR].contentColor_ = SYSTEM_COLOR_BLACK;
390 }
391 }
392 return true;
393 }
394
ChangeAvoidAreaToJsValue(NativeEngine & engine,const AvoidArea & avoidArea)395 NativeValue* ChangeAvoidAreaToJsValue(NativeEngine& engine, const AvoidArea& avoidArea)
396 {
397 NativeValue* objValue = engine.CreateObject();
398 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
399 if (object == nullptr) {
400 WLOGFE("Failed to convert rect to jsObject");
401 return engine.CreateUndefined();
402 }
403 object->SetProperty("leftRect", GetRectAndConvertToJsValue(engine, avoidArea.leftRect));
404 object->SetProperty("topRect", GetRectAndConvertToJsValue(engine, avoidArea.topRect));
405 object->SetProperty("rightRect", GetRectAndConvertToJsValue(engine, avoidArea.rightRect));
406 object->SetProperty("bottomRect", GetRectAndConvertToJsValue(engine, avoidArea.bottomRect));
407 return objValue;
408 }
409
CheckCallingPermission(std::string permission)410 bool CheckCallingPermission(std::string permission)
411 {
412 WLOGFI("JsWindowUtils::CheckCallingPermission, permission:%{public}s", permission.c_str());
413 if (!permission.empty() &&
414 Security::AccessToken::AccessTokenKit::VerifyAccessToken(IPCSkeleton::GetCallingTokenID(), permission)
415 != AppExecFwk::Constants::PERMISSION_GRANTED) {
416 WLOGFE("%{public}s permission not granted.", permission.c_str());
417 return false;
418 }
419 WLOGFI("JsWindowUtils::CheckCallingPermission end.");
420 return true;
421 }
422
GetAPI7Ability(NativeEngine & engine,AppExecFwk::Ability * & ability)423 bool GetAPI7Ability(NativeEngine& engine, AppExecFwk::Ability* &ability)
424 {
425 napi_value global;
426 auto env = reinterpret_cast<napi_env>(&engine);
427 if (napi_get_global(env, &global) != napi_ok) {
428 WLOGFE("[NAPI]Get global failed");
429 return false;
430 }
431 napi_value jsAbility;
432 napi_status status = napi_get_named_property(env, global, "ability", &jsAbility);
433 if (status != napi_ok || jsAbility == nullptr) {
434 WLOGFE("[NAPI]Get ability property failed");
435 return false;
436 }
437
438 if (napi_get_value_external(env, jsAbility, reinterpret_cast<void **>(&ability)) != napi_ok) {
439 WLOGFE("[NAPI]Get ability external failed");
440 return false;
441 }
442 if (ability == nullptr) {
443 return false;
444 } else {
445 WLOGI("[NAPI]Get ability");
446 }
447 return true;
448 }
449 } // namespace Rosen
450 } // namespace OHOS