• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vector>
17 #include <new>
18 
19 #include <hitrace_meter.h>
20 #include "js_runtime_utils.h"
21 #include "native_engine/native_reference.h"
22 #include "display_manager.h"
23 #include "window_manager_hilog.h"
24 #include "singleton_container.h"
25 #include "js_display_listener.h"
26 #include "js_display.h"
27 #include "js_display_manager.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 using namespace AbilityRuntime;
32 constexpr size_t ARGC_ONE = 1;
33 constexpr size_t ARGC_TWO = 2;
34 constexpr int32_t INDEX_ONE = 1;
35 namespace {
36     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "JsDisplayManager"};
37 }
38 
39 class JsDisplayManager {
40 public:
JsDisplayManager(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