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 <vector>
17 #include <new>
18 
19 #include <hitrace_meter.h>
20 #include "js_runtime_utils.h"
21 #include "native_engine/native_reference.h"
22 #include "display_manager.h"
23 #include "window_manager_hilog.h"
24 #include "singleton_container.h"
25 #include "js_display_listener.h"
26 #include "js_display.h"
27 #include "js_display_manager.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 using namespace AbilityRuntime;
32 constexpr size_t ARGC_ONE = 1;
33 constexpr size_t ARGC_TWO = 2;
34 constexpr int32_t INDEX_ONE = 1;
35 namespace {
36 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "JsDisplayManager"};
37 }
38 
39 class JsDisplayManager {
40 public:
JsDisplayManager(napi_env env)41 explicit JsDisplayManager(napi_env env) {
42 }
43 
44 ~JsDisplayManager() = default;
45 
Finalizer(napi_env env,void * data,void * hint)46 static void Finalizer(napi_env env, void* data, void* hint)
47 {
48     WLOGI("Finalizer is called");
49     std::unique_ptr<JsDisplayManager>(static_cast<JsDisplayManager*>(data));
50 }
51 
GetDefaultDisplay(napi_env env,napi_callback_info info)52 static napi_value GetDefaultDisplay(napi_env env, napi_callback_info info)
53 {
54     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
55     return (me != nullptr) ? me->OnGetDefaultDisplay(env, info) : nullptr;
56 }
57 
GetDefaultDisplaySync(napi_env env,napi_callback_info info)58 static napi_value GetDefaultDisplaySync(napi_env env, napi_callback_info info)
59 {
60     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
61     return (me != nullptr) ? me->OnGetDefaultDisplaySync(env, info) : nullptr;
62 }
63 
GetPrimaryDisplaySync(napi_env env,napi_callback_info info)64 static napi_value GetPrimaryDisplaySync(napi_env env, napi_callback_info info)
65 {
66     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
67     return (me != nullptr) ? me->OnGetPrimaryDisplaySync(env, info) : nullptr;
68 }
69 
GetDisplayByIdSync(napi_env env,napi_callback_info info)70 static napi_value GetDisplayByIdSync(napi_env env, napi_callback_info info)
71 {
72     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
73     return (me != nullptr) ? me->OnGetDisplayByIdSync(env, info) : nullptr;
74 }
75 
GetAllDisplay(napi_env env,napi_callback_info info)76 static napi_value GetAllDisplay(napi_env env, napi_callback_info info)
77 {
78     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
79     return (me != nullptr) ? me->OnGetAllDisplay(env, info) : nullptr;
80 }
81 
GetAllDisplayPhysicalResolution(napi_env env,napi_callback_info info)82 static napi_value GetAllDisplayPhysicalResolution(napi_env env, napi_callback_info info)
83 {
84     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
85     return (me != nullptr) ? me->OnGetAllDisplayPhysicalResolution(env, info) : nullptr;
86 }
87 
GetAllDisplays(napi_env env,napi_callback_info info)88 static napi_value GetAllDisplays(napi_env env, napi_callback_info info)
89 {
90     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
91     return (me != nullptr) ? me->OnGetAllDisplays(env, info) : nullptr;
92 }
93 
RegisterDisplayManagerCallback(napi_env env,napi_callback_info info)94 static napi_value RegisterDisplayManagerCallback(napi_env env, napi_callback_info info)
95 {
96     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
97     return (me != nullptr) ? me->OnRegisterDisplayManagerCallback(env, info) : nullptr;
98 }
99 
UnregisterDisplayManagerCallback(napi_env env,napi_callback_info info)100 static napi_value UnregisterDisplayManagerCallback(napi_env env, napi_callback_info info)
101 {
102     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
103     return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(env, info) : nullptr;
104 }
105 
HasPrivateWindow(napi_env env,napi_callback_info info)106 static napi_value HasPrivateWindow(napi_env env, napi_callback_info info)
107 {
108     JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
109     return (me != nullptr) ? me->OnHasPrivateWindow(env, info) : nullptr;
110 }
111 
IsFoldable(napi_env env,napi_callback_info info)112 static napi_value IsFoldable(napi_env env, napi_callback_info info)
113 {
114     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
115     return (me != nullptr) ? me->OnIsFoldable(env, info) : nullptr;
116 }
117 
IsCaptured(napi_env env,napi_callback_info info)118 static napi_value IsCaptured(napi_env env, napi_callback_info info)
119 {
120     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
121     return (me != nullptr) ? me->OnIsCaptured(env, info) : nullptr;
122 }
123 
GetFoldStatus(napi_env env,napi_callback_info info)124 static napi_value GetFoldStatus(napi_env env, napi_callback_info info)
125 {
126     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
127     return (me != nullptr) ? me->OnGetFoldStatus(env, info) : nullptr;
128 }
129 
GetFoldDisplayMode(napi_env env,napi_callback_info info)130 static napi_value GetFoldDisplayMode(napi_env env, napi_callback_info info)
131 {
132     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
133     return (me != nullptr) ? me->OnGetFoldDisplayMode(env, info) : nullptr;
134 }
135 
SetFoldDisplayMode(napi_env env,napi_callback_info info)136 static napi_value SetFoldDisplayMode(napi_env env, napi_callback_info info)
137 {
138     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
139     return (me != nullptr) ? me->OnSetFoldDisplayMode(env, info) : nullptr;
140 }
141 
SetFoldStatusLocked(napi_env env,napi_callback_info info)142 static napi_value SetFoldStatusLocked(napi_env env, napi_callback_info info)
143 {
144     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
145     return (me != nullptr) ? me->OnSetFoldStatusLocked(env, info) : nullptr;
146 }
147 
GetCurrentFoldCreaseRegion(napi_env env,napi_callback_info info)148 static napi_value GetCurrentFoldCreaseRegion(napi_env env, napi_callback_info info)
149 {
150     auto* me = CheckParamsAndGetThis<JsDisplayManager>(env, info);
151     return (me != nullptr) ? me->OnGetCurrentFoldCreaseRegion(env, info) : nullptr;
152 }
153 
154 private:
155 std::map<std::string, std::map<std::unique_ptr<NativeReference>, sptr<JsDisplayListener>>> jsCbMap_;
156 std::mutex mtx_;
157 
OnGetDefaultDisplay(napi_env env,napi_callback_info info)158 napi_value OnGetDefaultDisplay(napi_env env, napi_callback_info info)
159 {
160     WLOGI("GetDefaultDisplay called");
161     DMError errCode = DMError::DM_OK;
162     size_t argc = 4;
163     napi_value argv[4] = {nullptr};
164     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
165     if (argc != 0 && argc != ARGC_ONE) {
166         WLOGFE("OnGetDefaultDisplay params not match");
167         errCode = DMError::DM_ERROR_INVALID_PARAM;
168     }
169 
170     NapiAsyncTask::CompleteCallback complete =
171         [=](napi_env env, NapiAsyncTask& task, int32_t status) {
172             if (errCode != DMError::DM_OK) {
173                 task.Reject(env, CreateJsError(env,
174                     static_cast<int32_t>(errCode), "JsDisplayManager::OnGetDefaultDisplay failed."));
175             }
176             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Async:GetDefaultDisplay");
177             sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
178             if (display != nullptr) {
179                 task.Resolve(env, CreateJsDisplayObject(env, display));
180                 WLOGI("OnGetDefaultDisplay success");
181             } else {
182                 task.Reject(env, CreateJsError(env,
183                     static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetDefaultDisplay failed."));
184             }
185         };
186     napi_value lastParam = nullptr;
187     if (argc == ARGC_ONE && GetType(env, argv[0]) == napi_function) {
188         lastParam = argv[0];
189     }
190     napi_value result = nullptr;
191     NapiAsyncTask::Schedule("JsDisplayManager::OnGetDefaultDisplay",
192         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
193     return result;
194 }
195 
OnGetPrimaryDisplaySync(napi_env env,napi_callback_info info)196 napi_value OnGetPrimaryDisplaySync(napi_env env, napi_callback_info info)
197 {
198     WLOGD("OnGetPrimaryDisplaySync called");
199     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Sync:OnGetPrimaryDisplaySync");
200     sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetPrimaryDisplaySync();
201     if (display == nullptr) {
202         WLOGFE("[NAPI]Display info is nullptr, js error will be happen");
203         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN),
204             "invalid screen id"));
205         return NapiGetUndefined(env);
206     }
207     return CreateJsDisplayObject(env, display);
208 }
209 
OnGetDefaultDisplaySync(napi_env env,napi_callback_info info)210 napi_value OnGetDefaultDisplaySync(napi_env env, napi_callback_info info)
211 {
212     WLOGD("GetDefaultDisplaySync called");
213     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Sync:GetDefaultDisplay");
214     sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplaySync(true);
215     if (display == nullptr) {
216         WLOGFE("[NAPI]Display info is nullptr, js error will be happen");
217         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN)));
218         return NapiGetUndefined(env);
219     }
220     return CreateJsDisplayObject(env, display);
221 }
222 
OnGetDisplayByIdSync(napi_env env,napi_callback_info info)223 napi_value OnGetDisplayByIdSync(napi_env env, napi_callback_info info)
224 {
225     TLOGD(WmsLogTag::DMS, "OnGetDisplayByIdSync called");
226     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Sync:OnGetDisplayByIdSync");
227     size_t argc = 4;
228     napi_value argv[4] = {nullptr};
229     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
230     if (argc < ARGC_ONE) {
231         std::string errMsg = "Invalid args count, need one arg";
232         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
233         return NapiGetUndefined(env);
234     }
235     int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
236     if (!ConvertFromJsValue(env, argv[0], displayId)) {
237         TLOGE(WmsLogTag::DMS, "[NAPI]Failed to convert parameter to displayId");
238         std::string errMsg = "Failed to convert parameter to displayId";
239         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
240         return NapiGetUndefined(env);
241     }
242     if (displayId < 0) {
243         std::string errMsg = "displayid is invalid, less than 0";
244         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
245         return NapiGetUndefined(env);
246     }
247     sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<DisplayId>(displayId));
248     if (display == nullptr) {
249         TLOGE(WmsLogTag::DMS, "[NAPI]Display info is nullptr, js error will be happen");
250         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL)));
251         return NapiGetUndefined(env);
252     }
253     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Sync:OnGetDisplayByIdSync end");
254     return CreateJsDisplayObject(env, display);
255 }
256 
OnGetAllDisplay(napi_env env,napi_callback_info info)257 napi_value OnGetAllDisplay(napi_env env, napi_callback_info info)
258 {
259     WLOGD("GetAllDisplay called");
260     DMError errCode = DMError::DM_OK;
261     size_t argc = 4;
262     napi_value argv[4] = {nullptr};
263     std::string taskName = "OnGetAllDisplay";
264     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
265     if (argc != 0 && argc != ARGC_ONE) {
266         WLOGFE("OnGetAllDisplay params not match");
267         errCode = DMError::DM_ERROR_INVALID_PARAM;
268         return NapiGetUndefined(env);
269     }
270     napi_value lastParam = nullptr;
271     if (argc == ARGC_ONE && GetType(env, argv[0]) == napi_function) {
272         lastParam = argv[0];
273     }
274     napi_value result = nullptr;
275     std::unique_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
276     auto asyncTask = [this, env, task = napiAsyncTask.get()]() {
277         std::vector<sptr<Display>> displays = SingletonContainer::Get<DisplayManager>().GetAllDisplays();
278         if (!displays.empty()) {
279             task->Resolve(env, CreateJsDisplayArrayObject(env, displays));
280             WLOGI("GetAllDisplays success");
281         } else {
282             task->Reject(env, CreateJsError(env,
283                 static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetAllDisplay failed."));
284         }
285         delete task;
286     };
287     NapiSendDmsEvent(env, asyncTask, napiAsyncTask, taskName);
288     return result;
289 }
290 
NapiSendDmsEvent(napi_env env,std::function<void ()> asyncTask,std::unique_ptr<AbilityRuntime::NapiAsyncTask> & napiAsyncTask,std::string taskName)291 void NapiSendDmsEvent(napi_env env, std::function<void()> asyncTask,
292     std::unique_ptr<AbilityRuntime::NapiAsyncTask>& napiAsyncTask, std::string taskName)
293 {
294     if (!env) {
295         WLOGFE("env is null");
296         return;
297     }
298     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_immediate)) {
299         napiAsyncTask->Reject(env, CreateJsError(env,
300                 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN), "Send event failed!"));
301     } else {
302         napiAsyncTask.release();
303         WLOGFI("%{public}s:send event success", taskName.c_str());
304     }
305 }
306 
CreateEmptyAsyncTask(napi_env env,napi_value lastParam,napi_value * result)307 std::unique_ptr<NapiAsyncTask> CreateEmptyAsyncTask(napi_env env, napi_value lastParam, napi_value* result)
308 {
309     napi_valuetype type = napi_undefined;
310     napi_typeof(env, lastParam, &type);
311     if (lastParam == nullptr || type != napi_function) {
312         napi_deferred nativeDeferred = nullptr;
313         napi_create_promise(env, &nativeDeferred, result);
314         return std::make_unique<NapiAsyncTask>(nativeDeferred, std::unique_ptr<NapiAsyncTask::ExecuteCallback>(),
315             std::unique_ptr<NapiAsyncTask::CompleteCallback>());
316     } else {
317         napi_get_undefined(env, result);
318         napi_ref callbackRef = nullptr;
319         napi_create_reference(env, lastParam, 1, &callbackRef);
320         return std::make_unique<NapiAsyncTask>(callbackRef, std::unique_ptr<NapiAsyncTask::ExecuteCallback>(),
321             std::unique_ptr<NapiAsyncTask::CompleteCallback>());
322     }
323 }
324 
CreateJsDisplayPhysicalArrayObject(napi_env env,const std::vector<DisplayPhysicalResolution> & physicalArray)325 napi_value CreateJsDisplayPhysicalArrayObject(napi_env env,
326     const std::vector<DisplayPhysicalResolution>& physicalArray)
327 {
328     WLOGD("CreateJsDisplayPhysicalArrayObject is called");
329     napi_value arrayValue = nullptr;
330     napi_create_array_with_length(env, physicalArray.size(), &arrayValue);
331     if (arrayValue == nullptr) {
332         WLOGFE("Failed to create display array");
333         return NapiGetUndefined(env);
334     }
335     int32_t i = 0;
336     for (const auto& displayItem : physicalArray) {
337         napi_set_element(env, arrayValue, i++, CreateJsDisplayPhysicalInfoObject(env, displayItem));
338     }
339     return arrayValue;
340 }
341 
OnGetAllDisplayPhysicalResolution(napi_env env,napi_callback_info info)342 napi_value OnGetAllDisplayPhysicalResolution(napi_env env, napi_callback_info info)
343 {
344     WLOGD("OnGetAllDisplayPhysicalResolution called");
345     DMError errCode = DMError::DM_OK;
346     size_t argc = 4;
347     napi_value argv[4] = {nullptr};
348     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
349     if (argc != 0 && argc != ARGC_ONE) {
350         WLOGFE("params not match");
351         errCode = DMError::DM_ERROR_INVALID_PARAM;
352     }
353 
354     NapiAsyncTask::CompleteCallback complete =
355         [=](napi_env env, NapiAsyncTask& task, int32_t status) {
356             if (errCode != DMError::DM_OK) {
357                 task.Reject(env, CreateJsError(env,
358                     static_cast<int32_t>(errCode), "JsDisplayManager::OnGetAllDisplayPhysicalResolution failed."));
359             }
360             std::vector<DisplayPhysicalResolution> displayPhysicalArray =
361                 SingletonContainer::Get<DisplayManager>().GetAllDisplayPhysicalResolution();
362             if (!displayPhysicalArray.empty()) {
363                 task.Resolve(env, CreateJsDisplayPhysicalArrayObject(env, displayPhysicalArray));
364                 WLOGI("OnGetAllDisplayPhysicalResolution success");
365             } else {
366                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(DMError::DM_ERROR_NULLPTR),
367                     "JsDisplayManager::OnGetAllDisplayPhysicalResolution failed."));
368             }
369         };
370 
371     napi_value lastParam = nullptr;
372     if (argc == ARGC_ONE && GetType(env, argv[0]) == napi_function) {
373         lastParam = argv[0];
374     }
375     napi_value result = nullptr;
376     NapiAsyncTask::Schedule("JsDisplayManager::OnGetAllDisplayPhysicalResolution",
377         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
378     return result;
379 }
380 
OnGetAllDisplays(napi_env env,napi_callback_info info)381 napi_value OnGetAllDisplays(napi_env env, napi_callback_info info)
382 {
383     WLOGD("OnGetAllDisplays is called");
384 
385     NapiAsyncTask::CompleteCallback complete =
386         [=](napi_env env, NapiAsyncTask& task, int32_t status) {
387             std::vector<sptr<Display>> displays = SingletonContainer::Get<DisplayManager>().GetAllDisplays();
388             if (!displays.empty()) {
389                 task.Resolve(env, CreateJsDisplayArrayObject(env, displays));
390                 WLOGD("GetAllDisplays success");
391             } else {
392                 auto errorPending = false;
393                 napi_is_exception_pending(env, &errorPending);
394                 if (errorPending) {
395                     napi_value exception = nullptr;
396                     napi_get_and_clear_last_exception(env, &exception);
397                 }
398                 task.Reject(env, CreateJsError(env,
399                     static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN),
400                     "JsDisplayManager::OnGetAllDisplays failed."));
401             }
402         };
403     size_t argc = 4;
404     napi_value argv[4] = {nullptr};
405     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
406     napi_value lastParam = nullptr;
407     if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
408         GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
409         lastParam = argv[0];
410     }
411     napi_value result = nullptr;
412     NapiAsyncTask::Schedule("JsDisplayManager::OnGetAllDisplays",
413         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
414     return result;
415 }
416 
RegisterDisplayListenerWithType(napi_env env,const std::string & type,napi_value value)417 DMError RegisterDisplayListenerWithType(napi_env env, const std::string& type, napi_value value)
418 {
419     if (IfCallbackRegistered(env, type, value)) {
420         WLOGFE("RegisterDisplayListenerWithType callback already registered!");
421         return DMError::DM_OK;
422     }
423     std::unique_ptr<NativeReference> callbackRef;
424     napi_ref result = nullptr;
425     napi_create_reference(env, value, 1, &result);
426     callbackRef.reset(reinterpret_cast<NativeReference*>(result));
427     sptr<JsDisplayListener> displayListener = new(std::nothrow) JsDisplayListener(env);
428     DMError ret = DMError::DM_OK;
429     if (displayListener == nullptr) {
430         WLOGFE("displayListener is nullptr");
431         return DMError::DM_ERROR_INVALID_PARAM;
432     }
433     if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
434         ret = SingletonContainer::Get<DisplayManager>().RegisterDisplayListener(displayListener);
435     } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
436         ret = SingletonContainer::Get<DisplayManager>().RegisterPrivateWindowListener(displayListener);
437     } else if (type == EVENT_FOLD_STATUS_CHANGED) {
438         ret = SingletonContainer::Get<DisplayManager>().RegisterFoldStatusListener(displayListener);
439     } else if (type == EVENT_DISPLAY_MODE_CHANGED) {
440         ret = SingletonContainer::Get<DisplayManager>().RegisterDisplayModeListener(displayListener);
441     } else if (type == EVENT_AVAILABLE_AREA_CHANGED) {
442         ret = SingletonContainer::Get<DisplayManager>().RegisterAvailableAreaListener(displayListener);
443     } else if (type == EVENT_FOLD_ANGLE_CHANGED) {
444         ret = SingletonContainer::Get<DisplayManager>().RegisterFoldAngleListener(displayListener);
445     } else if (type == EVENT_CAPTURE_STATUS_CHANGED) {
446         ret = SingletonContainer::Get<DisplayManager>().RegisterCaptureStatusListener(displayListener);
447     } else {
448         WLOGFE("RegisterDisplayListenerWithType failed, %{public}s not support", type.c_str());
449         return DMError::DM_ERROR_INVALID_PARAM;
450     }
451     if (ret != DMError::DM_OK) {
452         WLOGFE("RegisterDisplayListenerWithType failed, ret: %{public}u", ret);
453         return ret;
454     }
455     displayListener->AddCallback(type, value);
456     jsCbMap_[type][std::move(callbackRef)] = displayListener;
457     return DMError::DM_OK;
458 }
459 
IfCallbackRegistered(napi_env env,const std::string & type,napi_value jsListenerObject)460 bool IfCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject)
461 {
462     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
463         WLOGI("IfCallbackRegistered methodName %{public}s not registered!", type.c_str());
464         return false;
465     }
466 
467     for (auto& iter : jsCbMap_[type]) {
468         bool isEquals = false;
469         napi_strict_equals(env, jsListenerObject, iter.first->GetNapiValue(), &isEquals);
470         if (isEquals) {
471             WLOGFE("IfCallbackRegistered callback already registered!");
472             return true;
473         }
474     }
475     return false;
476 }
477 
UnregisterAllDisplayListenerWithType(const std::string & type)478 DMError UnregisterAllDisplayListenerWithType(const std::string& type)
479 {
480     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
481         WLOGI("UnregisterAllDisplayListenerWithType methodName %{public}s not registered!",
482             type.c_str());
483         return DMError::DM_OK;
484     }
485     DMError ret = DMError::DM_OK;
486     for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
487         it->second->RemoveAllCallback();
488         if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
489             sptr<DisplayManager::IDisplayListener> thisListener(it->second);
490             ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
491         } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
492             sptr<DisplayManager::IPrivateWindowListener> thisListener(it->second);
493             ret = SingletonContainer::Get<DisplayManager>().UnregisterPrivateWindowListener(thisListener);
494         } else if (type == EVENT_AVAILABLE_AREA_CHANGED) {
495             sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
496             ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener);
497         } else if (type == EVENT_FOLD_STATUS_CHANGED) {
498             sptr<DisplayManager::IFoldStatusListener> thisListener(it->second);
499             ret = SingletonContainer::Get<DisplayManager>().UnregisterFoldStatusListener(thisListener);
500         } else if (type == EVENT_DISPLAY_MODE_CHANGED) {
501             sptr<DisplayManager::IDisplayModeListener> thisListener(it->second);
502             ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayModeListener(thisListener);
503         } else if (type == EVENT_FOLD_ANGLE_CHANGED) {
504             sptr<DisplayManager::IFoldAngleListener> thisListener(it->second);
505             ret = SingletonContainer::Get<DisplayManager>().UnregisterFoldAngleListener(thisListener);
506         } else if (type == EVENT_CAPTURE_STATUS_CHANGED) {
507             sptr<DisplayManager::ICaptureStatusListener> thisListener(it->second);
508             ret = SingletonContainer::Get<DisplayManager>().UnregisterCaptureStatusListener(thisListener);
509         } else {
510             ret = DMError::DM_ERROR_INVALID_PARAM;
511         }
512         jsCbMap_[type].erase(it++);
513         WLOGFI("unregister display listener with type %{public}s  ret: %{public}u", type.c_str(), ret);
514     }
515     jsCbMap_.erase(type);
516     return ret;
517 }
518 
UnRegisterDisplayListenerWithType(napi_env env,const std::string & type,napi_value value)519 DMError UnRegisterDisplayListenerWithType(napi_env env, const std::string& type, napi_value value)
520 {
521     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
522         WLOGI("UnRegisterDisplayListenerWithType methodName %{public}s not registered!", type.c_str());
523         return DMError::DM_OK;
524     }
525     DMError ret = DMError::DM_OK;
526     for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
527         bool isEquals = false;
528         napi_strict_equals(env, value, it->first->GetNapiValue(), &isEquals);
529         if (isEquals) {
530             it->second->RemoveCallback(env, type, value);
531             if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
532                 sptr<DisplayManager::IDisplayListener> thisListener(it->second);
533                 ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
534             } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
535                 sptr<DisplayManager::IPrivateWindowListener> thisListener(it->second);
536                 ret = SingletonContainer::Get<DisplayManager>().UnregisterPrivateWindowListener(thisListener);
537             } else if (type == EVENT_AVAILABLE_AREA_CHANGED) {
538                 sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
539                 ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener);
540             } else if (type == EVENT_FOLD_STATUS_CHANGED) {
541                 sptr<DisplayManager::IFoldStatusListener> thisListener(it->second);
542                 ret = SingletonContainer::Get<DisplayManager>().UnregisterFoldStatusListener(thisListener);
543             } else if (type == EVENT_DISPLAY_MODE_CHANGED) {
544                 sptr<DisplayManager::IDisplayModeListener> thisListener(it->second);
545                 ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayModeListener(thisListener);
546             } else if (type == EVENT_FOLD_ANGLE_CHANGED) {
547                 sptr<DisplayManager::IFoldAngleListener> thisListener(it->second);
548                 ret = SingletonContainer::Get<DisplayManager>().UnregisterFoldAngleListener(thisListener);
549             } else if (type == EVENT_CAPTURE_STATUS_CHANGED) {
550                 sptr<DisplayManager::ICaptureStatusListener> thisListener(it->second);
551                 ret = SingletonContainer::Get<DisplayManager>().UnregisterCaptureStatusListener(thisListener);
552             } else {
553                 ret = DMError::DM_ERROR_INVALID_PARAM;
554             }
555             jsCbMap_[type].erase(it++);
556             WLOGFI("unregister display listener with type %{public}s  ret: %{public}u", type.c_str(), ret);
557             break;
558         } else {
559             it++;
560         }
561     }
562     if (jsCbMap_[type].empty()) {
563         jsCbMap_.erase(type);
564     }
565     return ret;
566 }
567 
NapiIsCallable(napi_env env,napi_value value)568 bool NapiIsCallable(napi_env env, napi_value value)
569 {
570     bool result = false;
571     napi_is_callable(env, value, &result);
572     return result;
573 }
574 
OnRegisterDisplayManagerCallback(napi_env env,napi_callback_info info)575 napi_value OnRegisterDisplayManagerCallback(napi_env env, napi_callback_info info)
576 {
577     WLOGD("OnRegisterDisplayManagerCallback is called");
578     size_t argc = 4;
579     napi_value argv[4] = {nullptr};
580     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
581     if (argc < ARGC_TWO) {
582         WLOGFE("JsDisplayManager Params not match: %{public}zu", argc);
583         std::string errMsg = "Invalid args count, need 2 args";
584         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
585         return NapiGetUndefined(env);
586     }
587     std::string cbType;
588     if (!ConvertFromJsValue(env, argv[0], cbType)) {
589         std::string errMsg = "Failed to convert parameter to callbackType";
590         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
591         WLOGFE("Failed to convert parameter to callbackType");
592         return NapiGetUndefined(env);
593     }
594     napi_value value = argv[INDEX_ONE];
595     if (value == nullptr) {
596         WLOGI("OnRegisterDisplayManagerCallback info->argv[1] is nullptr");
597         std::string errMsg = "OnRegisterDisplayManagerCallback is nullptr";
598         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
599         return NapiGetUndefined(env);
600     }
601     if (!NapiIsCallable(env, value)) {
602         WLOGI("OnRegisterDisplayManagerCallback info->argv[1] is not callable");
603         std::string errMsg = "OnRegisterDisplayManagerCallback is not callable";
604         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
605         return NapiGetUndefined(env);
606     }
607     std::lock_guard<std::mutex> lock(mtx_);
608     DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(RegisterDisplayListenerWithType(env, cbType, value));
609     if (ret != DmErrorCode::DM_OK) {
610         DmErrorCode errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
611         if (ret == DmErrorCode::DM_ERROR_NOT_SYSTEM_APP) {
612             errCode = ret;
613         }
614         WLOGFE("Failed to register display listener with type");
615         std::string errMsg = "Failed to register display listener with type";
616         napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode), errMsg));
617         return NapiGetUndefined(env);
618     }
619     return NapiGetUndefined(env);
620 }
621 
OnUnregisterDisplayManagerCallback(napi_env env,napi_callback_info info)622 napi_value OnUnregisterDisplayManagerCallback(napi_env env, napi_callback_info info)
623 {
624     WLOGI("OnUnregisterDisplayCallback is called");
625     size_t argc = 4;
626     napi_value argv[4] = {nullptr};
627     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
628     if (argc < ARGC_ONE) {
629         WLOGFE("JsDisplayManager Params not match %{public}zu", argc);
630         std::string errMsg = "Invalid args count, need one arg at least!";
631         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
632         return NapiGetUndefined(env);
633     }
634     std::string cbType;
635     if (!ConvertFromJsValue(env, argv[0], cbType)) {
636         WLOGFE("Failed to convert parameter to callbackType");
637         std::string errMsg = "Failed to convert parameter to string";
638         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
639         return NapiGetUndefined(env);
640     }
641     std::lock_guard<std::mutex> lock(mtx_);
642     DmErrorCode ret;
643     if (argc == ARGC_ONE) {
644         ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
645     } else {
646         napi_value value = argv[INDEX_ONE];
647         if ((value == nullptr) || (!NapiIsCallable(env, value))) {
648             ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
649         } else {
650             ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(env, cbType, value));
651         }
652     }
653     if (ret != DmErrorCode::DM_OK) {
654         DmErrorCode errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
655         if (ret == DmErrorCode::DM_ERROR_NOT_SYSTEM_APP) {
656             errCode = ret;
657         }
658         WLOGFW("failed to unregister display listener with type");
659         std::string errMsg = "failed to unregister display listener with type";
660         napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode), errMsg));
661         return NapiGetUndefined(env);
662     }
663     return NapiGetUndefined(env);
664 }
665 
OnHasPrivateWindow(napi_env env,napi_callback_info info)666 napi_value OnHasPrivateWindow(napi_env env, napi_callback_info info)
667 {
668     bool hasPrivateWindow = false;
669     size_t argc = 4;
670     napi_value argv[4] = {nullptr};
671     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
672     if (argc < ARGC_ONE) {
673         std::string errMsg = "Invalid args count, need one arg";
674         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
675         return NapiGetUndefined(env);
676     }
677     int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
678     if (!ConvertFromJsValue(env, argv[0], displayId)) {
679         WLOGFE("[NAPI]Failed to convert parameter to displayId");
680         std::string errMsg = "Failed to convert parameter to displayId";
681         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
682         return NapiGetUndefined(env);
683     }
684     if (displayId < 0) {
685         std::string errMsg = "displayid is invalid, less than 0";
686         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
687         return NapiGetUndefined(env);
688     }
689     DmErrorCode errCode = DM_JS_TO_ERROR_CODE_MAP.at(
690         SingletonContainer::Get<DisplayManager>().HasPrivateWindow(displayId, hasPrivateWindow));
691     WLOGI("[NAPI]Display id = %{public}" PRIu64", hasPrivateWindow = %{public}u err = %{public}d",
692         static_cast<uint64_t>(displayId), hasPrivateWindow, errCode);
693     if (errCode != DmErrorCode::DM_OK) {
694         napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode)));
695         return NapiGetUndefined(env);
696     }
697     napi_value result;
698     napi_get_boolean(env, hasPrivateWindow, &result);
699     return result;
700 }
701 
CreateJsDisplayArrayObject(napi_env env,std::vector<sptr<Display>> & displays)702 napi_value CreateJsDisplayArrayObject(napi_env env, std::vector<sptr<Display>>& displays)
703 {
704     WLOGD("CreateJsDisplayArrayObject is called");
705     napi_value arrayValue = nullptr;
706     napi_create_array_with_length(env, displays.size(), &arrayValue);
707     if (arrayValue == nullptr) {
708         WLOGFE("Failed to create display array");
709         return NapiGetUndefined(env);
710     }
711     int32_t i = 0;
712     for (auto& display : displays) {
713         if (display == nullptr) {
714             continue;
715         }
716         napi_set_element(env, arrayValue, i++, CreateJsDisplayObject(env, display));
717     }
718     return arrayValue;
719 }
720 
OnIsFoldable(napi_env env,napi_callback_info info)721 napi_value OnIsFoldable(napi_env env, napi_callback_info info)
722 {
723     size_t argc = 4;
724     napi_value argv[4] = {nullptr};
725     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
726     if (argc >= ARGC_ONE) {
727         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
728         return NapiGetUndefined(env);
729     }
730     bool foldable = SingletonContainer::Get<DisplayManager>().IsFoldable();
731     WLOGD("[NAPI]" PRIu64", isFoldable = %{public}u", foldable);
732     napi_value result;
733     napi_get_boolean(env, foldable, &result);
734     return result;
735 }
736 
OnIsCaptured(napi_env env,napi_callback_info info)737 napi_value OnIsCaptured(napi_env env, napi_callback_info info)
738 {
739     size_t argc = 4;  // default arg length
740     napi_value argv[4] = { nullptr };  // default arg length
741     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
742     if (argc >= ARGC_ONE) {
743         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
744         return NapiGetUndefined(env);
745     }
746     bool isCapture = SingletonContainer::Get<DisplayManager>().IsCaptured();
747     WLOGD("[NAPI]" PRIu64", IsCaptured = %{public}u", isCapture);
748     napi_value result;
749     napi_get_boolean(env, isCapture, &result);
750     return result;
751 }
752 
OnGetFoldStatus(napi_env env,napi_callback_info info)753 napi_value OnGetFoldStatus(napi_env env, napi_callback_info info)
754 {
755     size_t argc = 4;
756     napi_value argv[4] = {nullptr};
757     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
758     if (argc >= ARGC_ONE) {
759         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
760         return NapiGetUndefined(env);
761     }
762     FoldStatus status = SingletonContainer::Get<DisplayManager>().GetFoldStatus();
763     WLOGD("[NAPI]" PRIu64", getFoldStatus = %{public}u", status);
764     return CreateJsValue(env, status);
765 }
766 
OnGetFoldDisplayMode(napi_env env,napi_callback_info info)767 napi_value OnGetFoldDisplayMode(napi_env env, napi_callback_info info)
768 {
769     size_t argc = 4;
770     napi_value argv[4] = {nullptr};
771     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
772     if (argc >= ARGC_ONE) {
773         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
774         return NapiGetUndefined(env);
775     }
776     FoldDisplayMode mode = SingletonContainer::Get<DisplayManager>().GetFoldDisplayMode();
777     WLOGD("[NAPI]" PRIu64", getFoldDisplayMode = %{public}u", mode);
778     return CreateJsValue(env, mode);
779 }
780 
OnSetFoldDisplayMode(napi_env env,napi_callback_info info)781 napi_value OnSetFoldDisplayMode(napi_env env, napi_callback_info info)
782 {
783     size_t argc = 4;
784     napi_value argv[4] = {nullptr};
785     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
786     if (argc < ARGC_ONE) {
787         std::string errMsg = "Invalid args count, need one arg";
788         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
789         return NapiGetUndefined(env);
790     }
791     FoldDisplayMode mode = FoldDisplayMode::UNKNOWN;
792     if (!ConvertFromJsValue(env, argv[0], mode)) {
793         WLOGFE("[NAPI]Failed to convert parameter to FoldDisplayMode");
794         std::string errMsg = "Failed to convert parameter to FoldDisplayMode";
795         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
796         return NapiGetUndefined(env);
797     }
798     DmErrorCode errCode = DM_JS_TO_ERROR_CODE_MAP.at(
799         SingletonContainer::Get<DisplayManager>().SetFoldDisplayModeFromJs(mode));
800     if (errCode != DmErrorCode::DM_OK) {
801         napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode)));
802         return NapiGetUndefined(env);
803     }
804     WLOGI("[NAPI]" PRIu64", setFoldDisplayMode");
805     return NapiGetUndefined(env);
806 }
807 
OnSetFoldStatusLocked(napi_env env,napi_callback_info info)808 napi_value OnSetFoldStatusLocked(napi_env env, napi_callback_info info)
809 {
810     size_t argc = 4;
811     napi_value argv[4] = {nullptr};
812     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
813     if (argc < ARGC_ONE) {
814         std::string errMsg = "Invalid args count, need one arg";
815         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
816         return NapiGetUndefined(env);
817     }
818     bool locked = false;
819     if (!ConvertFromJsValue(env, argv[0], locked)) {
820         WLOGFE("[NAPI]Failed to convert parameter to SetFoldStatusLocked");
821         std::string errMsg = "Failed to convert parameter to SetFoldStatusLocked";
822         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM), errMsg));
823         return NapiGetUndefined(env);
824     }
825     DmErrorCode errCode = DM_JS_TO_ERROR_CODE_MAP.at(
826         SingletonContainer::Get<DisplayManager>().SetFoldStatusLockedFromJs(locked));
827     if (errCode != DmErrorCode::DM_OK) {
828         napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode)));
829         return NapiGetUndefined(env);
830     }
831     WLOGI("[NAPI]" PRIu64", SetFoldStatusLocked");
832     return NapiGetUndefined(env);
833 }
834 
OnGetCurrentFoldCreaseRegion(napi_env env,napi_callback_info info)835 napi_value OnGetCurrentFoldCreaseRegion(napi_env env, napi_callback_info info)
836 {
837     size_t argc = 4;
838     napi_value argv[4] = {nullptr};
839     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
840     if (argc >= ARGC_ONE) {
841         napi_throw(env, CreateJsError(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
842         return NapiGetUndefined(env);
843     }
844     sptr<FoldCreaseRegion> region = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
845     WLOGI("[NAPI]" PRIu64", getCurrentFoldCreaseRegion");
846     return CreateJsFoldCreaseRegionObject(env, region);
847 }
848 
CreateJsFoldCreaseRegionObject(napi_env env,sptr<FoldCreaseRegion> region)849 napi_value CreateJsFoldCreaseRegionObject(napi_env env, sptr<FoldCreaseRegion> region)
850 {
851     WLOGI("JsDisplay::CreateJsFoldCreaseRegionObject is called");
852     napi_value objValue = nullptr;
853     napi_create_object(env, &objValue);
854     if (objValue == nullptr) {
855         WLOGFE("Failed to convert prop to jsObject");
856         return NapiGetUndefined(env);
857     }
858     if (region == nullptr) {
859         WLOGFW("Get null fold crease region");
860         return NapiGetUndefined(env);
861     }
862     DisplayId displayId = region->GetDisplayId();
863     std::vector<DMRect> creaseRects = region->GetCreaseRects();
864     napi_set_named_property(env, objValue, "displayId", CreateJsValue(env, static_cast<uint32_t>(displayId)));
865     napi_set_named_property(env, objValue, "creaseRects", CreateJsCreaseRectsArrayObject(env, creaseRects));
866     return objValue;
867 }
868 
CreateJsCreaseRectsArrayObject(napi_env env,std::vector<DMRect> creaseRects)869 napi_value CreateJsCreaseRectsArrayObject(napi_env env, std::vector<DMRect> creaseRects)
870 {
871     napi_value arrayValue = nullptr;
872     napi_create_array_with_length(env, creaseRects.size(), &arrayValue);
873     size_t i = 0;
874     for (const auto& rect : creaseRects) {
875         napi_set_element(env, arrayValue, i++, CreateJsRectObject(env, rect));
876     }
877     return arrayValue;
878 }
879 };
880 
InitDisplayState(napi_env env)881 napi_value InitDisplayState(napi_env env)
882 {
883     WLOGD("InitDisplayState called");
884 
885     if (env == nullptr) {
886         WLOGFE("env is nullptr");
887         return nullptr;
888     }
889 
890     napi_value objValue = nullptr;
891     napi_create_object(env, &objValue);
892     if (objValue == nullptr) {
893         WLOGFE("Failed to get object");
894         return nullptr;
895     }
896     napi_set_named_property(env, objValue, "STATE_UNKNOWN",
897         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_UNKNOWN)));
898     napi_set_named_property(env, objValue, "STATE_OFF",
899         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_OFF)));
900     napi_set_named_property(env, objValue, "STATE_ON",
901         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_ON)));
902     napi_set_named_property(env, objValue, "STATE_DOZE",
903         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_DOZE)));
904     napi_set_named_property(env, objValue, "STATE_DOZE_SUSPEND",
905         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_DOZE_SUSPEND)));
906     napi_set_named_property(env, objValue, "STATE_VR",
907         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_VR)));
908     napi_set_named_property(env, objValue, "STATE_ON_SUSPEND",
909         CreateJsValue(env, static_cast<int32_t>(DisplayStateMode::STATE_ON_SUSPEND)));
910     return objValue;
911 }
912 
InitOrientation(napi_env env)913 napi_value InitOrientation(napi_env env)
914 {
915     WLOGD("InitOrientation called");
916 
917     if (env == nullptr) {
918         WLOGFE("env is nullptr");
919         return nullptr;
920     }
921 
922     napi_value objValue = nullptr;
923     napi_create_object(env, &objValue);
924     if (objValue == nullptr) {
925         WLOGFE("Failed to get object");
926         return nullptr;
927     }
928 
929     napi_set_named_property(env, objValue, "PORTRAIT",
930         CreateJsValue(env, static_cast<uint32_t>(DisplayOrientation::PORTRAIT)));
931     napi_set_named_property(env, objValue, "LANDSCAPE",
932         CreateJsValue(env, static_cast<uint32_t>(DisplayOrientation::LANDSCAPE)));
933     napi_set_named_property(env, objValue, "PORTRAIT_INVERTED",
934         CreateJsValue(env, static_cast<uint32_t>(DisplayOrientation::PORTRAIT_INVERTED)));
935     napi_set_named_property(env, objValue, "LANDSCAPE_INVERTED",
936         CreateJsValue(env, static_cast<uint32_t>(DisplayOrientation::LANDSCAPE_INVERTED)));
937     return objValue;
938 }
939 
InitDisplayErrorCode(napi_env env)940 napi_value InitDisplayErrorCode(napi_env env)
941 {
942     WLOGD("InitDisplayErrorCode called");
943 
944     if (env == nullptr) {
945         WLOGFE("env is nullptr");
946         return nullptr;
947     }
948 
949     napi_value objValue = nullptr;
950     napi_create_object(env, &objValue);
951     if (objValue == nullptr) {
952         WLOGFE("Failed to get object");
953         return nullptr;
954     }
955 
956     napi_set_named_property(env, objValue, "DM_ERROR_NO_PERMISSION",
957         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_NO_PERMISSION)));
958     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_PARAM",
959         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
960     napi_set_named_property(env, objValue, "DM_ERROR_DEVICE_NOT_SUPPORT",
961         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT)));
962     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_SCREEN",
963         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN)));
964     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_CALLING",
965         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_CALLING)));
966     napi_set_named_property(env, objValue, "DM_ERROR_SYSTEM_INNORMAL",
967         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL)));
968 
969     return objValue;
970 }
971 
InitDisplayError(napi_env env)972 napi_value InitDisplayError(napi_env env)
973 {
974     WLOGD("InitDisplayError called");
975 
976     if (env == nullptr) {
977         WLOGFE("env is nullptr");
978         return nullptr;
979     }
980 
981     napi_value objValue = nullptr;
982     napi_create_object(env, &objValue);
983     if (objValue == nullptr) {
984         WLOGFE("Failed to get object");
985         return nullptr;
986     }
987 
988     napi_set_named_property(env, objValue, "DM_ERROR_INIT_DMS_PROXY_LOCKED",
989         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED)));
990     napi_set_named_property(env, objValue, "DM_ERROR_IPC_FAILED",
991         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_IPC_FAILED)));
992     napi_set_named_property(env, objValue, "DM_ERROR_REMOTE_CREATE_FAILED",
993         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_REMOTE_CREATE_FAILED)));
994     napi_set_named_property(env, objValue, "DM_ERROR_NULLPTR",
995         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_NULLPTR)));
996     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_PARAM",
997         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_PARAM)));
998     napi_set_named_property(env, objValue, "DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED",
999         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED)));
1000     napi_set_named_property(env, objValue, "DM_ERROR_DEATH_RECIPIENT",
1001         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_DEATH_RECIPIENT)));
1002     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_MODE_ID",
1003         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_MODE_ID)));
1004     napi_set_named_property(env, objValue, "DM_ERROR_WRITE_DATA_FAILED",
1005         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_WRITE_DATA_FAILED)));
1006     napi_set_named_property(env, objValue, "DM_ERROR_RENDER_SERVICE_FAILED",
1007         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_RENDER_SERVICE_FAILED)));
1008     napi_set_named_property(env, objValue, "DM_ERROR_UNREGISTER_AGENT_FAILED",
1009         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_UNREGISTER_AGENT_FAILED)));
1010     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_CALLING",
1011         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_CALLING)));
1012     napi_set_named_property(env, objValue, "DM_ERROR_UNKNOWN",
1013         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_UNKNOWN)));
1014 
1015     return objValue;
1016 }
1017 
InitFoldStatus(napi_env env)1018 napi_value InitFoldStatus(napi_env env)
1019 {
1020     WLOGD("InitFoldStatus called");
1021 
1022     if (env == nullptr) {
1023         WLOGFE("env is nullptr");
1024         return nullptr;
1025     }
1026 
1027     napi_value objValue = nullptr;
1028     napi_create_object(env, &objValue);
1029     if (objValue == nullptr) {
1030         WLOGFE("Failed to get object");
1031         return nullptr;
1032     }
1033     napi_set_named_property(env, objValue, "FOLD_STATUS_UNKNOWN",
1034         CreateJsValue(env, static_cast<uint32_t>(FoldStatus::UNKNOWN)));
1035     napi_set_named_property(env, objValue, "FOLD_STATUS_EXPANDED",
1036         CreateJsValue(env, static_cast<uint32_t>(FoldStatus::EXPAND)));
1037     napi_set_named_property(env, objValue, "FOLD_STATUS_FOLDED",
1038         CreateJsValue(env, static_cast<uint32_t>(FoldStatus::FOLDED)));
1039     napi_set_named_property(env, objValue, "FOLD_STATUS_HALF_FOLDED",
1040         CreateJsValue(env, static_cast<uint32_t>(FoldStatus::HALF_FOLD)));
1041     return objValue;
1042 }
1043 
InitFoldDisplayMode(napi_env env)1044 napi_value InitFoldDisplayMode(napi_env env)
1045 {
1046     WLOGD("IniFoldDisplayMode called");
1047 
1048     if (env == nullptr) {
1049         WLOGFE("env is nullptr");
1050         return nullptr;
1051     }
1052 
1053     napi_value objValue = nullptr;
1054     napi_create_object(env, &objValue);
1055     if (objValue == nullptr) {
1056         WLOGFE("Failed to get object");
1057         return nullptr;
1058     }
1059 
1060     napi_set_named_property(env, objValue, "FOLD_DISPLAY_MODE_UNKNOWN",
1061         CreateJsValue(env, static_cast<uint32_t>(FoldDisplayMode::UNKNOWN)));
1062     napi_set_named_property(env, objValue, "FOLD_DISPLAY_MODE_FULL",
1063         CreateJsValue(env, static_cast<uint32_t>(FoldDisplayMode::FULL)));
1064     napi_set_named_property(env, objValue, "FOLD_DISPLAY_MODE_MAIN",
1065         CreateJsValue(env, static_cast<uint32_t>(FoldDisplayMode::MAIN)));
1066     napi_set_named_property(env, objValue, "FOLD_DISPLAY_MODE_SUB",
1067         CreateJsValue(env, static_cast<uint32_t>(FoldDisplayMode::SUB)));
1068     napi_set_named_property(env, objValue, "FOLD_DISPLAY_MODE_COORDINATION",
1069         CreateJsValue(env, static_cast<uint32_t>(FoldDisplayMode::COORDINATION)));
1070     return objValue;
1071 }
1072 
InitColorSpace(napi_env env)1073 napi_value InitColorSpace(napi_env env)
1074 {
1075     WLOGD("InitColorSpace called");
1076 
1077     if (env == nullptr) {
1078         WLOGFE("env is nullptr");
1079         return nullptr;
1080     }
1081 
1082     napi_value objValue = nullptr;
1083     napi_create_object(env, &objValue);
1084     if (objValue == nullptr) {
1085         WLOGFE("Failed to get object");
1086         return nullptr;
1087     }
1088 
1089     napi_set_named_property(env, objValue, "UNKNOWN",
1090         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::UNKNOWN)));
1091     napi_set_named_property(env, objValue, "ADOBE_RGB",
1092         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::ADOBE_RGB)));
1093     napi_set_named_property(env, objValue, "BT2020_HLG",
1094         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::BT2020_HLG)));
1095     napi_set_named_property(env, objValue, "BT2020_PQ",
1096         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::BT2020_PQ)));
1097     napi_set_named_property(env, objValue, "BT601_EBU",
1098         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::BT601_EBU)));
1099     napi_set_named_property(env, objValue, "BT601_SMPTE_C",
1100         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::BT601_SMPTE_C)));
1101     napi_set_named_property(env, objValue, "BT709",
1102         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::BT709)));
1103     napi_set_named_property(env, objValue, "P3_HLG",
1104         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::P3_HLG)));
1105     napi_set_named_property(env, objValue, "P3_PQ",
1106         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::P3_PQ)));
1107     napi_set_named_property(env, objValue, "DISPLAY_P3",
1108         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::DISPLAY_P3)));
1109     napi_set_named_property(env, objValue, "SRGB",
1110         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::SRGB)));
1111     napi_set_named_property(env, objValue, "LINEAR_SRGB",
1112         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::LINEAR_SRGB)));
1113     napi_set_named_property(env, objValue, "LINEAR_P3",
1114         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::LINEAR_P3)));
1115     napi_set_named_property(env, objValue, "LINEAR_BT2020",
1116         CreateJsValue(env, static_cast<uint32_t>(ColorSpace::LINEAR_BT2020)));
1117     return objValue;
1118 }
1119 
InitHDRFormat(napi_env env)1120 napi_value InitHDRFormat(napi_env env)
1121 {
1122     WLOGD("InitHDRFormat called");
1123 
1124     if (env == nullptr) {
1125         WLOGFE("env is nullptr");
1126         return nullptr;
1127     }
1128 
1129     napi_value objValue = nullptr;
1130     napi_create_object(env, &objValue);
1131     if (objValue == nullptr) {
1132         WLOGFE("Failed to get object");
1133         return nullptr;
1134     }
1135 
1136     napi_set_named_property(env, objValue, "NONE",
1137         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::NONE)));
1138     napi_set_named_property(env, objValue, "VIDEO_HLG",
1139         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::VIDEO_HLG)));
1140     napi_set_named_property(env, objValue, "VIDEO_HDR10",
1141         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::VIDEO_HDR10)));
1142     napi_set_named_property(env, objValue, "VIDEO_HDR_VIVID",
1143         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::VIDEO_HDR_VIVID)));
1144     napi_set_named_property(env, objValue, "IMAGE_HDR_VIVID_DUAL",
1145         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::IMAGE_HDR_VIVID_DUAL)));
1146     napi_set_named_property(env, objValue, "IMAGE_HDR_VIVID_SINGLE",
1147         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::IMAGE_HDR_VIVID_SINGLE)));
1148     napi_set_named_property(env, objValue, "IMAGE_HDR_ISO_DUAL",
1149         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::IMAGE_HDR_ISO_DUAL)));
1150     napi_set_named_property(env, objValue, "IMAGE_HDR_ISO_SINGLE",
1151         CreateJsValue(env, static_cast<uint32_t>(HDRFormat::IMAGE_HDR_ISO_SINGLE)));
1152     return objValue;
1153 }
1154 
JsDisplayManagerInit(napi_env env,napi_value exportObj)1155 napi_value JsDisplayManagerInit(napi_env env, napi_value exportObj)
1156 {
1157     WLOGD("JsDisplayManagerInit is called");
1158 
1159     if (env == nullptr || exportObj == nullptr) {
1160         WLOGFE("JsDisplayManagerInit env or exportObj is nullptr");
1161         return nullptr;
1162     }
1163 
1164     std::unique_ptr<JsDisplayManager> jsDisplayManager = std::make_unique<JsDisplayManager>(env);
1165     napi_wrap(env, exportObj, jsDisplayManager.release(), JsDisplayManager::Finalizer, nullptr, nullptr);
1166 
1167     napi_set_named_property(env, exportObj, "DisplayState", InitDisplayState(env));
1168     napi_set_named_property(env, exportObj, "Orientation", InitOrientation(env));
1169     napi_set_named_property(env, exportObj, "DmErrorCode", InitDisplayErrorCode(env));
1170     napi_set_named_property(env, exportObj, "DMError", InitDisplayError(env));
1171     napi_set_named_property(env, exportObj, "FoldStatus", InitFoldStatus(env));
1172     napi_set_named_property(env, exportObj, "FoldDisplayMode", InitFoldDisplayMode(env));
1173     napi_set_named_property(env, exportObj, "ColorSpace", InitColorSpace(env));
1174     napi_set_named_property(env, exportObj, "HDRFormat", InitHDRFormat(env));
1175 
1176     const char *moduleName = "JsDisplayManager";
1177     BindNativeFunction(env, exportObj, "getDefaultDisplay", moduleName, JsDisplayManager::GetDefaultDisplay);
1178     BindNativeFunction(env, exportObj, "getDefaultDisplaySync", moduleName, JsDisplayManager::GetDefaultDisplaySync);
1179     BindNativeFunction(env, exportObj, "getPrimaryDisplaySync", moduleName, JsDisplayManager::GetPrimaryDisplaySync);
1180     BindNativeFunction(env, exportObj, "getDisplayByIdSync", moduleName, JsDisplayManager::GetDisplayByIdSync);
1181     BindNativeFunction(env, exportObj, "getAllDisplay", moduleName, JsDisplayManager::GetAllDisplay);
1182     BindNativeFunction(env, exportObj, "getAllDisplays", moduleName, JsDisplayManager::GetAllDisplays);
1183     BindNativeFunction(env, exportObj, "hasPrivateWindow", moduleName, JsDisplayManager::HasPrivateWindow);
1184     BindNativeFunction(env, exportObj, "isFoldable", moduleName, JsDisplayManager::IsFoldable);
1185     BindNativeFunction(env, exportObj, "isCaptured", moduleName, JsDisplayManager::IsCaptured);
1186     BindNativeFunction(env, exportObj, "getFoldStatus", moduleName, JsDisplayManager::GetFoldStatus);
1187     BindNativeFunction(env, exportObj, "getFoldDisplayMode", moduleName, JsDisplayManager::GetFoldDisplayMode);
1188     BindNativeFunction(env, exportObj, "setFoldDisplayMode", moduleName, JsDisplayManager::SetFoldDisplayMode);
1189     BindNativeFunction(env, exportObj, "setFoldStatusLocked", moduleName, JsDisplayManager::SetFoldStatusLocked);
1190     BindNativeFunction(env, exportObj, "getCurrentFoldCreaseRegion", moduleName,
1191         JsDisplayManager::GetCurrentFoldCreaseRegion);
1192     BindNativeFunction(env, exportObj, "on", moduleName, JsDisplayManager::RegisterDisplayManagerCallback);
1193     BindNativeFunction(env, exportObj, "off", moduleName, JsDisplayManager::UnregisterDisplayManagerCallback);
1194     BindNativeFunction(env, exportObj, "getAllDisplayPhysicalResolution", moduleName,
1195         JsDisplayManager::GetAllDisplayPhysicalResolution);
1196     return NapiGetUndefined(env);
1197 }
1198 }  // namespace Rosen
1199 }  // namespace OHOS
1200