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