1 /*
2 * Copyright (c) 2023-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 #include "js_pip_utils.h"
17
18 #include <string>
19 #include "window.h"
20 #include "wm_common.h"
21 #include "window_manager_hilog.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 using namespace AbilityRuntime;
26 namespace {
27 constexpr float MAX_PIP_SCALE = 1.0f;
28 }
NapiGetUndefined(napi_env env)29 napi_value NapiGetUndefined(napi_env env)
30 {
31 napi_value result = nullptr;
32 napi_get_undefined(env, &result);
33 return result;
34 }
35
NapiThrowInvalidParam(napi_env env,std::string msg)36 napi_value NapiThrowInvalidParam(napi_env env, std::string msg)
37 {
38 napi_throw(env, AbilityRuntime::CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM), msg));
39 return NapiGetUndefined(env);
40 }
41
NapiIsCallable(napi_env env,napi_value value)42 bool NapiIsCallable(napi_env env, napi_value value)
43 {
44 bool result = false;
45 napi_is_callable(env, value, &result);
46 return result;
47 }
48
GetType(napi_env env,napi_value value)49 napi_valuetype GetType(napi_env env, napi_value value)
50 {
51 napi_valuetype res = napi_undefined;
52 napi_typeof(env, value, &res);
53 return res;
54 }
55
SetNamedProperty(napi_env env,napi_value & obj,const std::string & name,int32_t value)56 static napi_status SetNamedProperty(napi_env env, napi_value& obj, const std::string& name, int32_t value)
57 {
58 napi_value property = nullptr;
59 napi_status status = napi_create_int32(env, value, &property);
60 if (status != napi_ok) {
61 return status;
62 }
63 status = napi_set_named_property(env, obj, name.c_str(), property);
64 if (status != napi_ok) {
65 return status;
66 }
67 return status;
68 }
69
ExportPictureInPictureTemplateType(napi_env env)70 static napi_value ExportPictureInPictureTemplateType(napi_env env)
71 {
72 napi_value result = nullptr;
73 napi_create_object(env, &result);
74 if (result == nullptr) {
75 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
76 return nullptr;
77 }
78 (void)SetNamedProperty(env, result, "VIDEO_PLAY", static_cast<int32_t>(PiPTemplateType::VIDEO_PLAY));
79 (void)SetNamedProperty(env, result, "VIDEO_CALL", static_cast<int32_t>(PiPTemplateType::VIDEO_CALL));
80 (void)SetNamedProperty(env, result, "VIDEO_MEETING", static_cast<int32_t>(PiPTemplateType::VIDEO_MEETING));
81 (void)SetNamedProperty(env, result, "VIDEO_LIVE", static_cast<int32_t>(PiPTemplateType::VIDEO_LIVE));
82 napi_object_freeze(env, result);
83 return result;
84 }
85
ExportPictureInPictureState(napi_env env)86 static napi_value ExportPictureInPictureState(napi_env env)
87 {
88 napi_value result = nullptr;
89 napi_create_object(env, &result);
90 if (result == nullptr) {
91 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
92 return nullptr;
93 }
94 (void)SetNamedProperty(env, result, "ABOUT_TO_START", static_cast<int32_t>(PiPState::ABOUT_TO_START));
95 (void)SetNamedProperty(env, result, "STARTED", static_cast<int32_t>(PiPState::STARTED));
96 (void)SetNamedProperty(env, result, "ABOUT_TO_STOP", static_cast<int32_t>(PiPState::ABOUT_TO_STOP));
97 (void)SetNamedProperty(env, result, "STOPPED", static_cast<int32_t>(PiPState::STOPPED));
98 (void)SetNamedProperty(env, result, "ABOUT_TO_RESTORE", static_cast<int32_t>(PiPState::ABOUT_TO_RESTORE));
99 (void)SetNamedProperty(env, result, "ERROR", static_cast<int32_t>(PiPState::ERROR));
100 napi_object_freeze(env, result);
101 return result;
102 }
103
ExportVideoPlayControlGroup(napi_env env)104 static napi_value ExportVideoPlayControlGroup(napi_env env)
105 {
106 napi_value result = nullptr;
107 napi_create_object(env, &result);
108 if (result == nullptr) {
109 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
110 return nullptr;
111 }
112 (void)SetNamedProperty(env, result, "VIDEO_PREVIOUS_NEXT",
113 static_cast<uint32_t>(PiPControlGroup::VIDEO_PREVIOUS_NEXT));
114 (void)SetNamedProperty(env, result, "FAST_FORWARD_BACKWARD",
115 static_cast<uint32_t>(PiPControlGroup::FAST_FORWARD_BACKWARD));
116 napi_object_freeze(env, result);
117 return result;
118 }
119
ExportVideoCallControlGroup(napi_env env)120 static napi_value ExportVideoCallControlGroup(napi_env env)
121 {
122 napi_value result = nullptr;
123 napi_create_object(env, &result);
124 if (result == nullptr) {
125 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
126 return nullptr;
127 }
128 (void)SetNamedProperty(env, result, "MICROPHONE_SWITCH",
129 static_cast<uint32_t>(PiPControlGroup::VIDEO_CALL_MICROPHONE_SWITCH));
130 (void)SetNamedProperty(env, result, "HANG_UP_BUTTON",
131 static_cast<uint32_t>(PiPControlGroup::VIDEO_CALL_HANG_UP_BUTTON));
132 (void)SetNamedProperty(env, result, "CAMERA_SWITCH",
133 static_cast<uint32_t>(PiPControlGroup::VIDEO_CALL_CAMERA_SWITCH));
134 (void)SetNamedProperty(env, result, "MUTE_SWITCH",
135 static_cast<uint32_t>(PiPControlGroup::VIDEO_CALL_MUTE_SWITCH));
136 napi_object_freeze(env, result);
137 return result;
138 }
139
ExportVideoMeetingControlGroup(napi_env env)140 static napi_value ExportVideoMeetingControlGroup(napi_env env)
141 {
142 napi_value result = nullptr;
143 napi_create_object(env, &result);
144 if (result == nullptr) {
145 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
146 return nullptr;
147 }
148 (void)SetNamedProperty(env, result, "HANG_UP_BUTTON",
149 static_cast<uint32_t>(PiPControlGroup::VIDEO_MEETING_HANG_UP_BUTTON));
150 (void)SetNamedProperty(env, result, "CAMERA_SWITCH",
151 static_cast<uint32_t>(PiPControlGroup::VIDEO_MEETING_CAMERA_SWITCH));
152 (void)SetNamedProperty(env, result, "MUTE_SWITCH",
153 static_cast<uint32_t>(PiPControlGroup::VIDEO_MEETING_MUTE_SWITCH));
154 (void)SetNamedProperty(env, result, "MICROPHONE_SWITCH",
155 static_cast<uint32_t>(PiPControlGroup::VIDEO_MEETING_MICROPHONE_SWITCH));
156 napi_object_freeze(env, result);
157 return result;
158 }
159
ExportVideoLiveControlGroup(napi_env env)160 static napi_value ExportVideoLiveControlGroup(napi_env env)
161 {
162 napi_value result = nullptr;
163 napi_create_object(env, &result);
164 if (result == nullptr) {
165 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
166 return nullptr;
167 }
168 (void)SetNamedProperty(env, result, "VIDEO_PLAY_PAUSE",
169 static_cast<uint32_t>(PiPControlGroup::VIDEO_PLAY_PAUSE));
170 (void)SetNamedProperty(env, result, "MUTE_SWITCH",
171 static_cast<uint32_t>(PiPControlGroup::VIDEO_LIVE_MUTE_SWITCH));
172 napi_object_freeze(env, result);
173 return result;
174 }
175
ExportControlStatus(napi_env env)176 static napi_value ExportControlStatus(napi_env env)
177 {
178 napi_value result = nullptr;
179 napi_create_object(env, &result);
180 if (result == nullptr) {
181 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
182 return nullptr;
183 }
184 (void)SetNamedProperty(env, result, "PLAY",
185 static_cast<int32_t>(PiPControlStatus::PLAY));
186 (void)SetNamedProperty(env, result, "PAUSE",
187 static_cast<int32_t>(PiPControlStatus::PAUSE));
188 (void)SetNamedProperty(env, result, "OPEN",
189 static_cast<int32_t>(PiPControlStatus::OPEN));
190 (void)SetNamedProperty(env, result, "CLOSE",
191 static_cast<int32_t>(PiPControlStatus::CLOSE));
192 (void)SetNamedProperty(env, result, "ENABLED",
193 static_cast<int32_t>(PiPControlStatus::ENABLED));
194 (void)SetNamedProperty(env, result, "DISABLED",
195 static_cast<int32_t>(PiPControlStatus::DISABLED));
196 napi_object_freeze(env, result);
197 return result;
198 }
199
ExportControlType(napi_env env)200 static napi_value ExportControlType(napi_env env)
201 {
202 napi_value result = nullptr;
203 napi_create_object(env, &result);
204 if (result == nullptr) {
205 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
206 return nullptr;
207 }
208 (void)SetNamedProperty(env, result, "VIDEO_PLAY_PAUSE",
209 static_cast<uint32_t>(PiPControlType::VIDEO_PLAY_PAUSE));
210 (void)SetNamedProperty(env, result, "VIDEO_PREVIOUS",
211 static_cast<uint32_t>(PiPControlType::VIDEO_PREVIOUS));
212 (void)SetNamedProperty(env, result, "VIDEO_NEXT",
213 static_cast<uint32_t>(PiPControlType::VIDEO_NEXT));
214 (void)SetNamedProperty(env, result, "FAST_FORWARD",
215 static_cast<uint32_t>(PiPControlType::FAST_FORWARD));
216 (void)SetNamedProperty(env, result, "FAST_BACKWARD",
217 static_cast<uint32_t>(PiPControlType::FAST_BACKWARD));
218 (void)SetNamedProperty(env, result, "HANG_UP_BUTTON",
219 static_cast<uint32_t>(PiPControlType::HANG_UP_BUTTON));
220 (void)SetNamedProperty(env, result, "MICROPHONE_SWITCH",
221 static_cast<uint32_t>(PiPControlType::MICROPHONE_SWITCH));
222 (void)SetNamedProperty(env, result, "CAMERA_SWITCH",
223 static_cast<uint32_t>(PiPControlType::CAMERA_SWITCH));
224 (void)SetNamedProperty(env, result, "MUTE_SWITCH",
225 static_cast<uint32_t>(PiPControlType::MUTE_SWITCH));
226 napi_object_freeze(env, result);
227 return result;
228 }
229
InitEnums(napi_env env,napi_value exports)230 napi_status InitEnums(napi_env env, napi_value exports)
231 {
232 const napi_property_descriptor properties[] = {
233 DECLARE_NAPI_PROPERTY("PiPTemplateType", ExportPictureInPictureTemplateType(env)),
234 DECLARE_NAPI_PROPERTY("PiPState", ExportPictureInPictureState(env)),
235 DECLARE_NAPI_PROPERTY("VideoPlayControlGroup", ExportVideoPlayControlGroup(env)),
236 DECLARE_NAPI_PROPERTY("VideoCallControlGroup", ExportVideoCallControlGroup(env)),
237 DECLARE_NAPI_PROPERTY("VideoMeetingControlGroup", ExportVideoMeetingControlGroup(env)),
238 DECLARE_NAPI_PROPERTY("PiPControlType", ExportControlType(env)),
239 DECLARE_NAPI_PROPERTY("PiPControlStatus", ExportControlStatus(env)),
240 DECLARE_NAPI_PROPERTY("VideoLiveControlGroup", ExportVideoLiveControlGroup(env)),
241 };
242 size_t count = sizeof(properties) / sizeof(napi_property_descriptor);
243 return napi_define_properties(env, exports, count, properties);
244 }
245
GetPiPWindowSizeAndConvertToJsValue(napi_env env,const Rect & rect,float scale)246 napi_value GetPiPWindowSizeAndConvertToJsValue(napi_env env, const Rect& rect, float scale)
247 {
248 napi_value objValue = nullptr;
249 napi_create_object(env, &objValue);
250 if (objValue == nullptr) {
251 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
252 return nullptr;
253 }
254 napi_set_named_property(env, objValue, "width", CreateJsValue(env, rect.width_));
255 napi_set_named_property(env, objValue, "height", CreateJsValue(env, rect.height_));
256 napi_set_named_property(env, objValue, "scale", CreateJsValue(env, scale));
257 return objValue;
258 }
259
CreateJsPiPWindowInfoObject(napi_env env,const sptr<Window> & window)260 napi_value CreateJsPiPWindowInfoObject(napi_env env, const sptr<Window>& window)
261 {
262 napi_value objValue = nullptr;
263 napi_create_object(env, &objValue);
264 if (objValue == nullptr) {
265 TLOGE(WmsLogTag::WMS_PIP, "Failed to get object");
266 return nullptr;
267 }
268 if (window == nullptr) {
269 TLOGE(WmsLogTag::WMS_PIP, "window is nullptr");
270 return nullptr;
271 }
272 const auto& windowRect = window->GetRect();
273 const auto& layoutTransform = window->GetLayoutTransform();
274 float maxScale = std::min(std::max(layoutTransform.scaleX_, layoutTransform.scaleY_), MAX_PIP_SCALE);
275 napi_value pipWindowSizeObj = GetPiPWindowSizeAndConvertToJsValue(env, windowRect, maxScale);
276 if (pipWindowSizeObj == nullptr) {
277 TLOGE(WmsLogTag::WMS_PIP, "Get window size failed!");
278 return nullptr;
279 }
280 napi_set_named_property(env, objValue, "windowId", CreateJsValue(env, window->GetWindowId()));
281 napi_set_named_property(env, objValue, "size", pipWindowSizeObj);
282 return objValue;
283 }
284 } // Rosen
285 } // OHOS