1 /*
2 * Copyright (c) 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
16 #include "js_display.h"
17
18 #include <cinttypes>
19 #include <hitrace_meter.h>
20 #include <map>
21 #include <set>
22
23 #include "cutout_info.h"
24 #include "display.h"
25 #include "display_info.h"
26 #include "window_manager_hilog.h"
27 #include "display_manager.h"
28 #include "singleton_container.h"
29
30 namespace OHOS {
31 namespace Rosen {
32 using namespace AbilityRuntime;
33 constexpr size_t ARGC_ONE = 1;
34 constexpr size_t ARGC_TWO = 2;
35 constexpr int32_t INDEX_ONE = 1;
36 namespace {
37 const std::map<DisplayState, DisplayStateMode> NATIVE_TO_JS_DISPLAY_STATE_MAP {
38 { DisplayState::UNKNOWN, DisplayStateMode::STATE_UNKNOWN },
39 { DisplayState::OFF, DisplayStateMode::STATE_OFF },
40 { DisplayState::ON, DisplayStateMode::STATE_ON },
41 { DisplayState::DOZE, DisplayStateMode::STATE_DOZE },
42 { DisplayState::DOZE_SUSPEND, DisplayStateMode::STATE_DOZE_SUSPEND },
43 { DisplayState::VR, DisplayStateMode::STATE_VR },
44 { DisplayState::ON_SUSPEND, DisplayStateMode::STATE_ON_SUSPEND },
45 };
46
47 using GraphicCM_ColorSpaceType = enum {
48 GRAPHIC_CM_COLORSPACE_NONE,
49
50 GRAPHIC_CM_BT601_EBU_FULL = 2 | (1 << 8) | (2 << 16) | (1 << 21), // COLORPRIMARIES_BT601_P | (TRANSFUNC_BT709 << 8) | (MATRIX_BT601_P << 16) | (RANGE_FULL << 21)
51 GRAPHIC_CM_BT601_SMPTE_C_FULL = 3 | (1 << 8) | (3 << 16) | (1 << 21), // COLORPRIMARIES_BT601_N | (TRANSFUNC_BT709 << 8) | (MATRIX_BT601_N << 16) | (RANGE_FULL << 21)
52 GRAPHIC_CM_BT709_FULL = 1 | (1 << 8) | (1 << 16) | (1 << 21), // COLORPRIMARIES_BT709 | (TRANSFUNC_BT709 << 8) | (MATRIX_BT709 << 16) | (RANGE_FULL << 21)
53 GRAPHIC_CM_BT2020_HLG_FULL = 4 | (5 << 8) | (4 << 16) | (1 << 21), // COLORPRIMARIES_BT2020 | (TRANSFUNC_HLG << 8) | (MATRIX_BT2020 << 16) | (RANGE_FULL << 21)
54 GRAPHIC_CM_BT2020_PQ_FULL = 4 | (4 << 8) | (4 << 16) | (1 << 21), // COLORPRIMARIES_BT2020 | (TRANSFUNC_PQ << 8) | (MATRIX_BT2020 << 16) | (RANGE_FULL << 21)
55
56 GRAPHIC_CM_BT601_EBU_LIMIT = 2 | (1 << 8) | (2 << 16) | (2 << 21), // COLORPRIMARIES_BT601_P | (TRANSFUNC_BT709 << 8) | (MATRIX_BT601_P << 16) | (RANGE_LIMITED << 21)
57 GRAPHIC_CM_BT601_SMPTE_C_LIMIT = 3 | (1 << 8) | (3 << 16) | (2 << 21), // COLORPRIMARIES_BT601_N | (TRANSFUNC_BT709 << 8) | (MATRIX_BT601_N << 16) | (RANGE_LIMITED << 21)
58 GRAPHIC_CM_BT709_LIMIT = 1 | (1 << 8) | (1 << 16) | (2 << 21), // COLORPRIMARIES_BT709 | (TRANSFUNC_BT709 << 8) | (MATRIX_BT709 << 16) | (RANGE_LIMITED << 21)
59 GRAPHIC_CM_BT2020_HLG_LIMIT = 4 | (5 << 8) | (4 << 16) | (2 << 21), // COLORPRIMARIES_BT2020 | (TRANSFUNC_HLG << 8) | (MATRIX_BT2020 << 16) | (RANGE_LIMITED << 21)
60 GRAPHIC_CM_BT2020_PQ_LIMIT = 4 | (4 << 8) | (4 << 16) | (2 << 21), // COLORPRIMARIES_BT2020 | (TRANSFUNC_PQ << 8) | (MATRIX_BT2020 << 16) | (RANGE_LIMITED << 21)
61
62 GRAPHIC_CM_SRGB_FULL = 1 | (2 << 8) | (3 << 16) | (1 << 21), // COLORPRIMARIES_SRGB | (TRANSFUNC_SRGB << 8) | (MATRIX_BT601_N << 16) | (RANGE_FULL << 21)
63 GRAPHIC_CM_P3_FULL = 6 | (2 << 8) | (3 << 16) | (1 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_SRGB << 8) | (MATRIX_P3 << 16) | (RANGE_FULL << 21)
64 GRAPHIC_CM_P3_HLG_FULL = 6 | (5 << 8) | (3 << 16) | (1 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_HLG << 8) | (MATRIX_P3 << 16) | (RANGE_FULL << 21)
65 GRAPHIC_CM_P3_PQ_FULL = 6 | (4 << 8) | (3 << 16) | (1 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_PQ << 8) | (MATRIX_P3 << 16) | (RANGE_FULL << 21)
66 GRAPHIC_CM_ADOBERGB_FULL = 23 | (6 << 8) | (0 << 16) | (1 << 21), // COLORPRIMARIES_ADOBERGB | (TRANSFUNC_ADOBERGB << 8) | (MATRIX_ADOBERGB << 16) | (RANGE_FULL << 21)
67
68 GRAPHIC_CM_SRGB_LIMIT = 1 | (2 << 8) | (3 << 16) | (2 << 21), // COLORPRIMARIES_SRGB | (TRANSFUNC_SRGB << 8) | (MATRIX_BT601_N << 16) | (RANGE_LIMITED << 21)
69 GRAPHIC_CM_P3_LIMIT = 6 | (2 << 8) | (3 << 16) | (2 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_SRGB << 8) | (MATRIX_P3 << 16) | (RANGE_LIMITED << 21)
70 GRAPHIC_CM_P3_HLG_LIMIT = 6 | (5 << 8) | (3 << 16) | (2 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_HLG << 8) | (MATRIX_P3 << 16) | (RANGE_LIMITED << 21)
71 GRAPHIC_CM_P3_PQ_LIMIT = 6 | (4 << 8) | (3 << 16) | (2 << 21), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_PQ << 8) | (MATRIX_P3 << 16) | (RANGE_LIMITED << 21)
72 GRAPHIC_CM_ADOBERGB_LIMIT = 23 | (6 << 8) | (0 << 16) | (2 << 21), // COLORPRIMARIES_ADOBERGB | (TRANSFUNC_ADOBERGB << 8) | (MATRIX_ADOBERGB << 16) | (RANGE_LIMITED << 21)
73
74 GRAPHIC_CM_LINEAR_SRGB = 1 | (3 << 8), // COLORPRIMARIES_SRGB | (TRANSFUNC_LINEAR << 8)
75 GRAPHIC_CM_LINEAR_BT709 = 1 | (3 << 8), // equal to GRAPHIC_CM_LINEAR_SRGB
76 GRAPHIC_CM_LINEAR_P3 = 6 | (3 << 8), // COLORPRIMARIES_P3_D65 | (TRANSFUNC_LINEAR << 8)
77 GRAPHIC_CM_LINEAR_BT2020 = 4 | (3 << 8), // COLORPRIMARIES_BT2020 | (TRANSFUNC_LINEAR << 8)
78
79 GRAPHIC_CM_DISPLAY_SRGB = 1 | (2 << 8) | (3 << 16) | (1 << 21), // equal to GRAPHIC_CM_SRGB_FULL
80 GRAPHIC_CM_DISPLAY_P3_SRGB = 6 | (2 << 8) | (3 << 16) | (1 << 21), // equal to GRAPHIC_CM_P3_FULL
81 GRAPHIC_CM_DISPLAY_P3_HLG = 6 | (5 << 8) | (3 << 16) | (1 << 21), // equal to GRAPHIC_CM_P3_HLG_FULL
82 GRAPHIC_CM_DISPLAY_P3_PQ = 6 | (4 << 8) | (3 << 16) | (1 << 21), // equal to GRAPHIC_CM_P3_PQ_FULL
83 GRAPHIC_CM_DISPLAY_BT2020_SRGB = 4 | (2 << 8) | (4 << 16) | (1 << 21), // COLORPRIMARIES_BT2020 | (TRANSFUNC_SRGB << 8) | (MATRIX_BT2020 << 16) | (RANGE_FULL << 21)
84 GRAPHIC_CM_DISPLAY_BT2020_HLG = 4 | (5 << 8) | (4 << 16) | (1 << 21), // equal to GRAPHIC_CM_BT2020_HLG_FULL
85 GRAPHIC_CM_DISPLAY_BT2020_PQ = 4 | (4 << 8) | (4 << 16) | (1 << 21) // equal to GRAPHIC_CM_BT2020_PQ_FULL
86 };
87
88 typedef enum : uint32_t {
89 NOT_SUPPORT_HDR = 0,
90 VIDEO_HLG,
91 VIDEO_HDR10,
92 VIDEO_HDR_VIVID,
93 IMAGE_HDR_VIVID_DUAL,
94 IMAGE_HDR_VIVID_SINGLE,
95 IMAGE_HDR_ISO_DUAL,
96 IMAGE_HDR_ISO_SINGLE,
97 } ScreenHDRFormat;
98
99 const std::map<GraphicCM_ColorSpaceType, DmsColorSpace> NATIVE_TO_JS_COLOR_SPACE_TYPE_MAP {
100 { GraphicCM_ColorSpaceType::GRAPHIC_CM_COLORSPACE_NONE, DmsColorSpace::UNKNOWN },
101 { GraphicCM_ColorSpaceType::GRAPHIC_CM_ADOBERGB_FULL, DmsColorSpace::ADOBE_RGB },
102 { GraphicCM_ColorSpaceType::GRAPHIC_CM_ADOBERGB_LIMIT, DmsColorSpace::ADOBE_RGB },
103 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT2020_HLG_FULL, DmsColorSpace::BT2020_HLG },
104 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT2020_HLG_LIMIT, DmsColorSpace::BT2020_HLG },
105 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_BT2020_HLG, DmsColorSpace::BT2020_HLG },
106 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT2020_PQ_FULL, DmsColorSpace::BT2020_PQ },
107 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT2020_PQ_LIMIT, DmsColorSpace::BT2020_PQ },
108 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_BT2020_PQ, DmsColorSpace::BT2020_PQ },
109 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT601_EBU_FULL, DmsColorSpace::BT601_EBU },
110 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT601_EBU_LIMIT, DmsColorSpace::BT601_EBU },
111 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT601_SMPTE_C_FULL, DmsColorSpace::BT601_SMPTE_C },
112 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT601_SMPTE_C_LIMIT, DmsColorSpace::BT601_SMPTE_C },
113 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT709_FULL, DmsColorSpace::BT709 },
114 { GraphicCM_ColorSpaceType::GRAPHIC_CM_BT709_LIMIT, DmsColorSpace::BT709 },
115 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_HLG_FULL, DmsColorSpace::P3_HLG },
116 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_HLG_LIMIT, DmsColorSpace::P3_HLG },
117 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_P3_HLG, DmsColorSpace::P3_HLG },
118 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_PQ_FULL, DmsColorSpace::P3_PQ },
119 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_PQ_LIMIT, DmsColorSpace::P3_PQ },
120 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_P3_PQ, DmsColorSpace::P3_PQ },
121 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_FULL, DmsColorSpace::DISPLAY_P3 },
122 { GraphicCM_ColorSpaceType::GRAPHIC_CM_P3_LIMIT, DmsColorSpace::DISPLAY_P3 },
123 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_P3_SRGB, DmsColorSpace::DISPLAY_P3 },
124 { GraphicCM_ColorSpaceType::GRAPHIC_CM_SRGB_FULL, DmsColorSpace::SRGB },
125 { GraphicCM_ColorSpaceType::GRAPHIC_CM_SRGB_LIMIT, DmsColorSpace::SRGB },
126 { GraphicCM_ColorSpaceType::GRAPHIC_CM_DISPLAY_SRGB, DmsColorSpace::SRGB },
127 { GraphicCM_ColorSpaceType::GRAPHIC_CM_LINEAR_SRGB, DmsColorSpace::LINEAR_SRGB },
128 { GraphicCM_ColorSpaceType::GRAPHIC_CM_LINEAR_BT709, DmsColorSpace::LINEAR_SRGB },
129 { GraphicCM_ColorSpaceType::GRAPHIC_CM_LINEAR_P3, DmsColorSpace::LINEAR_P3 },
130 { GraphicCM_ColorSpaceType::GRAPHIC_CM_LINEAR_BT2020, DmsColorSpace::LINEAR_BT2020 },
131 };
132
133 const std::map<ScreenHDRFormat, HDRFormat> NATIVE_TO_JS_HDR_FORMAT_TYPE_MAP {
134 { ScreenHDRFormat::NOT_SUPPORT_HDR, HDRFormat::NONE },
135 { ScreenHDRFormat::VIDEO_HLG, HDRFormat::VIDEO_HLG },
136 { ScreenHDRFormat::VIDEO_HDR10, HDRFormat::VIDEO_HDR10 },
137 { ScreenHDRFormat::VIDEO_HDR_VIVID, HDRFormat::VIDEO_HDR_VIVID },
138 { ScreenHDRFormat::IMAGE_HDR_VIVID_DUAL, HDRFormat::IMAGE_HDR_VIVID_DUAL },
139 { ScreenHDRFormat::IMAGE_HDR_VIVID_SINGLE, HDRFormat::IMAGE_HDR_VIVID_SINGLE },
140 { ScreenHDRFormat::IMAGE_HDR_ISO_DUAL, HDRFormat::IMAGE_HDR_ISO_DUAL },
141 { ScreenHDRFormat::IMAGE_HDR_ISO_SINGLE, HDRFormat::IMAGE_HDR_ISO_SINGLE },
142 };
143 }
144
145 static thread_local std::map<DisplayId, std::shared_ptr<NativeReference>> g_JsDisplayMap;
146 std::recursive_mutex g_mutex;
147
JsDisplay(const sptr<Display> & display)148 JsDisplay::JsDisplay(const sptr<Display>& display) : display_(display)
149 {
150 }
151
~JsDisplay()152 JsDisplay::~JsDisplay()
153 {
154 TLOGI(WmsLogTag::DMS, "JsDisplay::~JsDisplay is called");
155 }
156
Finalizer(napi_env env,void * data,void * hint)157 void JsDisplay::Finalizer(napi_env env, void* data, void* hint)
158 {
159 TLOGI(WmsLogTag::DMS, "called");
160 auto jsDisplay = std::unique_ptr<JsDisplay>(static_cast<JsDisplay*>(data));
161 if (jsDisplay == nullptr) {
162 TLOGE(WmsLogTag::DMS, "jsDisplay is null");
163 return;
164 }
165 sptr<Display> display = jsDisplay->display_;
166 if (display == nullptr) {
167 TLOGE(WmsLogTag::DMS, "display is null");
168 return;
169 }
170 DisplayId displayId = display->GetId();
171 TLOGI(WmsLogTag::DMS, "displayId : %{public}" PRIu64"", displayId);
172 std::lock_guard<std::recursive_mutex> lock(g_mutex);
173 if (g_JsDisplayMap.find(displayId) != g_JsDisplayMap.end()) {
174 TLOGI(WmsLogTag::DMS, "Display is destroyed: %{public}" PRIu64"", displayId);
175 g_JsDisplayMap.erase(displayId);
176 }
177 }
178
GetCutoutInfo(napi_env env,napi_callback_info info)179 napi_value JsDisplay::GetCutoutInfo(napi_env env, napi_callback_info info)
180 {
181 TLOGD(WmsLogTag::DMS, "called");
182 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
183 return (me != nullptr) ? me->OnGetCutoutInfo(env, info) : nullptr;
184 }
185
GetDisplayCapability(napi_env env,napi_callback_info info)186 napi_value JsDisplay::GetDisplayCapability(napi_env env, napi_callback_info info)
187 {
188 TLOGI(WmsLogTag::DMS, "called");
189 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
190 return (me != nullptr) ? me->OnGetDisplayCapability(env, info) : nullptr;
191 }
192
GetAvailableArea(napi_env env,napi_callback_info info)193 napi_value JsDisplay::GetAvailableArea(napi_env env, napi_callback_info info)
194 {
195 TLOGI(WmsLogTag::DMS, "called");
196 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
197 return (me != nullptr) ? me->OnGetAvailableArea(env, info) : nullptr;
198 }
199
RegisterDisplayManagerCallback(napi_env env,napi_callback_info info)200 napi_value JsDisplay::RegisterDisplayManagerCallback(napi_env env, napi_callback_info info)
201 {
202 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
203 return (me != nullptr) ? me->OnRegisterDisplayManagerCallback(env, info) : nullptr;
204 }
205
UnregisterDisplayManagerCallback(napi_env env,napi_callback_info info)206 napi_value JsDisplay::UnregisterDisplayManagerCallback(napi_env env, napi_callback_info info)
207 {
208 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
209 return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(env, info) : nullptr;
210 }
211
GetLiveCreaseRegion(napi_env env,napi_callback_info info)212 napi_value JsDisplay::GetLiveCreaseRegion(napi_env env, napi_callback_info info)
213 {
214 TLOGI(WmsLogTag::DMS, "called");
215 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
216 return (me != nullptr) ? me->OnGetLiveCreaseRegion(env, info) : nullptr;
217 }
218
NapiIsCallable(napi_env env,napi_value value)219 bool NapiIsCallable(napi_env env, napi_value value)
220 {
221 bool result = false;
222 napi_is_callable(env, value, &result);
223 return result;
224 }
225
IsCallbackRegistered(napi_env env,const std::string & type,napi_value jsListenerObject)226 bool JsDisplay::IsCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject)
227 {
228 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
229 TLOGI(WmsLogTag::DMS, "IsCallbackRegistered methodName %{public}s not registered!", type.c_str());
230 return false;
231 }
232
233 for (auto& iter : jsCbMap_[type]) {
234 bool isEquals = false;
235 napi_strict_equals(env, jsListenerObject, iter.first->GetNapiValue(), &isEquals);
236 if (isEquals) {
237 TLOGE(WmsLogTag::DMS, "IsCallbackRegistered callback already registered!");
238 return true;
239 }
240 }
241 return false;
242 }
243
OnRegisterDisplayManagerCallback(napi_env env,napi_callback_info info)244 napi_value JsDisplay::OnRegisterDisplayManagerCallback(napi_env env, napi_callback_info info)
245 {
246 TLOGD(WmsLogTag::DMS, "called");
247 size_t argc = 4;
248 napi_value argv[4] = {nullptr};
249 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
250 if (argc < ARGC_TWO) {
251 TLOGE(WmsLogTag::DMS, "JsDisplayManager Params not match: %{public}zu", argc);
252 std::string errMsg = "Invalid args count, need 2 args";
253 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
254 return NapiGetUndefined(env);
255 }
256 std::string cbType;
257 if (!ConvertFromJsValue(env, argv[0], cbType)) {
258 std::string errMsg = "Failed to convert parameter to callbackType";
259 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
260 TLOGE(WmsLogTag::DMS, "Failed to convert parameter to callbackType");
261 return NapiGetUndefined(env);
262 }
263 napi_value value = argv[INDEX_ONE];
264 if (value == nullptr) {
265 TLOGI(WmsLogTag::DMS, "info->argv[1] is nullptr");
266 std::string errMsg = "OnRegisterDisplayManagerCallback is nullptr";
267 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
268 return NapiGetUndefined(env);
269 }
270 if (!NapiIsCallable(env, value)) {
271 TLOGI(WmsLogTag::DMS, "info->argv[1] is not callable");
272 std::string errMsg = "OnRegisterDisplayManagerCallback is not callable";
273 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
274 return NapiGetUndefined(env);
275 }
276 std::lock_guard<std::mutex> lock(mtx_);
277 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(RegisterDisplayListenerWithType(env, cbType, value));
278 if (ret != DmErrorCode::DM_OK) {
279 TLOGE(WmsLogTag::DMS, "Failed to register display listener with type");
280 std::string errMsg = "Failed to register display listener with type";
281 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
282 return NapiGetUndefined(env);
283 }
284 return NapiGetUndefined(env);
285 }
286
RegisterDisplayListenerWithType(napi_env env,const std::string & type,napi_value value)287 DMError JsDisplay::RegisterDisplayListenerWithType(napi_env env, const std::string& type, napi_value value)
288 {
289 if (IsCallbackRegistered(env, type, value)) {
290 TLOGI(WmsLogTag::DMS, "callback already registered!");
291 return DMError::DM_OK;
292 }
293 std::unique_ptr<NativeReference> callbackRef;
294 napi_ref result = nullptr;
295 napi_create_reference(env, value, 1, &result);
296 callbackRef.reset(reinterpret_cast<NativeReference*>(result));
297 sptr<JsDisplayListener> displayListener = new(std::nothrow) JsDisplayListener(env);
298 DMError ret = DMError::DM_OK;
299 if (displayListener == nullptr) {
300 TLOGE(WmsLogTag::DMS, "displayListener is nullptr");
301 return DMError::DM_ERROR_INVALID_PARAM;
302 }
303 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
304 auto displayId = display_->GetId();
305 ret = SingletonContainer::Get<DisplayManager>().RegisterAvailableAreaListener(displayListener, displayId);
306 } else {
307 TLOGE(WmsLogTag::DMS, "failed, %{public}s not support", type.c_str());
308 return DMError::DM_ERROR_INVALID_PARAM;
309 }
310 if (ret != DMError::DM_OK) {
311 TLOGE(WmsLogTag::DMS, "failed, ret: %{public}u", ret);
312 return ret;
313 }
314 displayListener->AddCallback(type, value);
315 jsCbMap_[type][std::move(callbackRef)] = displayListener;
316 return DMError::DM_OK;
317 }
318
OnUnregisterDisplayManagerCallback(napi_env env,napi_callback_info info)319 napi_value JsDisplay::OnUnregisterDisplayManagerCallback(napi_env env, napi_callback_info info)
320 {
321 TLOGI(WmsLogTag::DMS, "called");
322 size_t argc = 4;
323 napi_value argv[4] = {nullptr};
324 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
325 if (argc < ARGC_ONE) {
326 TLOGE(WmsLogTag::DMS, "JsDisplayManager Params not match %{public}zu", argc);
327 std::string errMsg = "Invalid args count, need one arg at least!";
328 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
329 return NapiGetUndefined(env);
330 }
331 std::string cbType;
332 if (!ConvertFromJsValue(env, argv[0], cbType)) {
333 TLOGE(WmsLogTag::DMS, "Failed to convert parameter to callbackType");
334 std::string errMsg = "Failed to convert parameter to string";
335 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
336 return NapiGetUndefined(env);
337 }
338 std::lock_guard<std::mutex> lock(mtx_);
339 DmErrorCode ret;
340 if (argc == ARGC_ONE) {
341 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
342 } else {
343 napi_value value = argv[INDEX_ONE];
344 if ((value == nullptr) || (!NapiIsCallable(env, value))) {
345 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
346 } else {
347 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(env, cbType, value));
348 }
349 }
350 if (ret != DmErrorCode::DM_OK) {
351 TLOGW(WmsLogTag::DMS, "failed to unregister display listener with type");
352 std::string errMsg = "failed to unregister display listener with type";
353 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
354 return NapiGetUndefined(env);
355 }
356 return NapiGetUndefined(env);
357 }
358
UnregisterAllDisplayListenerWithType(const std::string & type)359 DMError JsDisplay::UnregisterAllDisplayListenerWithType(const std::string& type)
360 {
361 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
362 TLOGI(WmsLogTag::DMS, "methodName %{public}s not registered!",
363 type.c_str());
364 return DMError::DM_OK;
365 }
366 DMError ret = DMError::DM_OK;
367 for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
368 it->second->RemoveAllCallback();
369 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
370 auto displayId = display_->GetId();
371 sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
372 ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener, displayId);
373 } else {
374 ret = DMError::DM_ERROR_INVALID_PARAM;
375 }
376 jsCbMap_[type].erase(it++);
377 TLOGI(WmsLogTag::DMS, "unregister display listener with type %{public}s ret: %{public}u", type.c_str(), ret);
378 }
379 jsCbMap_.erase(type);
380 return ret;
381 }
382
UnRegisterDisplayListenerWithType(napi_env env,const std::string & type,napi_value value)383 DMError JsDisplay::UnRegisterDisplayListenerWithType(napi_env env, const std::string& type, napi_value value)
384 {
385 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
386 TLOGI(WmsLogTag::DMS, "methodName %{public}s not registered!", type.c_str());
387 return DMError::DM_OK;
388 }
389 DMError ret = DMError::DM_OK;
390 for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
391 bool isEquals = false;
392 napi_strict_equals(env, value, it->first->GetNapiValue(), &isEquals);
393 if (isEquals) {
394 it->second->RemoveCallback(env, type, value);
395 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
396 auto displayId = display_->GetId();
397 sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
398 ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener,
399 displayId);
400 } else {
401 ret = DMError::DM_ERROR_INVALID_PARAM;
402 }
403 jsCbMap_[type].erase(it++);
404 TLOGI(WmsLogTag::DMS, "unregister display listener with type %{public}s ret: %{public}u", type.c_str(),
405 ret);
406 break;
407 } else {
408 it++;
409 }
410 }
411 if (jsCbMap_[type].empty()) {
412 jsCbMap_.erase(type);
413 }
414 return ret;
415 }
416
HasImmersiveWindow(napi_env env,napi_callback_info info)417 napi_value JsDisplay::HasImmersiveWindow(napi_env env, napi_callback_info info)
418 {
419 TLOGI(WmsLogTag::DMS, "called");
420 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
421 return (me != nullptr) ? me->OnHasImmersiveWindow(env, info) : nullptr;
422 }
423
GetType(napi_env env,napi_value value)424 napi_valuetype GetType(napi_env env, napi_value value)
425 {
426 napi_valuetype res = napi_undefined;
427 napi_typeof(env, value, &res);
428 return res;
429 }
430
OnGetCutoutInfo(napi_env env,napi_callback_info info)431 napi_value JsDisplay::OnGetCutoutInfo(napi_env env, napi_callback_info info)
432 {
433 TLOGD(WmsLogTag::DMS, "called");
434 napi_value result = nullptr;
435 size_t argc = 4;
436 napi_value argv[4] = {nullptr};
437 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
438 napi_value lastParam = nullptr;
439 if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr && GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
440 lastParam = argv[ARGC_ONE - 1];
441 }
442 std::unique_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
443 auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
444 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsDisplay::OnGetCutoutInfo");
445 sptr<CutoutInfo> cutoutInfo = display_->GetCutoutInfo();
446 if (cutoutInfo != nullptr) {
447 task->Resolve(env, CreateJsCutoutInfoObject(env, cutoutInfo));
448 TLOGND(WmsLogTag::DMS, "JsDisplay::OnGetCutoutInfo success");
449 } else {
450 task->Reject(env, CreateJsError(env,
451 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "JsDisplay::OnGetCutoutInfo failed."));
452 }
453 delete task;
454 };
455 if (napi_send_event(env, asyncTask, napi_eprio_immediate, "OnGetCutoutInfo") != napi_status::napi_ok) {
456 napiAsyncTask->Reject(env, CreateJsError(env,
457 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
458 } else {
459 napiAsyncTask.release();
460 }
461 return result;
462 }
463
CreateEmptyAsyncTask(napi_env env,napi_value lastParam,napi_value * result)464 std::unique_ptr<NapiAsyncTask> JsDisplay::CreateEmptyAsyncTask(napi_env env, napi_value lastParam, napi_value* result)
465 {
466 napi_valuetype type = napi_undefined;
467 napi_typeof(env, lastParam, &type);
468 if (lastParam == nullptr || type != napi_function) {
469 napi_deferred nativeDeferred = nullptr;
470 napi_create_promise(env, &nativeDeferred, result);
471 return std::make_unique<NapiAsyncTask>(nativeDeferred, std::unique_ptr<NapiAsyncTask::ExecuteCallback>(),
472 std::unique_ptr<NapiAsyncTask::CompleteCallback>());
473 } else {
474 napi_get_undefined(env, result);
475 napi_ref callbackRef = nullptr;
476 napi_create_reference(env, lastParam, 1, &callbackRef);
477 return std::make_unique<NapiAsyncTask>(callbackRef, std::unique_ptr<NapiAsyncTask::ExecuteCallback>(),
478 std::unique_ptr<NapiAsyncTask::CompleteCallback>());
479 }
480 }
481
OnGetAvailableArea(napi_env env,napi_callback_info info)482 napi_value JsDisplay::OnGetAvailableArea(napi_env env, napi_callback_info info)
483 {
484 TLOGI(WmsLogTag::DMS, "called");
485 size_t argc = 4;
486 napi_value argv[4] = {nullptr};
487 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
488 napi_value lastParam = nullptr;
489 if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
490 GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
491 lastParam = argv[ARGC_ONE - 1];
492 }
493 napi_value result = nullptr;
494 std::unique_ptr<NapiAsyncTask> napiAsyncTask = JsDisplay::CreateEmptyAsyncTask(env, lastParam, &result);
495 auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
496 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsDisplay::OnGetAvailableArea");
497 DMRect area;
498 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetAvailableArea(area));
499 if (ret == DmErrorCode::DM_OK) {
500 task->Resolve(env, CreateJsRectObject(env, area));
501 TLOGNI(WmsLogTag::DMS, "JsDisplay::OnGetAvailableArea success");
502 } else {
503 task->Reject(env, CreateJsError(env, static_cast<int32_t>(ret),
504 "JsDisplay::OnGetAvailableArea failed."));
505 }
506 delete task;
507 };
508 if (napi_send_event(env, asyncTask, napi_eprio_immediate, "OnGetAvailableArea") != napi_status::napi_ok) {
509 napiAsyncTask->Reject(env, CreateJsError(env,
510 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
511 } else {
512 napiAsyncTask.release();
513 }
514 return result;
515 }
516
OnGetDisplayCapability(napi_env env,napi_callback_info info)517 napi_value JsDisplay::OnGetDisplayCapability(napi_env env, napi_callback_info info)
518 {
519 TLOGI(WmsLogTag::DMS, "called");
520 size_t argc = 4;
521 napi_value argv[4] = {nullptr};
522 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
523 std::string capabilitInfo;
524 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetDisplayCapability(capabilitInfo));
525 if (ret == DmErrorCode::DM_OK) {
526 TLOGI(WmsLogTag::DMS, "success, displayCapability = %{public}s", capabilitInfo.c_str());
527 } else {
528 napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
529 TLOGE(WmsLogTag::DMS, "failed.");
530 }
531 return CreateJsValue(env, capabilitInfo);
532 }
533
OnHasImmersiveWindow(napi_env env,napi_callback_info info)534 napi_value JsDisplay::OnHasImmersiveWindow(napi_env env, napi_callback_info info)
535 {
536 TLOGI(WmsLogTag::DMS, "called");
537 size_t argc = 4;
538 napi_value argv[4] = {nullptr};
539 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
540 napi_value lastParam = nullptr;
541 if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
542 GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
543 lastParam = argv[ARGC_ONE - 1];
544 }
545 napi_value result = nullptr;
546 std::unique_ptr<NapiAsyncTask> napiAsyncTask = JsDisplay::CreateEmptyAsyncTask(env, lastParam, &result);
547 auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
548 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsDisplay::OnHasImmersiveWindow");
549 bool immersive = false;
550 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->HasImmersiveWindow(immersive));
551 if (ret == DmErrorCode::DM_OK) {
552 task->Resolve(env, CreateJsValue(env, immersive));
553 TLOGNI(WmsLogTag::DMS, "JsDisplay::OnHasImmersiveWindow success - immersive window exists: %{public}d",
554 immersive);
555 } else {
556 task->Reject(env, CreateJsError(env,
557 static_cast<int32_t>(ret), "JsDisplay::OnHasImmersiveWindow failed."));
558 }
559 delete task;
560 };
561 if (napi_send_event(env, asyncTask, napi_eprio_immediate, "OnHasImmersiveWindow") != napi_status::napi_ok) {
562 napiAsyncTask->Reject(env, CreateJsError(env,
563 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
564 } else {
565 napiAsyncTask.release();
566 }
567 return result;
568 }
569
OnGetLiveCreaseRegion(napi_env env,napi_callback_info info)570 napi_value JsDisplay::OnGetLiveCreaseRegion(napi_env env, napi_callback_info info)
571 {
572 TLOGI(WmsLogTag::DMS, "called");
573 size_t argc = 4;
574 napi_value argv[4] = {nullptr};
575 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
576 if (argc >= ARGC_ONE) {
577 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
578 return NapiGetUndefined(env);
579 }
580 FoldCreaseRegion region;
581 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetLiveCreaseRegion(region));
582 if (ret != DmErrorCode::DM_OK) {
583 napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
584 return NapiGetUndefined(env);
585 }
586 return CreateJsFoldCreaseRegionObject(env, region);
587 }
588
GetSupportedColorSpaces(napi_env env,napi_callback_info info)589 napi_value JsDisplay::GetSupportedColorSpaces(napi_env env, napi_callback_info info)
590 {
591 TLOGI(WmsLogTag::DMS, "called");
592 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
593 return (me != nullptr) ? me->OnGetSupportedColorSpaces(env, info) : nullptr;
594 }
595
CreateJsColorSpaceArray(napi_env env,const std::vector<uint32_t> & colorSpaces)596 static napi_value CreateJsColorSpaceArray(napi_env env, const std::vector<uint32_t>& colorSpaces)
597 {
598 TLOGD(WmsLogTag::DMS, "called");
599 std::set<uint32_t> nativeColorSpaces;
600 for (const auto colorSpace : colorSpaces) {
601 GraphicCM_ColorSpaceType colorSpaceValue = static_cast<GraphicCM_ColorSpaceType>(colorSpace);
602 if (NATIVE_TO_JS_COLOR_SPACE_TYPE_MAP.count(colorSpaceValue) == 0) {
603 TLOGE(WmsLogTag::DMS, "Get color space name %{public}u, but not in api type", colorSpace);
604 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DMError::DM_ERROR_DEVICE_NOT_SUPPORT)));
605 return NapiGetUndefined(env);
606 }
607 nativeColorSpaces.insert(static_cast<uint32_t>(NATIVE_TO_JS_COLOR_SPACE_TYPE_MAP.at(colorSpaceValue)));
608 }
609 napi_value arrayValue = nullptr;
610 napi_create_array_with_length(env, nativeColorSpaces.size(), &arrayValue);
611 if (arrayValue == nullptr) {
612 TLOGE(WmsLogTag::DMS, "Failed to create color space array");
613 return NapiGetUndefined(env);
614 }
615 uint32_t index = 0;
616 for (const auto nativeColorSpace : nativeColorSpaces) {
617 napi_set_element(env, arrayValue, index++, CreateJsValue(env, nativeColorSpace));
618 }
619 return arrayValue;
620 }
621
OnGetSupportedColorSpaces(napi_env env,napi_callback_info info)622 napi_value JsDisplay::OnGetSupportedColorSpaces(napi_env env, napi_callback_info info)
623 {
624 TLOGI(WmsLogTag::DMS, "called");
625 size_t argc = 4;
626 napi_value argv[4] = {nullptr};
627 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
628 napi_value lastParam = nullptr;
629 if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
630 GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
631 lastParam = argv[ARGC_ONE - 1];
632 }
633 napi_value result = nullptr;
634 std::unique_ptr<NapiAsyncTask> napiAsyncTask = JsDisplay::CreateEmptyAsyncTask(env, lastParam, &result);
635 auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
636 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsDisplay::OnGetSupportedColorSpaces");
637 std::vector<uint32_t> colorSpaces;
638 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetSupportedColorSpaces(colorSpaces));
639 if (ret == DmErrorCode::DM_OK) {
640 task->Resolve(env, CreateJsColorSpaceArray(env, colorSpaces));
641 TLOGNI(WmsLogTag::DMS, "OnGetSupportedColorSpaces success");
642 } else {
643 task->Reject(env, CreateJsError(env, static_cast<int32_t>(ret),
644 "JsDisplay::OnGetSupportedColorSpaces failed."));
645 TLOGNE(WmsLogTag::DMS, "OnGetSupportedColorSpaces failed");
646 }
647 delete task;
648 };
649 if (napi_send_event(env, asyncTask, napi_eprio_immediate, "OnGetSupportedColorSpaces") != napi_status::napi_ok) {
650 napiAsyncTask->Reject(env, CreateJsError(env,
651 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
652 } else {
653 napiAsyncTask.release();
654 }
655 return result;
656 }
657
GetSupportedHDRFormats(napi_env env,napi_callback_info info)658 napi_value JsDisplay::GetSupportedHDRFormats(napi_env env, napi_callback_info info)
659 {
660 TLOGI(WmsLogTag::DMS, "called");
661 JsDisplay* me = CheckParamsAndGetThis<JsDisplay>(env, info);
662 return (me != nullptr) ? me->OnGetSupportedHDRFormats(env, info) : nullptr;
663 }
664
CreateJsHDRFormatArray(napi_env env,const std::vector<uint32_t> & hdrFormats)665 static napi_value CreateJsHDRFormatArray(napi_env env, const std::vector<uint32_t>& hdrFormats)
666 {
667 TLOGD(WmsLogTag::DMS, "called");
668 std::set<uint32_t> nativeHDRFormats;
669 for (const auto hdrFormat : hdrFormats) {
670 ScreenHDRFormat hdrFormatValue = static_cast<ScreenHDRFormat>(hdrFormat);
671 if (NATIVE_TO_JS_HDR_FORMAT_TYPE_MAP.count(hdrFormatValue) == 0) {
672 TLOGE(WmsLogTag::DMS, "Get HDR format name %{public}u, but not in api type", hdrFormat);
673 napi_throw(env, CreateJsError(env, static_cast<int32_t>(DMError::DM_ERROR_DEVICE_NOT_SUPPORT)));
674 return NapiGetUndefined(env);
675 }
676 nativeHDRFormats.insert(static_cast<uint32_t>(NATIVE_TO_JS_HDR_FORMAT_TYPE_MAP.at(hdrFormatValue)));
677 }
678 napi_value arrayValue = nullptr;
679 napi_create_array_with_length(env, hdrFormats.size(), &arrayValue);
680 if (arrayValue == nullptr) {
681 TLOGE(WmsLogTag::DMS, "Failed to create HDR format array");
682 return NapiGetUndefined(env);
683 }
684 uint32_t index = 0;
685 for (const auto nativeHDRFormat : nativeHDRFormats) {
686 napi_set_element(env, arrayValue, index++, CreateJsValue(env, nativeHDRFormat));
687 }
688 return arrayValue;
689 }
690
OnGetSupportedHDRFormats(napi_env env,napi_callback_info info)691 napi_value JsDisplay::OnGetSupportedHDRFormats(napi_env env, napi_callback_info info)
692 {
693 TLOGI(WmsLogTag::DMS, "called");
694 size_t argc = 4;
695 napi_value argv[4] = {nullptr};
696 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
697 napi_value lastParam = nullptr;
698 if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
699 GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
700 lastParam = argv[ARGC_ONE - 1];
701 }
702 napi_value result = nullptr;
703 std::unique_ptr<NapiAsyncTask> napiAsyncTask = JsDisplay::CreateEmptyAsyncTask(env, lastParam, &result);
704 auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
705 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsDisplay::OnGetSupportedHDRFormats");
706 std::vector<uint32_t> hdrFormats;
707 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetSupportedHDRFormats(hdrFormats));
708 if (ret == DmErrorCode::DM_OK) {
709 task->Resolve(env, CreateJsHDRFormatArray(env, hdrFormats));
710 TLOGNI(WmsLogTag::DMS, "OnGetSupportedHDRFormats success");
711 } else {
712 task->Reject(env, CreateJsError(env, static_cast<int32_t>(ret),
713 "JsDisplay::OnGetSupportedHDRFormats failed."));
714 TLOGNE(WmsLogTag::DMS, "OnGetSupportedHDRFormats failed");
715 }
716 delete task;
717 };
718 if (napi_send_event(env, asyncTask, napi_eprio_immediate, "OnGetSupportedHDRFormats") != napi_status::napi_ok) {
719 napiAsyncTask->Reject(env, CreateJsError(env,
720 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
721 } else {
722 napiAsyncTask.release();
723 }
724 return result;
725 }
726
CreateJsSupportedRefreshRateArray(napi_env env,const std::vector<uint32_t> & supportedRefreshRate)727 static napi_value CreateJsSupportedRefreshRateArray(napi_env env, const std::vector<uint32_t>& supportedRefreshRate)
728 {
729 TLOGD(WmsLogTag::DMS, "called");
730 napi_value arrayValue = nullptr;
731 napi_create_array_with_length(env, supportedRefreshRate.size(), &arrayValue);
732 if (arrayValue == nullptr) {
733 TLOGE(WmsLogTag::DMS, "Failed to create supported Refresh Rate array");
734 return NapiGetUndefined(env);
735 }
736 uint32_t index = 0;
737 for (const auto refreshRate : supportedRefreshRate) {
738 napi_set_element(env, arrayValue, index++, CreateJsValue(env, refreshRate));
739 }
740 return arrayValue;
741 }
742
FindJsDisplayObject(DisplayId displayId)743 std::shared_ptr<NativeReference> FindJsDisplayObject(DisplayId displayId)
744 {
745 TLOGD(WmsLogTag::DMS, "[NAPI]Try to find display %{public}" PRIu64" in g_JsDisplayMap", displayId);
746 std::lock_guard<std::recursive_mutex> lock(g_mutex);
747 if (g_JsDisplayMap.find(displayId) == g_JsDisplayMap.end()) {
748 TLOGD(WmsLogTag::DMS, "[NAPI]Can not find display %{public}" PRIu64" in g_JsDisplayMap", displayId);
749 return nullptr;
750 }
751 return g_JsDisplayMap[displayId];
752 }
753
NapiGetUndefined(napi_env env)754 napi_value NapiGetUndefined(napi_env env)
755 {
756 napi_value result = nullptr;
757 napi_get_undefined(env, &result);
758 return result;
759 }
760
CreateJsCutoutInfoObject(napi_env env,sptr<CutoutInfo> cutoutInfo)761 napi_value CreateJsCutoutInfoObject(napi_env env, sptr<CutoutInfo> cutoutInfo)
762 {
763 TLOGD(WmsLogTag::DMS, "called");
764 napi_value objValue = nullptr;
765 napi_create_object(env, &objValue);
766 if (objValue == nullptr) {
767 TLOGE(WmsLogTag::DMS, "Failed to convert prop to jsObject");
768 return NapiGetUndefined(env);
769 }
770 if (cutoutInfo == nullptr) {
771 TLOGE(WmsLogTag::DMS, "Get null cutout info");
772 return NapiGetUndefined(env);
773 }
774 std::vector<DMRect> boundingRects = cutoutInfo->GetBoundingRects();
775 WaterfallDisplayAreaRects waterfallDisplayAreaRects = cutoutInfo->GetWaterfallDisplayAreaRects();
776 napi_set_named_property(env, objValue, "boundingRects", CreateJsBoundingRectsArrayObject(env, boundingRects));
777 napi_set_named_property(env, objValue, "waterfallDisplayAreaRects",
778 CreateJsWaterfallDisplayAreaRectsObject(env, waterfallDisplayAreaRects));
779 return objValue;
780 }
781
CreateJsDisplayPhysicalInfoObject(napi_env env,DisplayPhysicalResolution physicalInfo)782 napi_value CreateJsDisplayPhysicalInfoObject(napi_env env, DisplayPhysicalResolution physicalInfo)
783 {
784 napi_value objValue = nullptr;
785 napi_create_object(env, &objValue);
786 napi_set_named_property(env, objValue, "foldDisplayMode", CreateJsValue(env, physicalInfo.foldDisplayMode_));
787 napi_set_named_property(env, objValue, "physicalWidth", CreateJsValue(env, physicalInfo.physicalWidth_));
788 napi_set_named_property(env, objValue, "physicalHeight", CreateJsValue(env, physicalInfo.physicalHeight_));
789 return objValue;
790 }
791
CreateJsRectObject(napi_env env,DMRect rect)792 napi_value CreateJsRectObject(napi_env env, DMRect rect)
793 {
794 napi_value objValue = nullptr;
795 napi_create_object(env, &objValue);
796 napi_set_named_property(env, objValue, "left", CreateJsValue(env, rect.posX_));
797 napi_set_named_property(env, objValue, "top", CreateJsValue(env, rect.posY_));
798 napi_set_named_property(env, objValue, "width", CreateJsValue(env, rect.width_));
799 napi_set_named_property(env, objValue, "height", CreateJsValue(env, rect.height_));
800 return objValue;
801 }
802
CreateJsWaterfallDisplayAreaRectsObject(napi_env env,WaterfallDisplayAreaRects waterfallDisplayAreaRects)803 napi_value CreateJsWaterfallDisplayAreaRectsObject(napi_env env,
804 WaterfallDisplayAreaRects waterfallDisplayAreaRects)
805 {
806 napi_value objValue = nullptr;
807 napi_create_object(env, &objValue);
808 napi_set_named_property(env, objValue, "left", CreateJsRectObject(env, waterfallDisplayAreaRects.left));
809 napi_set_named_property(env, objValue, "top", CreateJsRectObject(env, waterfallDisplayAreaRects.top));
810 napi_set_named_property(env, objValue, "right", CreateJsRectObject(env, waterfallDisplayAreaRects.right));
811 napi_set_named_property(env, objValue, "bottom", CreateJsRectObject(env, waterfallDisplayAreaRects.bottom));
812 return objValue;
813 }
814
CreateJsBoundingRectsArrayObject(napi_env env,std::vector<DMRect> boundingRects)815 napi_value CreateJsBoundingRectsArrayObject(napi_env env, std::vector<DMRect> boundingRects)
816 {
817 napi_value arrayValue = nullptr;
818 napi_create_array_with_length(env, boundingRects.size(), &arrayValue);
819 size_t i = 0;
820 for (const auto& rect : boundingRects) {
821 napi_set_element(env, arrayValue, i++, CreateJsRectObject(env, rect));
822 }
823 return arrayValue;
824 }
825
NapiSetNamedProperty(napi_env env,napi_value objValue,sptr<DisplayInfo> info)826 void NapiSetNamedProperty(napi_env env, napi_value objValue, sptr<DisplayInfo> info)
827 {
828 napi_set_named_property(env, objValue, "id", CreateJsValue(env, static_cast<uint32_t>(info->GetDisplayId())));
829 napi_set_named_property(env, objValue, "name", CreateJsValue(env, info->GetName()));
830 napi_set_named_property(env, objValue, "alive", CreateJsValue(env, info->GetAliveStatus()));
831 if (NATIVE_TO_JS_DISPLAY_STATE_MAP.count(info->GetDisplayState()) != 0) {
832 napi_set_named_property(env, objValue, "state",
833 CreateJsValue(env, NATIVE_TO_JS_DISPLAY_STATE_MAP.at(info->GetDisplayState())));
834 } else {
835 napi_set_named_property(env, objValue, "state", CreateJsValue(env, DisplayStateMode::STATE_UNKNOWN));
836 }
837 napi_set_named_property(env, objValue, "refreshRate", CreateJsValue(env, info->GetRefreshRate()));
838 napi_set_named_property(env, objValue, "rotation", CreateJsValue(env, info->GetRotation()));
839 napi_set_named_property(env, objValue, "width", CreateJsValue(env, info->GetWidth()));
840 napi_set_named_property(env, objValue, "height", CreateJsValue(env, info->GetHeight()));
841 napi_set_named_property(env, objValue, "densityDPI",
842 CreateJsValue(env, info->GetVirtualPixelRatio() * DOT_PER_INCH));
843 napi_set_named_property(env, objValue, "orientation", CreateJsValue(env, info->GetDisplayOrientation()));
844 napi_set_named_property(env, objValue, "densityPixels", CreateJsValue(env, info->GetVirtualPixelRatio()));
845 napi_set_named_property(env, objValue, "scaledDensity", CreateJsValue(env, info->GetVirtualPixelRatio()));
846 napi_set_named_property(env, objValue, "xDPI", CreateJsValue(env, info->GetXDpi()));
847 napi_set_named_property(env, objValue, "yDPI", CreateJsValue(env, info->GetYDpi()));
848 napi_set_named_property(env, objValue, "colorSpaces", CreateJsColorSpaceArray(env, info->GetColorSpaces()));
849 napi_set_named_property(env, objValue, "hdrFormats", CreateJsHDRFormatArray(env, info->GetHdrFormats()));
850 napi_set_named_property(env, objValue, "availableWidth", CreateJsValue(env, info->GetAvailableWidth()));
851 napi_set_named_property(env, objValue, "availableHeight", CreateJsValue(env, info->GetAvailableHeight()));
852 napi_set_named_property(env, objValue, "screenShape", CreateJsValue(env, info->GetScreenShape()));
853 if (info->GetDisplaySourceMode() == DisplaySourceMode::MAIN ||
854 info->GetDisplaySourceMode() == DisplaySourceMode::EXTEND) {
855 napi_set_named_property(env, objValue, "x", CreateJsValue(env, info->GetX()));
856 napi_set_named_property(env, objValue, "y", CreateJsValue(env, info->GetY()));
857 } else {
858 napi_set_named_property(env, objValue, "x", NapiGetUndefined(env));
859 napi_set_named_property(env, objValue, "y", NapiGetUndefined(env));
860 }
861 napi_set_named_property(env, objValue, "sourceMode", CreateJsValue(env, info->GetDisplaySourceMode()));
862 napi_set_named_property(env, objValue, "supportedRefreshRate", CreateJsSupportedRefreshRateArray(
863 env, info->GetSupportedRefreshRate()));
864 }
865
CreateJsDisplayObject(napi_env env,sptr<Display> & display)866 napi_value CreateJsDisplayObject(napi_env env, sptr<Display>& display)
867 {
868 TLOGD(WmsLogTag::DMS, "called");
869 napi_value objValue = nullptr;
870 std::shared_ptr<NativeReference> jsDisplayObj = FindJsDisplayObject(display->GetId());
871 if (jsDisplayObj != nullptr && jsDisplayObj->GetNapiValue() != nullptr) {
872 TLOGD(WmsLogTag::DMS, "[NAPI]FindJsDisplayObject %{public}" PRIu64"", display->GetId());
873 objValue = jsDisplayObj->GetNapiValue();
874 }
875 if (objValue == nullptr) {
876 napi_create_object(env, &objValue);
877 }
878 if (objValue == nullptr) {
879 TLOGE(WmsLogTag::DMS, "Failed to get jsObject");
880 return NapiGetUndefined(env);
881 }
882 auto info = display->GetDisplayInfoWithCache();
883 if (info == nullptr) {
884 TLOGE(WmsLogTag::DMS, "Failed to GetDisplayInfo");
885 return NapiGetUndefined(env);
886 }
887
888 NapiSetNamedProperty(env, objValue, info);
889
890 if (jsDisplayObj == nullptr || jsDisplayObj->GetNapiValue() == nullptr) {
891 std::unique_ptr<JsDisplay> jsDisplay = std::make_unique<JsDisplay>(display);
892 napi_wrap(env, objValue, jsDisplay.release(), JsDisplay::Finalizer, nullptr, nullptr);
893 BindNativeFunction(env, objValue, "getCutoutInfo", "JsDisplay", JsDisplay::GetCutoutInfo);
894 BindNativeFunction(env, objValue, "getAvailableArea", "JsDisplay", JsDisplay::GetAvailableArea);
895 BindNativeFunction(env, objValue, "hasImmersiveWindow", "JsDisplay", JsDisplay::HasImmersiveWindow);
896 BindNativeFunction(env, objValue, "getSupportedColorSpaces", "JsDisplay", JsDisplay::GetSupportedColorSpaces);
897 BindNativeFunction(env, objValue, "getSupportedHDRFormats", "JsDisplay", JsDisplay::GetSupportedHDRFormats);
898 BindNativeFunction(env, objValue, "on", "JsDisplay", JsDisplay::RegisterDisplayManagerCallback);
899 BindNativeFunction(env, objValue, "off", "JsDisplay", JsDisplay::UnregisterDisplayManagerCallback);
900 BindNativeFunction(env, objValue, "getDisplayCapability", "JsDisplay", JsDisplay::GetDisplayCapability);
901 BindNativeFunction(env, objValue, "getLiveCreaseRegion", "JsDisplay", JsDisplay::GetLiveCreaseRegion);
902 std::shared_ptr<NativeReference> jsDisplayRef;
903 napi_ref result = nullptr;
904 napi_create_reference(env, objValue, 1, &result);
905 jsDisplayRef.reset(reinterpret_cast<NativeReference*>(result));
906 DisplayId displayId = display->GetId();
907 std::lock_guard<std::recursive_mutex> lock(g_mutex);
908 g_JsDisplayMap[displayId] = jsDisplayRef;
909 }
910 return objValue;
911 }
912
CreateJsFoldCreaseRegionObject(napi_env env,const FoldCreaseRegion & region)913 napi_value CreateJsFoldCreaseRegionObject(napi_env env, const FoldCreaseRegion& region)
914 {
915 TLOGI(WmsLogTag::DMS, "called");
916 napi_value objValue = nullptr;
917 napi_create_object(env, &objValue);
918 if (objValue == nullptr) {
919 TLOGE(WmsLogTag::DMS, "Failed to convert prop to jsObject");
920 return NapiGetUndefined(env);
921 }
922 DisplayId displayId = region.GetDisplayId();
923 std::vector<DMRect> creaseRects = region.GetCreaseRects();
924 napi_set_named_property(env, objValue, "displayId", CreateJsValue(env, static_cast<uint32_t>(displayId)));
925 napi_set_named_property(env, objValue, "creaseRects", CreateJsCreaseRectsArrayObject(env, creaseRects));
926 return objValue;
927 }
928
CreateJsCreaseRectsArrayObject(napi_env env,const std::vector<DMRect> & creaseRects)929 napi_value CreateJsCreaseRectsArrayObject(napi_env env, const std::vector<DMRect>& creaseRects)
930 {
931 napi_value arrayValue = nullptr;
932 napi_create_array_with_length(env, creaseRects.size(), &arrayValue);
933 size_t i = 0;
934 for (const auto& rect : creaseRects) {
935 napi_set_element(env, arrayValue, i++, CreateJsRectObject(env, rect));
936 }
937 return arrayValue;
938 }
939 } // namespace Rosen
940 } // namespace OHOS
941