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