1 /*
2  * Copyright (c) 2023 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 #ifndef OHOS_WINDOW_SCENE_JS_SCENE_UTILS_H
17 #define OHOS_WINDOW_SCENE_JS_SCENE_UTILS_H
18 
19 #include <js_runtime_utils.h>
20 #include <native_engine/native_engine.h>
21 #include <native_engine/native_value.h>
22 #include <pointer_event.h>
23 
24 #include "dm_common.h"
25 #include "interfaces/include/ws_common.h"
26 #include "common/include/window_session_property.h"
27 #include "wm_common.h"
28 #include "hitrace_meter.h"
29 
30 namespace OHOS::Rosen {
31 enum class JsSessionType : uint32_t {
32     TYPE_UNDEFINED = 0,
33     TYPE_APP,
34     TYPE_SUB_APP,
35     TYPE_SYSTEM_ALERT,
36     TYPE_INPUT_METHOD,
37     TYPE_STATUS_BAR,
38     TYPE_PANEL,
39     TYPE_KEYGUARD,
40     TYPE_VOLUME_OVERLAY,
41     TYPE_NAVIGATION_BAR,
42     TYPE_FLOAT,
43     TYPE_WALLPAPER,
44     TYPE_DESKTOP,
45     TYPE_LAUNCHER_DOCK,
46     TYPE_FLOAT_CAMERA,
47     TYPE_DIALOG,
48     TYPE_SCREENSHOT,
49     TYPE_TOAST,
50     TYPE_POINTER,
51     TYPE_LAUNCHER_RECENT,
52     TYPE_SCENE_BOARD,
53     TYPE_DRAGGING_EFFECT,
54     TYPE_INPUT_METHOD_STATUS_BAR,
55     TYPE_GLOBAL_SEARCH,
56     TYPE_NEGATIVE_SCREEN,
57     TYPE_VOICE_INTERACTION,
58     TYPE_SYSTEM_TOAST,
59     TYPE_SYSTEM_FLOAT,
60     TYPE_THEME_EDITOR,
61     TYPE_PIP,
62     TYPE_NAVIGATION_INDICATOR,
63     TYPE_SEARCHING_BAR,
64     TYPE_SYSTEM_SUB_WINDOW,
65     TYPE_HANDWRITE,
66     TYPE_KEYBOARD_PANEL,
67     TYPE_DIVIDER,
68     TYPE_TRANSPARENT_VIEW,
69 };
70 
71 const std::map<WindowType, JsSessionType> WINDOW_TO_JS_SESSION_TYPE_MAP {
72     { WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,          JsSessionType::TYPE_APP                     },
73     { WindowType::WINDOW_TYPE_APP_SUB_WINDOW,           JsSessionType::TYPE_SUB_APP                 },
74     { WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW,      JsSessionType::TYPE_SYSTEM_ALERT            },
75     { WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT,       JsSessionType::TYPE_INPUT_METHOD            },
76     { WindowType::WINDOW_TYPE_STATUS_BAR,               JsSessionType::TYPE_STATUS_BAR              },
77     { WindowType::WINDOW_TYPE_PANEL,                    JsSessionType::TYPE_PANEL                   },
78     { WindowType::WINDOW_TYPE_KEYGUARD,                 JsSessionType::TYPE_KEYGUARD                },
79     { WindowType::WINDOW_TYPE_VOLUME_OVERLAY,           JsSessionType::TYPE_VOLUME_OVERLAY          },
80     { WindowType::WINDOW_TYPE_NAVIGATION_BAR,           JsSessionType::TYPE_NAVIGATION_BAR          },
81     { WindowType::WINDOW_TYPE_FLOAT,                    JsSessionType::TYPE_FLOAT                   },
82     { WindowType::WINDOW_TYPE_WALLPAPER,                JsSessionType::TYPE_WALLPAPER               },
83     { WindowType::WINDOW_TYPE_DESKTOP,                  JsSessionType::TYPE_DESKTOP                 },
84     { WindowType::WINDOW_TYPE_LAUNCHER_DOCK,            JsSessionType::TYPE_LAUNCHER_DOCK           },
85     { WindowType::WINDOW_TYPE_FLOAT_CAMERA,             JsSessionType::TYPE_FLOAT_CAMERA            },
86     { WindowType::WINDOW_TYPE_DIALOG,                   JsSessionType::TYPE_DIALOG                  },
87     { WindowType::WINDOW_TYPE_SCREENSHOT,               JsSessionType::TYPE_SCREENSHOT              },
88     { WindowType::WINDOW_TYPE_TOAST,                    JsSessionType::TYPE_TOAST                   },
89     { WindowType::WINDOW_TYPE_POINTER,                  JsSessionType::TYPE_POINTER                 },
90     { WindowType::WINDOW_TYPE_LAUNCHER_RECENT,          JsSessionType::TYPE_LAUNCHER_RECENT         },
91     { WindowType::WINDOW_TYPE_SCENE_BOARD,              JsSessionType::TYPE_SCENE_BOARD             },
92     { WindowType::WINDOW_TYPE_DRAGGING_EFFECT,          JsSessionType::TYPE_DRAGGING_EFFECT         },
93     { WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR,  JsSessionType::TYPE_INPUT_METHOD_STATUS_BAR },
94     { WindowType::WINDOW_TYPE_GLOBAL_SEARCH,            JsSessionType::TYPE_GLOBAL_SEARCH           },
95     { WindowType::WINDOW_TYPE_NEGATIVE_SCREEN,          JsSessionType::TYPE_NEGATIVE_SCREEN         },
96     { WindowType::WINDOW_TYPE_VOICE_INTERACTION,        JsSessionType::TYPE_VOICE_INTERACTION       },
97     { WindowType::WINDOW_TYPE_SYSTEM_TOAST,             JsSessionType::TYPE_SYSTEM_TOAST            },
98     { WindowType::WINDOW_TYPE_SYSTEM_FLOAT,             JsSessionType::TYPE_SYSTEM_FLOAT            },
99     { WindowType::WINDOW_TYPE_THEME_EDITOR,             JsSessionType::TYPE_THEME_EDITOR            },
100     { WindowType::WINDOW_TYPE_PIP,                      JsSessionType::TYPE_PIP                     },
101     { WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR,     JsSessionType::TYPE_NAVIGATION_INDICATOR    },
102     { WindowType::WINDOW_TYPE_SEARCHING_BAR,            JsSessionType::TYPE_SEARCHING_BAR           },
103     { WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW,        JsSessionType::TYPE_SYSTEM_SUB_WINDOW       },
104     { WindowType::WINDOW_TYPE_HANDWRITE,                JsSessionType::TYPE_HANDWRITE               },
105     { WindowType::WINDOW_TYPE_KEYBOARD_PANEL,           JsSessionType::TYPE_KEYBOARD_PANEL          },
106     { WindowType::WINDOW_TYPE_DOCK_SLICE,               JsSessionType::TYPE_DIVIDER                 },
107     { WindowType::WINDOW_TYPE_TRANSPARENT_VIEW,         JsSessionType::TYPE_TRANSPARENT_VIEW        },
108 };
109 
110 const std::map<JsSessionType, WindowType> JS_SESSION_TO_WINDOW_TYPE_MAP {
111     { JsSessionType::TYPE_APP,                      WindowType::WINDOW_TYPE_APP_MAIN_WINDOW         },
112     { JsSessionType::TYPE_SUB_APP,                  WindowType::WINDOW_TYPE_APP_SUB_WINDOW          },
113     { JsSessionType::TYPE_SYSTEM_ALERT,             WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW     },
114     { JsSessionType::TYPE_INPUT_METHOD,             WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT      },
115     { JsSessionType::TYPE_STATUS_BAR,               WindowType::WINDOW_TYPE_STATUS_BAR              },
116     { JsSessionType::TYPE_PANEL,                    WindowType::WINDOW_TYPE_PANEL                   },
117     { JsSessionType::TYPE_KEYGUARD,                 WindowType::WINDOW_TYPE_KEYGUARD                },
118     { JsSessionType::TYPE_VOLUME_OVERLAY,           WindowType::WINDOW_TYPE_VOLUME_OVERLAY          },
119     { JsSessionType::TYPE_NAVIGATION_BAR,           WindowType::WINDOW_TYPE_NAVIGATION_BAR          },
120     { JsSessionType::TYPE_FLOAT,                    WindowType::WINDOW_TYPE_FLOAT                   },
121     { JsSessionType::TYPE_WALLPAPER,                WindowType::WINDOW_TYPE_WALLPAPER               },
122     { JsSessionType::TYPE_DESKTOP,                  WindowType::WINDOW_TYPE_DESKTOP                 },
123     { JsSessionType::TYPE_LAUNCHER_DOCK,            WindowType::WINDOW_TYPE_LAUNCHER_DOCK           },
124     { JsSessionType::TYPE_FLOAT_CAMERA,             WindowType::WINDOW_TYPE_FLOAT_CAMERA            },
125     { JsSessionType::TYPE_DIALOG,                   WindowType::WINDOW_TYPE_DIALOG                  },
126     { JsSessionType::TYPE_SCREENSHOT,               WindowType::WINDOW_TYPE_SCREENSHOT              },
127     { JsSessionType::TYPE_TOAST,                    WindowType::WINDOW_TYPE_TOAST                   },
128     { JsSessionType::TYPE_POINTER,                  WindowType::WINDOW_TYPE_POINTER                 },
129     { JsSessionType::TYPE_LAUNCHER_RECENT,          WindowType::WINDOW_TYPE_LAUNCHER_RECENT         },
130     { JsSessionType::TYPE_SCENE_BOARD,              WindowType::WINDOW_TYPE_SCENE_BOARD             },
131     { JsSessionType::TYPE_DRAGGING_EFFECT,          WindowType::WINDOW_TYPE_DRAGGING_EFFECT         },
132     { JsSessionType::TYPE_INPUT_METHOD_STATUS_BAR,  WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR },
133     { JsSessionType::TYPE_GLOBAL_SEARCH,            WindowType::WINDOW_TYPE_GLOBAL_SEARCH           },
134     { JsSessionType::TYPE_NEGATIVE_SCREEN,          WindowType::WINDOW_TYPE_NEGATIVE_SCREEN         },
135     { JsSessionType::TYPE_VOICE_INTERACTION,        WindowType::WINDOW_TYPE_VOICE_INTERACTION       },
136     { JsSessionType::TYPE_SYSTEM_TOAST,             WindowType::WINDOW_TYPE_SYSTEM_TOAST,           },
137     { JsSessionType::TYPE_SYSTEM_FLOAT,             WindowType::WINDOW_TYPE_SYSTEM_FLOAT,           },
138     { JsSessionType::TYPE_THEME_EDITOR,             WindowType::WINDOW_TYPE_THEME_EDITOR            },
139     { JsSessionType::TYPE_PIP,                      WindowType::WINDOW_TYPE_PIP,                    },
140     { JsSessionType::TYPE_NAVIGATION_INDICATOR,     WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR    },
141     { JsSessionType::TYPE_SEARCHING_BAR,            WindowType::WINDOW_TYPE_SEARCHING_BAR           },
142     { JsSessionType::TYPE_SYSTEM_SUB_WINDOW,        WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW       },
143     { JsSessionType::TYPE_HANDWRITE,                WindowType::WINDOW_TYPE_HANDWRITE               },
144     { JsSessionType::TYPE_KEYBOARD_PANEL,           WindowType::WINDOW_TYPE_KEYBOARD_PANEL          },
145     { JsSessionType::TYPE_DIVIDER,                  WindowType::WINDOW_TYPE_DOCK_SLICE              },
146     { JsSessionType::TYPE_TRANSPARENT_VIEW,         WindowType::WINDOW_TYPE_TRANSPARENT_VIEW        },
147 };
148 
149 JsSessionType GetApiType(WindowType type);
150 bool ConvertSessionInfoFromJs(napi_env env, napi_value jsObject, SessionInfo& sessionInfo);
151 bool ConvertPointerEventFromJs(napi_env env, napi_value jsObject, MMI::PointerEvent& pointerEvent);
152 bool ConvertDeviceIdFromJs(napi_env env, napi_value jsObject, MMI::PointerEvent& pointerEvent);
153 bool ConvertInt32ArrayFromJs(napi_env env, napi_value jsObject, std::vector<int32_t>& intList);
154 bool ConvertStringMapFromJs(napi_env env, napi_value value, std::unordered_map<std::string, std::string>& stringMap);
155 bool ConvertJsonFromJs(napi_env env, napi_value value, nlohmann::json& payload);
156 bool ParseArrayStringValue(napi_env env, napi_value array, std::vector<std::string>& vector);
157 bool ConvertProcessOptionFromJs(napi_env env, napi_value jsObject,
158     std::shared_ptr<AAFwk::ProcessOptions> processOptions);
159 napi_value CreateJsSessionInfo(napi_env env, const SessionInfo& sessionInfo);
160 napi_value CreateJsSessionRecoverInfo(
161     napi_env env, const SessionInfo& sessionInfo, const sptr<WindowSessionProperty> property);
162 void SetJsSessionInfoByWant(napi_env env, const SessionInfo& sessionInfo, napi_value objValue);
163 napi_value CreateJsProcessOption(napi_env env, std::shared_ptr<AAFwk::ProcessOptions> processOptions);
164 napi_value CreateJsSessionStartupVisibility(napi_env env);
165 napi_value CreateJsWindowVisibility(napi_env env);
166 napi_value CreateJsSessionProcessMode(napi_env env);
167 napi_value GetWindowRectIntValue(napi_env env, int val);
168 napi_value CreateJsSessionState(napi_env env);
169 napi_value CreateJsSessionSizeChangeReason(napi_env env);
170 napi_value CreateJsSessionPiPControlType(napi_env env);
171 napi_value CreateJsSessionPiPControlStatus(napi_env env);
172 napi_value CreateJsSessionGravity(napi_env env);
173 napi_value CreateJsSessionDragResizeType(napi_env env);
174 void CreatePiPSizeChangeReason(napi_env env, napi_value objValue);
175 template<typename T>
176 napi_value CreateJsSessionRect(napi_env env, const T& rect);
177 napi_value CreateJsSessionEventParam(napi_env env, const SessionEventParam& param);
178 napi_value SubWindowModalTypeInit(napi_env env);
179 napi_value CreateJsSystemBarPropertyArrayObject(
180     napi_env env, const std::unordered_map<WindowType, SystemBarProperty>& propertyMap);
181 napi_value CreateJsKeyboardLayoutParams(napi_env env, const KeyboardLayoutParams& params);
182 napi_value SessionTypeInit(napi_env env);
183 napi_value SceneTypeInit(napi_env env);
184 napi_value KeyboardGravityInit(napi_env env);
185 napi_value NapiGetUndefined(napi_env env);
186 napi_valuetype GetType(napi_env env, napi_value value);
187 bool NapiIsCallable(napi_env env, napi_value value);
188 bool ConvertRectInfoFromJs(napi_env env, napi_value jsObject, WSRect& rect);
189 bool ConvertHookInfoFromJs(napi_env env, napi_value jsObject, HookInfo& hookInfo);
190 bool ConvertRotateAnimationConfigFromJs(napi_env env, napi_value value, RotateAnimationConfig& config);
191 bool ConvertDragResizeTypeFromJs(napi_env env, napi_value value, DragResizeType& dragResizeType);
192 WSError GetIntValueFromString(const std::string& str, uint32_t& value);
193 constexpr size_t ARGC_ONE = 1;
194 constexpr size_t ARGC_TWO = 2;
195 constexpr size_t ARGC_THREE = 3;
196 constexpr size_t ARGC_FOUR = 4;
197 constexpr size_t ARGC_FIVE = 5;
198 
199 class MainThreadScheduler {
200 public:
201     using Task = std::function<void()>;
202     explicit MainThreadScheduler(napi_env env);
203     void PostMainThreadTask(Task&& localTask, std::string traceInfo = "Unnamed", int64_t delayTime = 0);
204 
205 private:
206     void GetMainEventHandler();
207     napi_env env_;
208     std::shared_ptr<int> envChecker_;
209     std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler_;
210 };
211 } // namespace OHOS::Rosen
212 #endif // OHOS_WINDOW_SCENE_JS_SCENE_UTILS_H
213