• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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