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