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(NativeEngine * engine)41 explicit JsDisplayManager(NativeEngine* engine) {
42 }
43
44 ~JsDisplayManager() = default;
45
Finalizer(NativeEngine * engine,void * data,void * hint)46 static void Finalizer(NativeEngine* engine, void* data, void* hint)
47 {
48 WLOGI("Finalizer is called");
49 std::unique_ptr<JsDisplayManager>(static_cast<JsDisplayManager*>(data));
50 }
51
GetDefaultDisplay(NativeEngine * engine,NativeCallbackInfo * info)52 static NativeValue* GetDefaultDisplay(NativeEngine* engine, NativeCallbackInfo* info)
53 {
54 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
55 return (me != nullptr) ? me->OnGetDefaultDisplay(*engine, *info) : nullptr;
56 }
57
GetDefaultDisplaySync(NativeEngine * engine,NativeCallbackInfo * info)58 static NativeValue* GetDefaultDisplaySync(NativeEngine* engine, NativeCallbackInfo* info)
59 {
60 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
61 return (me != nullptr) ? me->OnGetDefaultDisplaySync(*engine, *info) : nullptr;
62 }
63
GetAllDisplay(NativeEngine * engine,NativeCallbackInfo * info)64 static NativeValue* GetAllDisplay(NativeEngine* engine, NativeCallbackInfo* info)
65 {
66 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
67 return (me != nullptr) ? me->OnGetAllDisplay(*engine, *info) : nullptr;
68 }
69
GetAllDisplays(NativeEngine * engine,NativeCallbackInfo * info)70 static NativeValue* GetAllDisplays(NativeEngine* engine, NativeCallbackInfo* info)
71 {
72 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
73 return (me != nullptr) ? me->OnGetAllDisplays(*engine, *info) : nullptr;
74 }
75
RegisterDisplayManagerCallback(NativeEngine * engine,NativeCallbackInfo * info)76 static NativeValue* RegisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info)
77 {
78 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
79 return (me != nullptr) ? me->OnRegisterDisplayManagerCallback(*engine, *info) : nullptr;
80 }
81
UnregisterDisplayManagerCallback(NativeEngine * engine,NativeCallbackInfo * info)82 static NativeValue* UnregisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info)
83 {
84 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
85 return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(*engine, *info) : nullptr;
86 }
87
HasPrivateWindow(NativeEngine * engine,NativeCallbackInfo * info)88 static NativeValue* HasPrivateWindow(NativeEngine* engine, NativeCallbackInfo* info)
89 {
90 JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
91 return (me != nullptr) ? me->OnHasPrivateWindow(*engine, *info) : nullptr;
92 }
93
IsFoldable(NativeEngine * engine,NativeCallbackInfo * info)94 static NativeValue* IsFoldable(NativeEngine* engine, NativeCallbackInfo* info)
95 {
96 auto* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
97 return (me != nullptr) ? me->OnIsFoldable(*engine, *info) : nullptr;
98 }
99
GetFoldStatus(NativeEngine * engine,NativeCallbackInfo * info)100 static NativeValue* GetFoldStatus(NativeEngine* engine, NativeCallbackInfo* info)
101 {
102 auto* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
103 return (me != nullptr) ? me->OnGetFoldStatus(*engine, *info) : nullptr;
104 }
105
GetFoldDisplayMode(NativeEngine * engine,NativeCallbackInfo * info)106 static NativeValue* GetFoldDisplayMode(NativeEngine* engine, NativeCallbackInfo* info)
107 {
108 auto* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
109 return (me != nullptr) ? me->OnGetFoldDisplayMode(*engine, *info) : nullptr;
110 }
111
SetFoldDisplayMode(NativeEngine * engine,NativeCallbackInfo * info)112 static NativeValue* SetFoldDisplayMode(NativeEngine* engine, NativeCallbackInfo* info)
113 {
114 auto* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
115 return (me != nullptr) ? me->OnSetFoldDisplayMode(*engine, *info) : nullptr;
116 }
117
GetCurrentFoldCreaseRegion(NativeEngine * engine,NativeCallbackInfo * info)118 static NativeValue* GetCurrentFoldCreaseRegion(NativeEngine* engine, NativeCallbackInfo* info)
119 {
120 auto* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
121 return (me != nullptr) ? me->OnGetCurrentFoldCreaseRegion(*engine, *info) : nullptr;
122 }
123
124 private:
125 std::map<std::string, std::map<std::unique_ptr<NativeReference>, sptr<JsDisplayListener>>> jsCbMap_;
126 std::mutex mtx_;
127
OnGetDefaultDisplay(NativeEngine & engine,NativeCallbackInfo & info)128 NativeValue* OnGetDefaultDisplay(NativeEngine& engine, NativeCallbackInfo& info)
129 {
130 WLOGI("GetDefaultDisplay called");
131 DMError errCode = DMError::DM_OK;
132 if (info.argc != 0 && info.argc != ARGC_ONE) {
133 WLOGFE("OnGetDefaultDisplay params not match");
134 errCode = DMError::DM_ERROR_INVALID_PARAM;
135 }
136
137 AsyncTask::CompleteCallback complete =
138 [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
139 if (errCode != DMError::DM_OK) {
140 task.Reject(engine, CreateJsError(engine,
141 static_cast<int32_t>(errCode), "JsDisplayManager::OnGetDefaultDisplay failed."));
142 }
143 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Async:GetDefaultDisplay");
144 sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
145 if (display != nullptr) {
146 task.Resolve(engine, CreateJsDisplayObject(engine, display));
147 WLOGI("OnGetDefaultDisplay success");
148 } else {
149 task.Reject(engine, CreateJsError(engine,
150 static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetDefaultDisplay failed."));
151 }
152 };
153 NativeValue* lastParam = nullptr;
154 if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) {
155 lastParam = info.argv[0];
156 }
157 NativeValue* result = nullptr;
158 AsyncTask::Schedule("JsDisplayManager::OnGetDefaultDisplay",
159 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
160 return result;
161 }
162
OnGetDefaultDisplaySync(NativeEngine & engine,NativeCallbackInfo & info)163 NativeValue* OnGetDefaultDisplaySync(NativeEngine& engine, NativeCallbackInfo& info)
164 {
165 WLOGI("GetDefaultDisplaySync called");
166 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Sync:GetDefaultDisplay");
167 sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplaySync();
168 if (display == nullptr) {
169 WLOGFE("OnGetDefaultDisplaySync, display is nullptr.");
170 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN)));
171 return engine.CreateUndefined();
172 }
173 return CreateJsDisplayObject(engine, display);
174 }
175
OnGetAllDisplay(NativeEngine & engine,NativeCallbackInfo & info)176 NativeValue* OnGetAllDisplay(NativeEngine& engine, NativeCallbackInfo& info)
177 {
178 WLOGI("GetAllDisplay called");
179 DMError errCode = DMError::DM_OK;
180 if (info.argc != 0 && info.argc != ARGC_ONE) {
181 WLOGFE("OnGetAllDisplay params not match");
182 errCode = DMError::DM_ERROR_INVALID_PARAM;
183 }
184
185 AsyncTask::CompleteCallback complete =
186 [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
187 if (errCode != DMError::DM_OK) {
188 task.Reject(engine, CreateJsError(engine,
189 static_cast<int32_t>(errCode), "JsDisplayManager::OnGetAllDisplay failed."));
190 }
191 std::vector<sptr<Display>> displays = SingletonContainer::Get<DisplayManager>().GetAllDisplays();
192 if (!displays.empty()) {
193 task.Resolve(engine, CreateJsDisplayArrayObject(engine, displays));
194 WLOGI("GetAllDisplays success");
195 } else {
196 task.Reject(engine, CreateJsError(engine,
197 static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetAllDisplay failed."));
198 }
199 };
200
201 NativeValue* lastParam = nullptr;
202 if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) {
203 lastParam = info.argv[0];
204 }
205 NativeValue* result = nullptr;
206 AsyncTask::Schedule("JsDisplayManager::OnGetAllDisplay",
207 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
208 return result;
209 }
210
OnGetAllDisplays(NativeEngine & engine,NativeCallbackInfo & info)211 NativeValue* OnGetAllDisplays(NativeEngine& engine, NativeCallbackInfo& info)
212 {
213 WLOGI("GetAllDisplays is called");
214
215 AsyncTask::CompleteCallback complete =
216 [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
217 std::vector<sptr<Display>> displays = SingletonContainer::Get<DisplayManager>().GetAllDisplays();
218 if (!displays.empty()) {
219 task.Resolve(engine, CreateJsDisplayArrayObject(engine, displays));
220 WLOGI("GetAllDisplays success");
221 } else {
222 task.Reject(engine, CreateJsError(engine,
223 static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN),
224 "JsDisplayManager::OnGetAllDisplays failed."));
225 }
226 };
227
228 NativeValue* lastParam = nullptr;
229 if (info.argc >= ARGC_ONE && info.argv[ARGC_ONE - 1] != nullptr &&
230 info.argv[ARGC_ONE - 1]->TypeOf() == NATIVE_FUNCTION) {
231 lastParam = info.argv[0];
232 }
233 NativeValue* result = nullptr;
234 AsyncTask::Schedule("JsDisplayManager::OnGetAllDisplays",
235 engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
236 return result;
237 }
238
RegisterDisplayListenerWithType(NativeEngine & engine,const std::string & type,NativeValue * value)239 DMError RegisterDisplayListenerWithType(NativeEngine& engine, const std::string& type, NativeValue* value)
240 {
241 if (IfCallbackRegistered(type, value)) {
242 WLOGFE("RegisterDisplayListenerWithType callback already registered!");
243 return DMError::DM_ERROR_INVALID_PARAM;
244 }
245 std::unique_ptr<NativeReference> callbackRef;
246 callbackRef.reset(engine.CreateReference(value, 1));
247 sptr<JsDisplayListener> displayListener = new(std::nothrow) JsDisplayListener(&engine);
248 DMError ret = DMError::DM_OK;
249 if (displayListener == nullptr) {
250 WLOGFE("displayListener is nullptr");
251 return DMError::DM_ERROR_INVALID_PARAM;
252 }
253 if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
254 ret = SingletonContainer::Get<DisplayManager>().RegisterDisplayListener(displayListener);
255 } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
256 ret = SingletonContainer::Get<DisplayManager>().RegisterPrivateWindowListener(displayListener);
257 } else if (type == EVENT_FOLD_STATUS_CHANGED) {
258 ret = SingletonContainer::Get<DisplayManager>().RegisterFoldStatusListener(displayListener);
259 } else if (type == EVENT_DISPLAY_MODE_CHANGED) {
260 ret = SingletonContainer::Get<DisplayManager>().RegisterDisplayModeListener(displayListener);
261 } else {
262 WLOGFE("RegisterDisplayListenerWithType failed, %{public}s not support", type.c_str());
263 return DMError::DM_ERROR_INVALID_PARAM;
264 }
265 if (ret != DMError::DM_OK) {
266 WLOGFE("RegisterDisplayListenerWithType failed, ret: %{public}u", ret);
267 return ret;
268 }
269 displayListener->AddCallback(type, value);
270 jsCbMap_[type][std::move(callbackRef)] = displayListener;
271 return DMError::DM_OK;
272 }
273
IfCallbackRegistered(const std::string & type,NativeValue * jsListenerObject)274 bool IfCallbackRegistered(const std::string& type, NativeValue* jsListenerObject)
275 {
276 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
277 WLOGI("IfCallbackRegistered methodName %{public}s not registered!", type.c_str());
278 return false;
279 }
280
281 for (auto& iter : jsCbMap_[type]) {
282 if (jsListenerObject->StrictEquals(iter.first->Get())) {
283 WLOGFE("IfCallbackRegistered callback already registered!");
284 return true;
285 }
286 }
287 return false;
288 }
289
UnregisterAllDisplayListenerWithType(const std::string & type)290 DMError UnregisterAllDisplayListenerWithType(const std::string& type)
291 {
292 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
293 WLOGI("UnregisterAllDisplayListenerWithType methodName %{public}s not registered!",
294 type.c_str());
295 return DMError::DM_ERROR_INVALID_PARAM;
296 }
297 DMError ret = DMError::DM_OK;
298 for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
299 it->second->RemoveAllCallback();
300 if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
301 sptr<DisplayManager::IDisplayListener> thisListener(it->second);
302 ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
303 WLOGFD("unregister displayListener, type: %{public}s ret: %{public}u", type.c_str(), ret);
304 } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
305 sptr<DisplayManager::IPrivateWindowListener> thisListener(it->second);
306 ret = SingletonContainer::Get<DisplayManager>().UnregisterPrivateWindowListener(thisListener);
307 WLOGFD("unregister privateWindowListener, ret: %{public}u", ret);
308 }
309 jsCbMap_[type].erase(it++);
310 }
311 jsCbMap_.erase(type);
312 return ret;
313 }
314
UnRegisterDisplayListenerWithType(const std::string & type,NativeValue * value)315 DMError UnRegisterDisplayListenerWithType(const std::string& type, NativeValue* value)
316 {
317 if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
318 WLOGI("UnRegisterDisplayListenerWithType methodName %{public}s not registered!",
319 type.c_str());
320 return DMError::DM_ERROR_INVALID_PARAM;
321 }
322 DMError ret = DMError::DM_OK;
323 for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
324 if (value->StrictEquals(it->first->Get())) {
325 it->second->RemoveCallback(type, value);
326 if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
327 sptr<DisplayManager::IDisplayListener> thisListener(it->second);
328 ret = SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
329 WLOGFD("unregister displayListener, type: %{public}s ret: %{public}u", type.c_str(), ret);
330 } else if (type == EVENT_PRIVATE_MODE_CHANGE) {
331 sptr<DisplayManager::IPrivateWindowListener> thisListener(it->second);
332 ret = SingletonContainer::Get<DisplayManager>().UnregisterPrivateWindowListener(thisListener);
333 WLOGFD("unregister privateWindowListener, ret: %{public}u", ret);
334 } else {
335 ret = DMError::DM_ERROR_INVALID_PARAM;
336 WLOGFE("unregister displaylistener with type failed, %{public}s not matched", type.c_str());
337 }
338 jsCbMap_[type].erase(it++);
339 break;
340 } else {
341 it++;
342 }
343 }
344 if (jsCbMap_[type].empty()) {
345 jsCbMap_.erase(type);
346 }
347 return ret;
348 }
349
OnRegisterDisplayManagerCallback(NativeEngine & engine,NativeCallbackInfo & info)350 NativeValue* OnRegisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info)
351 {
352 WLOGI("OnRegisterDisplayManagerCallback is called");
353 if (info.argc < ARGC_TWO) {
354 WLOGFE("JsDisplayManager Params not match: %{public}zu", info.argc);
355 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
356 return engine.CreateUndefined();
357 }
358 std::string cbType;
359 if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
360 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
361 WLOGFE("Failed to convert parameter to callbackType");
362 return engine.CreateUndefined();
363 }
364 NativeValue* value = info.argv[INDEX_ONE];
365 if (value == nullptr) {
366 WLOGI("OnRegisterDisplayManagerCallback info->argv[1] is nullptr");
367 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
368 return engine.CreateUndefined();
369 }
370 if (!value->IsCallable()) {
371 WLOGI("OnRegisterDisplayManagerCallback info->argv[1] is not callable");
372 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
373 return engine.CreateUndefined();
374 }
375 std::lock_guard<std::mutex> lock(mtx_);
376 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(RegisterDisplayListenerWithType(engine, cbType, value));
377 if (ret != DmErrorCode::DM_OK) {
378 WLOGFE("Failed to register display listener with type");
379 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
380 return engine.CreateUndefined();
381 }
382 return engine.CreateUndefined();
383 }
384
OnUnregisterDisplayManagerCallback(NativeEngine & engine,NativeCallbackInfo & info)385 NativeValue* OnUnregisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info)
386 {
387 WLOGI("OnUnregisterDisplayCallback is called");
388 if (info.argc < ARGC_ONE) {
389 WLOGFE("JsDisplayManager Params not match %{public}zu", info.argc);
390 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
391 return engine.CreateUndefined();
392 }
393 std::string cbType;
394 if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
395 WLOGFE("Failed to convert parameter to callbackType");
396 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
397 return engine.CreateUndefined();
398 }
399 std::lock_guard<std::mutex> lock(mtx_);
400 DmErrorCode ret;
401 if (info.argc == ARGC_ONE) {
402 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
403 } else {
404 NativeValue* value = info.argv[INDEX_ONE];
405 if ((value == nullptr) || (!value->IsCallable())) {
406 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(cbType));
407 } else {
408 ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(cbType, value));
409 }
410 }
411 if (ret != DmErrorCode::DM_OK) {
412 WLOGFE("failed to unregister display listener with type");
413 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
414 return engine.CreateUndefined();
415 }
416 return engine.CreateUndefined();
417 }
418
OnHasPrivateWindow(NativeEngine & engine,NativeCallbackInfo & info)419 NativeValue* OnHasPrivateWindow(NativeEngine& engine, NativeCallbackInfo& info)
420 {
421 bool hasPrivateWindow = false;
422 if (info.argc < ARGC_ONE) {
423 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
424 return engine.CreateUndefined();
425 }
426 int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
427 if (!ConvertFromJsValue(engine, info.argv[0], displayId)) {
428 WLOGFE("[NAPI]Failed to convert parameter to displayId");
429 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
430 return engine.CreateUndefined();
431 }
432 if (displayId < 0) {
433 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
434 return engine.CreateUndefined();
435 }
436 DmErrorCode errCode = DM_JS_TO_ERROR_CODE_MAP.at(
437 SingletonContainer::Get<DisplayManager>().HasPrivateWindow(displayId, hasPrivateWindow));
438 WLOGI("[NAPI]Display id = %{public}" PRIu64", hasPrivateWindow = %{public}u err = %{public}d",
439 static_cast<uint64_t>(displayId), hasPrivateWindow, errCode);
440 if (errCode != DmErrorCode::DM_OK) {
441 engine.Throw(CreateJsError(engine, static_cast<int32_t>(errCode)));
442 return engine.CreateUndefined();
443 }
444 return engine.CreateBoolean(hasPrivateWindow);
445 }
446
CreateJsDisplayArrayObject(NativeEngine & engine,std::vector<sptr<Display>> & displays)447 NativeValue* CreateJsDisplayArrayObject(NativeEngine& engine, std::vector<sptr<Display>>& displays)
448 {
449 WLOGI("CreateJsDisplayArrayObject is called");
450 NativeValue* arrayValue = engine.CreateArray(displays.size());
451 NativeArray* array = ConvertNativeValueTo<NativeArray>(arrayValue);
452 if (array == nullptr) {
453 WLOGFE("Failed to create display array");
454 return engine.CreateUndefined();
455 }
456 int32_t i = 0;
457 for (auto& display : displays) {
458 if (display == nullptr) {
459 continue;
460 }
461 array->SetElement(i++, CreateJsDisplayObject(engine, display));
462 }
463 return arrayValue;
464 }
465
OnIsFoldable(NativeEngine & engine,NativeCallbackInfo & info)466 NativeValue* OnIsFoldable(NativeEngine& engine, NativeCallbackInfo& info)
467 {
468 if (info.argc >= ARGC_ONE) {
469 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
470 return engine.CreateUndefined();
471 }
472 bool foldable = SingletonContainer::Get<DisplayManager>().IsFoldable();
473 WLOGI("[NAPI]" PRIu64", isFoldable = %{public}u", foldable);
474 return engine.CreateBoolean(foldable);
475 }
476
OnGetFoldStatus(NativeEngine & engine,NativeCallbackInfo & info)477 NativeValue* OnGetFoldStatus(NativeEngine& engine, NativeCallbackInfo& info)
478 {
479 if (info.argc >= ARGC_ONE) {
480 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
481 return engine.CreateUndefined();
482 }
483 FoldStatus status = SingletonContainer::Get<DisplayManager>().GetFoldStatus();
484 WLOGI("[NAPI]" PRIu64", getFoldStatus = %{public}u", status);
485 return CreateJsValue(engine, status);
486 }
487
OnGetFoldDisplayMode(NativeEngine & engine,NativeCallbackInfo & info)488 NativeValue* OnGetFoldDisplayMode(NativeEngine& engine, NativeCallbackInfo& info)
489 {
490 if (info.argc >= ARGC_ONE) {
491 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
492 return engine.CreateUndefined();
493 }
494 FoldDisplayMode mode = SingletonContainer::Get<DisplayManager>().GetFoldDisplayMode();
495 WLOGI("[NAPI]" PRIu64", getFoldDisplayMode = %{public}u", mode);
496 return CreateJsValue(engine, mode);
497 }
498
OnSetFoldDisplayMode(NativeEngine & engine,NativeCallbackInfo & info)499 NativeValue* OnSetFoldDisplayMode(NativeEngine& engine, NativeCallbackInfo& info)
500 {
501 if (info.argc < ARGC_ONE) {
502 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
503 return engine.CreateUndefined();
504 }
505 FoldDisplayMode mode = FoldDisplayMode::UNKNOWN;
506 if (!ConvertFromJsValue(engine, info.argv[0], mode)) {
507 WLOGFE("[NAPI]Failed to convert parameter to FoldDisplayMode");
508 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
509 return engine.CreateUndefined();
510 }
511 SingletonContainer::Get<DisplayManager>().SetFoldDisplayMode(mode);
512 WLOGI("[NAPI]" PRIu64", setFoldDisplayMode");
513 return engine.CreateUndefined();
514 }
515
OnGetCurrentFoldCreaseRegion(NativeEngine & engine,NativeCallbackInfo & info)516 NativeValue* OnGetCurrentFoldCreaseRegion(NativeEngine& engine, NativeCallbackInfo& info)
517 {
518 if (info.argc >= ARGC_ONE) {
519 engine.Throw(CreateJsError(engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
520 return engine.CreateUndefined();
521 }
522 sptr<FoldCreaseRegion> region = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
523 WLOGI("[NAPI]" PRIu64", getCurrentFoldCreaseRegion");
524 return CreateJsFoldCreaseRegionObject(engine, region);
525 }
526
CreateJsFoldCreaseRegionObject(NativeEngine & engine,sptr<FoldCreaseRegion> region)527 NativeValue* CreateJsFoldCreaseRegionObject(NativeEngine& engine, sptr<FoldCreaseRegion> region)
528 {
529 WLOGI("JsDisplay::CreateJsFoldCreaseRegionObject is called");
530 NativeValue* objValue = engine.CreateObject();
531 auto* object = ConvertNativeValueTo<NativeObject>(objValue);
532 if (object == nullptr) {
533 WLOGFE("Failed to convert prop to jsObject");
534 return engine.CreateUndefined();
535 }
536 if (region == nullptr) {
537 WLOGFE("Get null fold crease region");
538 return engine.CreateUndefined();
539 }
540 DisplayId displayId = region->GetDisplayId();
541 std::vector<DMRect> creaseRects = region->GetCreaseRects();
542 object->SetProperty("displayId", CreateJsValue(engine, static_cast<uint32_t>(displayId)));
543 object->SetProperty("creaseRects", CreateJsCreaseRectsArrayObject(engine, creaseRects));
544 return objValue;
545 }
546
CreateJsCreaseRectsArrayObject(NativeEngine & engine,std::vector<DMRect> creaseRects)547 NativeValue* CreateJsCreaseRectsArrayObject(NativeEngine& engine, std::vector<DMRect> creaseRects)
548 {
549 NativeValue* arrayValue = engine.CreateArray(creaseRects.size());
550 auto* array = ConvertNativeValueTo<NativeArray>(arrayValue);
551 size_t i = 0;
552 for (const auto& rect : creaseRects) {
553 array->SetElement(i++, CreateJsRectObject(engine, rect));
554 }
555 return arrayValue;
556 }
557 };
558
InitDisplayState(NativeEngine * engine)559 NativeValue* InitDisplayState(NativeEngine* engine)
560 {
561 WLOGI("InitDisplayState called");
562
563 if (engine == nullptr) {
564 WLOGFE("engine is nullptr");
565 return nullptr;
566 }
567
568 NativeValue *objValue = engine->CreateObject();
569 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
570 if (object == nullptr) {
571 WLOGFE("Failed to get object");
572 return nullptr;
573 }
574
575 object->SetProperty("STATE_UNKNOWN", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_UNKNOWN)));
576 object->SetProperty("STATE_OFF", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_OFF)));
577 object->SetProperty("STATE_ON", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_ON)));
578 object->SetProperty("STATE_DOZE",
579 CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_DOZE)));
580 object->SetProperty("STATE_DOZE_SUSPEND",
581 CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_DOZE_SUSPEND)));
582 object->SetProperty("STATE_VR",
583 CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_VR)));
584 object->SetProperty("STATE_ON_SUSPEND",
585 CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_ON_SUSPEND)));
586 return objValue;
587 }
588
InitOrientation(NativeEngine * engine)589 NativeValue* InitOrientation(NativeEngine* engine)
590 {
591 WLOGI("InitOrientation called");
592
593 if (engine == nullptr) {
594 WLOGFE("engine is nullptr");
595 return nullptr;
596 }
597
598 NativeValue *objValue = engine->CreateObject();
599 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
600 if (object == nullptr) {
601 WLOGFE("Failed to get object");
602 return nullptr;
603 }
604
605 object->SetProperty("PORTRAIT", CreateJsValue(*engine, static_cast<uint32_t>(DisplayOrientation::PORTRAIT)));
606 object->SetProperty("LANDSCAPE", CreateJsValue(*engine, static_cast<uint32_t>(DisplayOrientation::LANDSCAPE)));
607 object->SetProperty("PORTRAIT_INVERTED",
608 CreateJsValue(*engine, static_cast<uint32_t>(DisplayOrientation::PORTRAIT_INVERTED)));
609 object->SetProperty("LANDSCAPE_INVERTED",
610 CreateJsValue(*engine, static_cast<uint32_t>(DisplayOrientation::LANDSCAPE_INVERTED)));
611 return objValue;
612 }
613
InitDisplayErrorCode(NativeEngine * engine)614 NativeValue* InitDisplayErrorCode(NativeEngine* engine)
615 {
616 WLOGI("InitDisplayErrorCode called");
617
618 if (engine == nullptr) {
619 WLOGFE("engine is nullptr");
620 return nullptr;
621 }
622
623 NativeValue *objValue = engine->CreateObject();
624 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
625 if (object == nullptr) {
626 WLOGFE("Failed to get object");
627 return nullptr;
628 }
629
630 object->SetProperty("DM_ERROR_NO_PERMISSION",
631 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_NO_PERMISSION)));
632 object->SetProperty("DM_ERROR_INVALID_PARAM",
633 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
634 object->SetProperty("DM_ERROR_DEVICE_NOT_SUPPORT",
635 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT)));
636 object->SetProperty("DM_ERROR_INVALID_SCREEN",
637 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN)));
638 object->SetProperty("DM_ERROR_INVALID_CALLING",
639 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_CALLING)));
640 object->SetProperty("DM_ERROR_SYSTEM_INNORMAL",
641 CreateJsValue(*engine, static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL)));
642
643 return objValue;
644 }
645
InitDisplayError(NativeEngine * engine)646 NativeValue* InitDisplayError(NativeEngine* engine)
647 {
648 WLOGI("InitDisplayError called");
649
650 if (engine == nullptr) {
651 WLOGFE("engine is nullptr");
652 return nullptr;
653 }
654
655 NativeValue *objValue = engine->CreateObject();
656 NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
657 if (object == nullptr) {
658 WLOGFE("Failed to get object");
659 return nullptr;
660 }
661
662 object->SetProperty("DM_ERROR_INIT_DMS_PROXY_LOCKED",
663 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED)));
664 object->SetProperty("DM_ERROR_IPC_FAILED",
665 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_IPC_FAILED)));
666 object->SetProperty("DM_ERROR_REMOTE_CREATE_FAILED",
667 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_REMOTE_CREATE_FAILED)));
668 object->SetProperty("DM_ERROR_NULLPTR",
669 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_NULLPTR)));
670 object->SetProperty("DM_ERROR_INVALID_PARAM",
671 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_INVALID_PARAM)));
672 object->SetProperty("DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED",
673 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED)));
674 object->SetProperty("DM_ERROR_DEATH_RECIPIENT",
675 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_DEATH_RECIPIENT)));
676 object->SetProperty("DM_ERROR_INVALID_MODE_ID",
677 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_INVALID_MODE_ID)));
678 object->SetProperty("DM_ERROR_WRITE_DATA_FAILED",
679 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_WRITE_DATA_FAILED)));
680 object->SetProperty("DM_ERROR_RENDER_SERVICE_FAILED",
681 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_RENDER_SERVICE_FAILED)));
682 object->SetProperty("DM_ERROR_UNREGISTER_AGENT_FAILED",
683 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_UNREGISTER_AGENT_FAILED)));
684 object->SetProperty("DM_ERROR_INVALID_CALLING",
685 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_INVALID_CALLING)));
686 object->SetProperty("DM_ERROR_UNKNOWN",
687 CreateJsValue(*engine, static_cast<int32_t>(DMError::DM_ERROR_UNKNOWN)));
688
689 return objValue;
690 }
691
InitFoldStatus(NativeEngine * engine)692 NativeValue* InitFoldStatus(NativeEngine* engine)
693 {
694 WLOGI("InitFoldStatus called");
695
696 if (engine == nullptr) {
697 WLOGFE("engine is nullptr");
698 return nullptr;
699 }
700
701 NativeValue* objValue = engine->CreateObject();
702 auto* object = ConvertNativeValueTo<NativeObject>(objValue);
703 if (object == nullptr) {
704 WLOGFE("Failed to get object");
705 return nullptr;
706 }
707 object->SetProperty("FOLD_STATUS_UNKNOWN", CreateJsValue(*engine, static_cast<uint32_t>(FoldStatus::UNKNOWN)));
708 object->SetProperty("FOLD_STATUS_EXPANDED", CreateJsValue(*engine, static_cast<uint32_t>(FoldStatus::EXPAND)));
709 object->SetProperty("FOLD_STATUS_FOLDED", CreateJsValue(*engine, static_cast<uint32_t>(FoldStatus::FOLDED)));
710 object->SetProperty("FOLD_STATUS_HALF_FOLDED",
711 CreateJsValue(*engine, static_cast<uint32_t>(FoldStatus::HALF_FOLD)));
712 return objValue;
713 }
714
InitFoldDisplayMode(NativeEngine * engine)715 NativeValue* InitFoldDisplayMode(NativeEngine* engine)
716 {
717 WLOGI("IniFoldDisplayMode called");
718
719 if (engine == nullptr) {
720 WLOGFE("engine is nullptr");
721 return nullptr;
722 }
723
724 NativeValue* objValue = engine->CreateObject();
725 auto* object = ConvertNativeValueTo<NativeObject>(objValue);
726 if (object == nullptr) {
727 WLOGFE("Failed to get object");
728 return nullptr;
729 }
730
731 object->SetProperty("FOLD_DISPLAY_MODE_UNKNOWN",
732 CreateJsValue(*engine, static_cast<uint32_t>(FoldDisplayMode::UNKNOWN)));
733 object->SetProperty("FOLD_DISPLAY_MODE_FULL", CreateJsValue(*engine, static_cast<uint32_t>(FoldDisplayMode::FULL)));
734 object->SetProperty("FOLD_DISPLAY_MODE_MAIN", CreateJsValue(*engine, static_cast<uint32_t>(FoldDisplayMode::MAIN)));
735 object->SetProperty("FOLD_DISPLAY_MODE_SUB", CreateJsValue(*engine, static_cast<uint32_t>(FoldDisplayMode::SUB)));
736 object->SetProperty("FOLD_DISPLAY_MODE_COORDINATION",
737 CreateJsValue(*engine, static_cast<uint32_t>(FoldDisplayMode::COORDINATION)));
738 return objValue;
739 }
740
JsDisplayManagerInit(NativeEngine * engine,NativeValue * exportObj)741 NativeValue* JsDisplayManagerInit(NativeEngine* engine, NativeValue* exportObj)
742 {
743 WLOGI("JsDisplayManagerInit is called");
744
745 if (engine == nullptr || exportObj == nullptr) {
746 WLOGFE("JsDisplayManagerInit engine or exportObj is nullptr");
747 return nullptr;
748 }
749
750 NativeObject* object = ConvertNativeValueTo<NativeObject>(exportObj);
751 if (object == nullptr) {
752 WLOGFE("JsDisplayManagerInit object is nullptr");
753 return nullptr;
754 }
755
756 std::unique_ptr<JsDisplayManager> jsDisplayManager = std::make_unique<JsDisplayManager>(engine);
757 object->SetNativePointer(jsDisplayManager.release(), JsDisplayManager::Finalizer, nullptr);
758
759 object->SetProperty("DisplayState", InitDisplayState(engine));
760 object->SetProperty("Orientation", InitOrientation(engine));
761 object->SetProperty("DmErrorCode", InitDisplayErrorCode(engine));
762 object->SetProperty("DMError", InitDisplayError(engine));
763 object->SetProperty("FoldStatus", InitFoldStatus(engine));
764 object->SetProperty("FoldDisplayMode", InitFoldDisplayMode(engine));
765
766 const char *moduleName = "JsDisplayManager";
767 BindNativeFunction(*engine, *object, "getDefaultDisplay", moduleName, JsDisplayManager::GetDefaultDisplay);
768 BindNativeFunction(*engine, *object, "getDefaultDisplaySync", moduleName, JsDisplayManager::GetDefaultDisplaySync);
769 BindNativeFunction(*engine, *object, "getAllDisplay", moduleName, JsDisplayManager::GetAllDisplay);
770 BindNativeFunction(*engine, *object, "getAllDisplays", moduleName, JsDisplayManager::GetAllDisplays);
771 BindNativeFunction(*engine, *object, "hasPrivateWindow", moduleName, JsDisplayManager::HasPrivateWindow);
772 BindNativeFunction(*engine, *object, "isFoldable", moduleName, JsDisplayManager::IsFoldable);
773 BindNativeFunction(*engine, *object, "getFoldStatus", moduleName, JsDisplayManager::GetFoldStatus);
774 BindNativeFunction(*engine, *object, "getFoldDisplayMode", moduleName, JsDisplayManager::GetFoldDisplayMode);
775 BindNativeFunction(*engine, *object, "setFoldDisplayMode", moduleName, JsDisplayManager::SetFoldDisplayMode);
776 BindNativeFunction(*engine, *object, "getCurrentFoldCreaseRegion", moduleName,
777 JsDisplayManager::GetCurrentFoldCreaseRegion);
778 BindNativeFunction(*engine, *object, "on", moduleName, JsDisplayManager::RegisterDisplayManagerCallback);
779 BindNativeFunction(*engine, *object, "off", moduleName, JsDisplayManager::UnregisterDisplayManagerCallback);
780 return engine->CreateUndefined();
781 }
782 } // namespace Rosen
783 } // namespace OHOS