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