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 "js_screen_manager.h"
17 
18 #include <cinttypes>
19 #include <vector>
20 #include <new>
21 #include "js_runtime_utils.h"
22 #include "js_screen.h"
23 #include "js_screen_listener.h"
24 #include "native_engine/native_reference.h"
25 #include "screen_manager.h"
26 #include "singleton_container.h"
27 #include "surface_utils.h"
28 #include "window_manager_hilog.h"
29 
30 namespace OHOS {
31 namespace Rosen {
32 using namespace AbilityRuntime;
33 constexpr size_t ARGC_ONE = 1;
34 constexpr size_t ARGC_TWO = 2;
35 constexpr size_t ARGC_THREE = 3;
36 constexpr int32_t INDEX_ONE = 1;
37 constexpr uint32_t MAX_SCREENS_NUM = 1000;
38 namespace {
39 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "JsScreenManager"};
40 }
41 
42 class JsScreenManager {
43 public:
JsScreenManager(napi_env env)44 explicit JsScreenManager(napi_env env) {
45 }
46 
47 ~JsScreenManager() = default;
48 
Finalizer(napi_env env,void * data,void * hint)49 static void Finalizer(napi_env env, void* data, void* hint)
50 {
51     WLOGI("JsScreenManager::Finalizer is called");
52     std::unique_ptr<JsScreenManager>(static_cast<JsScreenManager*>(data));
53 }
54 
GetAllScreens(napi_env env,napi_callback_info info)55 static napi_value GetAllScreens(napi_env env, napi_callback_info info)
56 {
57     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
58     return (me != nullptr) ? me->OnGetAllScreens(env, info) : nullptr;
59 }
60 
RegisterScreenManagerCallback(napi_env env,napi_callback_info info)61 static napi_value RegisterScreenManagerCallback(napi_env env, napi_callback_info info)
62 {
63     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
64     return (me != nullptr) ? me->OnRegisterScreenManagerCallback(env, info) : nullptr;
65 }
66 
UnregisterScreenMangerCallback(napi_env env,napi_callback_info info)67 static napi_value UnregisterScreenMangerCallback(napi_env env, napi_callback_info info)
68 {
69     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
70     return (me != nullptr) ? me->OnUnregisterScreenManagerCallback(env, info) : nullptr;
71 }
72 
MakeMirror(napi_env env,napi_callback_info info)73 static napi_value MakeMirror(napi_env env, napi_callback_info info)
74 {
75     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
76     return (me != nullptr) ? me->OnMakeMirror(env, info) : nullptr;
77 }
78 
MakeExpand(napi_env env,napi_callback_info info)79 static napi_value MakeExpand(napi_env env, napi_callback_info info)
80 {
81     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
82     return (me != nullptr) ? me->OnMakeExpand(env, info) : nullptr;
83 }
84 
StopMirror(napi_env env,napi_callback_info info)85 static napi_value StopMirror(napi_env env, napi_callback_info info)
86 {
87     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
88     return (me != nullptr) ? me->OnStopMirror(env, info) : nullptr;
89 }
90 
StopExpand(napi_env env,napi_callback_info info)91 static napi_value StopExpand(napi_env env, napi_callback_info info)
92 {
93     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
94     return (me != nullptr) ? me->OnStopExpand(env, info) : nullptr;
95 }
96 
CreateVirtualScreen(napi_env env,napi_callback_info info)97 static napi_value CreateVirtualScreen(napi_env env, napi_callback_info info)
98 {
99     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
100     return (me != nullptr) ? me->OnCreateVirtualScreen(env, info) : nullptr;
101 }
102 
DestroyVirtualScreen(napi_env env,napi_callback_info info)103 static napi_value DestroyVirtualScreen(napi_env env, napi_callback_info info)
104 {
105     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
106     return (me != nullptr) ? me->OnDestroyVirtualScreen(env, info) : nullptr;
107 }
108 
SetVirtualScreenSurface(napi_env env,napi_callback_info info)109 static napi_value SetVirtualScreenSurface(napi_env env, napi_callback_info info)
110 {
111     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
112     return (me != nullptr) ? me->OnSetVirtualScreenSurface(env, info) : nullptr;
113 }
114 
IsScreenRotationLocked(napi_env env,napi_callback_info info)115 static napi_value IsScreenRotationLocked(napi_env env, napi_callback_info info)
116 {
117     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
118     return (me != nullptr) ? me->OnIsScreenRotationLocked(env, info) : nullptr;
119 }
120 
SetScreenRotationLocked(napi_env env,napi_callback_info info)121 static napi_value SetScreenRotationLocked(napi_env env, napi_callback_info info)
122 {
123     JsScreenManager* me = CheckParamsAndGetThis<JsScreenManager>(env, info);
124     return (me != nullptr) ? me->OnSetScreenRotationLocked(env, info) : nullptr;
125 }
126 private:
127 std::map<std::string, std::map<std::unique_ptr<NativeReference>, sptr<JsScreenListener>>> jsCbMap_;
128 std::mutex mtx_;
129 
OnGetAllScreens(napi_env env,napi_callback_info info)130 napi_value OnGetAllScreens(napi_env env, napi_callback_info info)
131 {
132     WLOGI("OnGetAllScreens is called");
133     NapiAsyncTask::CompleteCallback complete =
134         [this](napi_env env, NapiAsyncTask& task, int32_t status) {
135             std::vector<sptr<Screen>> screens;
136             auto res = DM_JS_TO_ERROR_CODE_MAP.at(SingletonContainer::Get<ScreenManager>().GetAllScreens(screens));
137             if (res != DmErrorCode::DM_OK) {
138                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(res),
139                     "JsScreenManager::OnGetAllScreens failed."));
140             } else if (!screens.empty()) {
141                 task.Resolve(env, CreateJsScreenVectorObject(env, screens));
142                 WLOGI("JsScreenManager::OnGetAllScreens success");
143             } else {
144                 task.Reject(env, CreateJsError(env,
145                     static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN),
146                     "JsScreenManager::OnGetAllScreens failed."));
147             }
148         };
149     size_t argc = 4;
150     napi_value argv[4] = {nullptr};
151     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
152     napi_value lastParam = nullptr;
153     if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
154         GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
155         lastParam = argv[ARGC_ONE - 1];
156     }
157     napi_value result = nullptr;
158     NapiAsyncTask::Schedule("JsScreenManager::OnGetAllScreens",
159         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
160     return result;
161 }
162 
CreateJsScreenVectorObject(napi_env env,std::vector<sptr<Screen>> & screens)163 napi_value CreateJsScreenVectorObject(napi_env env, std::vector<sptr<Screen>>& screens)
164 {
165     napi_value arrayValue = nullptr;
166     napi_create_array_with_length(env, screens.size(), &arrayValue);
167     if (arrayValue == nullptr) {
168         WLOGFE("Failed to get screens");
169         return NapiGetUndefined(env);
170     }
171     size_t i = 0;
172     for (auto& screen : screens) {
173         if (screen == nullptr) {
174             continue;
175         }
176         napi_set_element(env, arrayValue, i++, CreateJsScreenObject(env, screen));
177     }
178     return arrayValue;
179 }
180 
IfCallbackRegistered(napi_env env,const std::string & type,napi_value jsListenerObject)181 bool IfCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject)
182 {
183     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
184         WLOGI("JsScreenManager::IfCallbackRegistered methodName %{public}s not registered!", type.c_str());
185         return false;
186     }
187 
188     for (auto& iter : jsCbMap_[type]) {
189         bool isEquals = false;
190         napi_strict_equals(env, jsListenerObject, iter.first->GetNapiValue(), &isEquals);
191         if (isEquals) {
192             WLOGFE("JsScreenManager::IfCallbackRegistered callback already registered!");
193             return true;
194         }
195     }
196     return false;
197 }
198 
RegisterScreenListenerWithType(napi_env env,const std::string & type,napi_value value)199 DmErrorCode RegisterScreenListenerWithType(napi_env env, const std::string& type, napi_value value)
200 {
201     if (IfCallbackRegistered(env, type, value)) {
202         WLOGFE("JsScreenManager::RegisterScreenListenerWithType callback already registered!");
203         return DmErrorCode::DM_ERROR_INVALID_CALLING;
204     }
205     std::unique_ptr<NativeReference> callbackRef;
206     napi_ref result = nullptr;
207     napi_create_reference(env, value, 1, &result);
208     callbackRef.reset(reinterpret_cast<NativeReference*>(result));
209     sptr<JsScreenListener> screenListener = new(std::nothrow) JsScreenListener(env);
210     if (screenListener == nullptr) {
211         WLOGFE("screenListener is nullptr");
212         return DmErrorCode::DM_ERROR_INVALID_SCREEN;
213     }
214     if (type == EVENT_CONNECT || type == EVENT_DISCONNECT || type == EVENT_CHANGE) {
215         DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(
216             SingletonContainer::Get<ScreenManager>().RegisterScreenListener(screenListener));
217         if (ret != DmErrorCode::DM_OK) {
218             return ret;
219         }
220         WLOGI("JsScreenManager::RegisterScreenListenerWithType success");
221     } else {
222         WLOGFE("JsScreenManager::RegisterScreenListenerWithType failed method: %{public}s not support!",
223             type.c_str());
224         return DmErrorCode::DM_ERROR_INVALID_CALLING;
225     }
226     screenListener->AddCallback(type, value);
227     jsCbMap_[type][std::move(callbackRef)] = screenListener;
228     return DmErrorCode::DM_OK;
229 }
230 
UnregisterAllScreenListenerWithType(const std::string & type)231 DmErrorCode UnregisterAllScreenListenerWithType(const std::string& type)
232 {
233     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
234         WLOGFE("JsScreenManager::UnregisterAllScreenListenerWithType methodName %{public}s not registered!",
235             type.c_str());
236         return DmErrorCode::DM_OK;
237     }
238     for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
239         it->second->RemoveAllCallback();
240         if (type == EVENT_CONNECT || type == EVENT_DISCONNECT || type == EVENT_CHANGE) {
241             sptr<ScreenManager::IScreenListener> thisListener(it->second);
242             SingletonContainer::Get<ScreenManager>().UnregisterScreenListener(thisListener);
243             WLOGI("JsScreenManager::UnregisterAllScreenListenerWithType success");
244         }
245         jsCbMap_[type].erase(it++);
246     }
247     jsCbMap_.erase(type);
248     return DmErrorCode::DM_OK;
249 }
250 
UnRegisterScreenListenerWithType(napi_env env,const std::string & type,napi_value value)251 DmErrorCode UnRegisterScreenListenerWithType(napi_env env, const std::string& type, napi_value value)
252 {
253     if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
254         WLOGI("JsScreenManager::UnRegisterScreenListenerWithType methodName %{public}s not registered!",
255             type.c_str());
256         return DmErrorCode::DM_OK;
257     }
258     if (value == nullptr) {
259         WLOGFE("JsScreenManager::UnRegisterScreenListenerWithType value is nullptr");
260         return DmErrorCode::DM_ERROR_INVALID_SCREEN;
261     }
262     DmErrorCode ret = DmErrorCode::DM_OK;
263     for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
264         bool isEquals = false;
265         napi_strict_equals(env, value, it->first->GetNapiValue(), &isEquals);
266         if (isEquals) {
267             it->second->RemoveCallback(env, type, value);
268             if (type == EVENT_CONNECT || type == EVENT_DISCONNECT || type == EVENT_CHANGE) {
269                 sptr<ScreenManager::IScreenListener> thisListener(it->second);
270                 ret = DM_JS_TO_ERROR_CODE_MAP.at(
271                     SingletonContainer::Get<ScreenManager>().UnregisterScreenListener(thisListener));
272             }
273             jsCbMap_[type].erase(it++);
274             break;
275         } else {
276             it++;
277         }
278     }
279     if (jsCbMap_[type].empty()) {
280         jsCbMap_.erase(type);
281     }
282     if (ret == DmErrorCode::DM_OK) {
283         WLOGFI("JsScreenManager::UnRegisterScreenListenerWithType success");
284     }
285     return ret;
286 }
287 
NapiIsCallable(napi_env env,napi_value value)288 bool NapiIsCallable(napi_env env, napi_value value)
289 {
290     bool result = false;
291     napi_is_callable(env, value, &result);
292     return result;
293 }
294 
NapiThrowError(napi_env env,DmErrorCode errCode,std::string msg="")295 napi_value NapiThrowError(napi_env env, DmErrorCode errCode, std::string msg = "")
296 {
297     napi_throw(env, CreateJsError(env, static_cast<int32_t>(errCode), msg));
298     return NapiGetUndefined(env);
299 }
300 
OnRegisterScreenManagerCallback(napi_env env,napi_callback_info info)301 napi_value OnRegisterScreenManagerCallback(napi_env env, napi_callback_info info)
302 {
303     WLOGI("JsScreenManager::OnRegisterScreenManagerCallback is called");
304     size_t argc = 4;
305     napi_value argv[4] = {nullptr};
306     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
307     if (argc < ARGC_TWO) {
308         WLOGFE("Invalid args count, need 2 args!");
309         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, 2 args is needed.");
310     }
311     std::string cbType;
312     if (!ConvertFromJsValue(env, argv[0], cbType)) {
313         WLOGFE("Failed to convert parameter to eventType");
314         std::string errMsg = "Failed to convert parameter to eventType";
315         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
316     }
317     napi_value value = argv[INDEX_ONE];
318     if (value == nullptr) {
319         WLOGI("JsScreenManager::OnRegisterScreenManagerCallback argv[1] is nullptr");
320         std::string errMsg = "OnRegisterScreenManagerCallback error, argv[1] is nullptr";
321         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
322     }
323     if (!NapiIsCallable(env, value)) {
324         WLOGI("JsScreenManager::OnRegisterScreenManagerCallback argv[1] is not callable");
325         std::string errMsg = "OnRegisterScreenManagerCallback error, argv[1] is not callable";
326         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
327     }
328     std::lock_guard<std::mutex> lock(mtx_);
329     DmErrorCode ret = RegisterScreenListenerWithType(env, cbType, value);
330     if (ret != DmErrorCode::DM_OK) {
331         WLOGFE("JsScreenManager::OnRegisterScreenManagerCallback failed");
332         napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
333     }
334     return NapiGetUndefined(env);
335 }
336 
OnUnregisterScreenManagerCallback(napi_env env,napi_callback_info info)337 napi_value OnUnregisterScreenManagerCallback(napi_env env, napi_callback_info info)
338 {
339     WLOGI("JsScreenManager::OnUnregisterScreenCallback is called");
340     size_t argc = 4;
341     napi_value argv[4] = {nullptr};
342     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
343     if (argc < ARGC_ONE) {
344         WLOGFE("Invalid args count, need one arg at least!");
345         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, need one arg at least!");
346     }
347     std::string cbType;
348     if (!ConvertFromJsValue(env, argv[0], cbType)) {
349         WLOGFE("Failed to convert parameter to eventType");
350         std::string errMsg = "Failed to convert parameter to eventType";
351         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
352     }
353     std::lock_guard<std::mutex> lock(mtx_);
354     if (argc == ARGC_ONE) {
355         DmErrorCode ret = UnregisterAllScreenListenerWithType(cbType);
356         if (ret != DmErrorCode::DM_OK) {
357             WLOGFE("unregister all callback failed");
358             napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
359         }
360     } else {
361         napi_value value = argv[INDEX_ONE];
362         if ((value == nullptr) || (!NapiIsCallable(env, value))) {
363             DmErrorCode ret = UnregisterAllScreenListenerWithType(cbType);
364             if (ret != DmErrorCode::DM_OK) {
365                 WLOGFE("JsScreenManager::OnUnRegisterAllScreenManagerCallback failed");
366                 napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
367             }
368         } else {
369             DmErrorCode ret = UnRegisterScreenListenerWithType(env, cbType, value);
370             if (ret != DmErrorCode::DM_OK) {
371                 WLOGFE("JsScreenManager::OnUnRegisterScreenManagerCallback failed");
372                 napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
373             }
374         }
375     }
376     return NapiGetUndefined(env);
377 }
378 
OnMakeMirror(napi_env env,napi_callback_info info)379 napi_value OnMakeMirror(napi_env env, napi_callback_info info)
380 {
381     WLOGI("OnMakeMirror is called");
382     size_t argc = 4;
383     napi_value argv[4] = {nullptr};
384     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
385     if (argc < ARGC_TWO) {
386         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, need 2 args at least!");
387     }
388 
389     int64_t mainScreenId;
390     if (!ConvertFromJsValue(env, argv[0], mainScreenId)) {
391         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to convert parameter to int");
392     }
393     napi_value array = argv[INDEX_ONE];
394     if (array == nullptr) {
395         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to get mirrorScreen, is nullptr");
396     }
397     uint32_t size = 0;
398     napi_get_array_length(env, array, &size);
399     std::vector<ScreenId> screenIds;
400     for (uint32_t i = 0; i < size; i++) {
401         uint32_t screenId;
402         napi_value value = nullptr;
403         napi_get_element(env, array, i, &value);
404         if (!ConvertFromJsValue(env, value, screenId)) {
405             return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to convert parameter to ScreenId");
406         }
407         screenIds.emplace_back(static_cast<ScreenId>(screenId));
408     }
409 
410     NapiAsyncTask::CompleteCallback complete =
411         [mainScreenId, screenIds](napi_env env, NapiAsyncTask& task, int32_t status) {
412             ScreenId screenGroupId = INVALID_SCREEN_ID;
413             DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(
414                 SingletonContainer::Get<ScreenManager>().MakeMirror(mainScreenId, screenIds, screenGroupId));
415             if (ret == DmErrorCode::DM_OK) {
416                 task.Resolve(env, CreateJsValue(env, static_cast<uint32_t>(screenGroupId)));
417             } else {
418                 task.Reject(env,
419                     CreateJsError(env, static_cast<int32_t>(ret), "JsScreenManager::OnMakeMirror failed."));
420             }
421         };
422     napi_value lastParam = nullptr;
423     if (argc >= ARGC_THREE && argv[ARGC_THREE - 1] != nullptr &&
424         GetType(env, argv[ARGC_THREE - 1]) == napi_function) {
425         lastParam = argv[ARGC_THREE - 1];
426     }
427     napi_value result = nullptr;
428     NapiAsyncTask::Schedule("JsScreenManager::OnMakeMirror",
429         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
430     return result;
431 }
432 
OnMakeExpand(napi_env env,napi_callback_info info)433 napi_value OnMakeExpand(napi_env env, napi_callback_info info)
434 {
435     WLOGI("OnMakeExpand is called");
436     size_t argc = 4;
437     napi_value argv[4] = {nullptr};
438     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
439     if (argc < ARGC_ONE) {
440         WLOGFE("Invalid args count, need one arg at least!");
441         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, need one arg at least!");
442     }
443 
444     napi_value array = argv[0];
445     if (array == nullptr) {
446         WLOGFE("Failed to get options, options is nullptr");
447         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to get options, options is nullptr");
448     }
449     uint32_t size = 0;
450     napi_get_array_length(env, array, &size);
451     std::vector<ExpandOption> options;
452     for (uint32_t i = 0; i < size; ++i) {
453         napi_value object = nullptr;
454         napi_get_element(env, array, i, &object);
455         ExpandOption expandOption;
456         int32_t res = GetExpandOptionFromJs(env, object, expandOption);
457         if (res == -1) {
458             WLOGE("expandoption param %{public}d error!", i);
459             return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "expandoption param error!");
460         }
461         options.emplace_back(expandOption);
462     }
463 
464     NapiAsyncTask::CompleteCallback complete =
465         [options](napi_env env, NapiAsyncTask& task, int32_t status) {
466             ScreenId screenGroupId = INVALID_SCREEN_ID;
467             DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(
468                 SingletonContainer::Get<ScreenManager>().MakeExpand(options, screenGroupId));
469             if (ret == DmErrorCode::DM_OK) {
470                 task.Resolve(env, CreateJsValue(env, static_cast<uint32_t>(screenGroupId)));
471                 WLOGI("MakeExpand success");
472             } else {
473                 task.Reject(env,
474                     CreateJsError(env, static_cast<int32_t>(ret), "JsScreenManager::OnMakeExpand failed."));
475                 WLOGFE("MakeExpand failed");
476             }
477         };
478     napi_value lastParam = nullptr;
479     if (argc >= ARGC_TWO && argv[ARGC_TWO - 1] != nullptr && GetType(env, argv[ARGC_TWO - 1]) == napi_function) {
480         lastParam = argv[ARGC_TWO - 1];
481     }
482     napi_value result = nullptr;
483     NapiAsyncTask::Schedule("JsScreenManager::OnMakeExpand",
484         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
485     return result;
486 }
487 
OnStopMirror(napi_env env,napi_callback_info info)488 napi_value OnStopMirror(napi_env env, napi_callback_info info)
489 {
490     WLOGI("OnStopMirror is called");
491     size_t argc = 4;
492     napi_value argv[4] = {nullptr};
493     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
494     if (argc < ARGC_ONE) {
495         WLOGFE("Invalid args count, need one arg at least!");
496         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, need one arg at least!");
497     }
498 
499     napi_value array = argv[0];
500     if (array == nullptr) {
501         WLOGFE("Failed to get mirrorScreen, mirrorScreen is nullptr");
502         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to get mirrorScreen, is nullptr");
503     }
504     uint32_t size = 0;
505     napi_get_array_length(env, array, &size);
506     if (size > MAX_SCREENS_NUM) {
507         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "size of mirrorScreen is greater than 1000");
508     }
509     std::vector<ScreenId> screenIds;
510     for (uint32_t i = 0; i < size; i++) {
511         uint32_t screenId;
512         napi_value value = nullptr;
513         napi_get_element(env, array, i, &value);
514         if (!ConvertFromJsValue(env, value, screenId)) {
515             return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to convert parameter to ScreenId");
516         }
517         screenIds.emplace_back(static_cast<ScreenId>(screenId));
518     }
519 
520     NapiAsyncTask::CompleteCallback complete =
521         [ screenIds](napi_env env, NapiAsyncTask& task, int32_t status) {
522             DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(
523                 SingletonContainer::Get<ScreenManager>().StopMirror(screenIds));
524             if (ret == DmErrorCode::DM_OK) {
525                 task.Resolve(env, NapiGetUndefined(env));
526             } else {
527                 task.Reject(env,
528                     CreateJsError(env, static_cast<int32_t>(ret), "JsScreenManager::OnStopMirror failed."));
529             }
530         };
531     napi_value lastParam = nullptr;
532     if (argc >= ARGC_TWO && argv[ARGC_TWO - 1] != nullptr && GetType(env, argv[ARGC_TWO - 1]) == napi_function) {
533         lastParam = argv[ARGC_TWO - 1];
534     }
535     napi_value result = nullptr;
536     NapiAsyncTask::Schedule("JsScreenManager::OnStopMirror",
537         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
538     return result;
539 }
540 
OnStopExpand(napi_env env,napi_callback_info info)541 napi_value OnStopExpand(napi_env env, napi_callback_info info)
542 {
543     WLOGI("OnStopExpand is called");
544     size_t argc = 4;
545     napi_value argv[4] = {nullptr};
546     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
547     if (argc < ARGC_ONE) {
548         WLOGFE("Invalid args count, need one arg at least!");
549         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid args count, need one arg at least!");
550     }
551 
552     napi_value array = argv[0];
553     if (array == nullptr) {
554         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to get expandScreen, is nullptr");
555     }
556     uint32_t size = 0;
557     napi_get_array_length(env, array, &size);
558     if (size > MAX_SCREENS_NUM) {
559         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "size of expandScreen is greater than 1000");
560     }
561     std::vector<ScreenId> screenIds;
562     for (uint32_t i = 0; i < size; i++) {
563         uint32_t screenId;
564         napi_value value = nullptr;
565         napi_get_element(env, array, i, &value);
566         if (!ConvertFromJsValue(env, value, screenId)) {
567             return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to convert parameter to ScreenId");
568         }
569         screenIds.emplace_back(static_cast<ScreenId>(screenId));
570     }
571 
572     NapiAsyncTask::CompleteCallback complete =
573         [screenIds](napi_env env, NapiAsyncTask& task, int32_t status) {
574             DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(
575                 SingletonContainer::Get<ScreenManager>().StopExpand(screenIds));
576             if (ret == DmErrorCode::DM_OK) {
577                 task.Resolve(env, NapiGetUndefined(env));
578                 WLOGI("MakeExpand success");
579             } else {
580                 task.Reject(env,
581                     CreateJsError(env, static_cast<int32_t>(ret), "JsScreenManager::OnStopExpand failed."));
582                 WLOGFE("MakeExpand failed");
583             }
584         };
585     napi_value lastParam = nullptr;
586     if (argc >= ARGC_TWO && argv[ARGC_TWO - 1] != nullptr && GetType(env, argv[ARGC_TWO - 1]) == napi_function) {
587         lastParam = argv[ARGC_TWO - 1];
588     }
589     napi_value result = nullptr;
590     NapiAsyncTask::Schedule("JsScreenManager::OnStopExpand",
591         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
592     return result;
593 }
594 
GetExpandOptionFromJs(napi_env env,napi_value optionObject,ExpandOption & option)595 static int32_t GetExpandOptionFromJs(napi_env env, napi_value optionObject, ExpandOption& option)
596 {
597     napi_value screedIdValue = nullptr;
598     napi_value startXValue = nullptr;
599     napi_value startYValue = nullptr;
600     uint32_t screenId;
601     uint32_t startX;
602     uint32_t startY;
603     napi_get_named_property(env, optionObject, "screenId", &screedIdValue);
604     napi_get_named_property(env, optionObject, "startX", &startXValue);
605     napi_get_named_property(env, optionObject, "startY", &startYValue);
606     if (!ConvertFromJsValue(env, screedIdValue, screenId)) {
607         WLOGFE("Failed to convert screedIdValue to callbackType");
608         return -1;
609     }
610     if (!ConvertFromJsValue(env, startXValue, startX)) {
611         WLOGFE("Failed to convert startXValue to callbackType");
612         return -1;
613     }
614     if (!ConvertFromJsValue(env, startYValue, startY)) {
615         WLOGFE("Failed to convert startYValue to callbackType");
616         return -1;
617     }
618     option = {screenId, startX, startY};
619     return 0;
620 }
621 
OnCreateVirtualScreen(napi_env env,napi_callback_info info)622 napi_value OnCreateVirtualScreen(napi_env env, napi_callback_info info)
623 {
624     WLOGI("JsScreenManager::OnCreateVirtualScreen is called");
625     DmErrorCode errCode = DmErrorCode::DM_OK;
626     VirtualScreenOption option;
627     size_t argc = 4;
628     std::string errMsg = "";
629     napi_value argv[4] = {nullptr};
630     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
631     if (argc < ARGC_ONE) {
632         errMsg = "Invalid args count, need one arg at least!";
633         errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
634     } else {
635         napi_value object = argv[0];
636         if (object == nullptr) {
637             errMsg = "Failed to get options, options is nullptr";
638             errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
639         } else {
640             errCode = GetVirtualScreenOptionFromJs(env, object, option);
641         }
642     }
643     if (errCode == DmErrorCode::DM_ERROR_INVALID_PARAM) {
644         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
645     }
646     NapiAsyncTask::CompleteCallback complete =
647         [option](napi_env env, NapiAsyncTask& task, int32_t status) {
648             auto screenId = SingletonContainer::Get<ScreenManager>().CreateVirtualScreen(option);
649             auto screen = SingletonContainer::Get<ScreenManager>().GetScreenById(screenId);
650             if (screen == nullptr) {
651                 DmErrorCode ret = DmErrorCode::DM_ERROR_INVALID_SCREEN;
652                 if (screenId == ERROR_ID_NOT_SYSTEM_APP) {
653                     ret = DmErrorCode::DM_ERROR_NOT_SYSTEM_APP;
654                 }
655                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(ret), "CreateVirtualScreen failed."));
656                 WLOGFE("ScreenManager::CreateVirtualScreen failed.");
657                 return;
658             }
659             task.Resolve(env, CreateJsScreenObject(env, screen));
660             WLOGI("JsScreenManager::OnCreateVirtualScreen success");
661         };
662     napi_value lastParam = nullptr;
663     if (argc >= ARGC_TWO && argv[ARGC_TWO - 1] != nullptr &&
664         GetType(env, argv[ARGC_TWO - 1]) == napi_function) {
665         lastParam = argv[ARGC_TWO - 1];
666     }
667     napi_value result = nullptr;
668     NapiAsyncTask::Schedule("JsScreenManager::OnCreateVirtualScreen",
669         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
670     return result;
671 }
672 
GetVirtualScreenOptionFromJs(napi_env env,napi_value optionObject,VirtualScreenOption & option)673 DmErrorCode GetVirtualScreenOptionFromJs(napi_env env, napi_value optionObject, VirtualScreenOption& option)
674 {
675     napi_value name = nullptr;
676     napi_get_named_property(env, optionObject, "name", &name);
677     if (!ConvertFromJsValue(env, name, option.name_)) {
678         WLOGFE("Failed to convert parameter to name.");
679         return DmErrorCode::DM_ERROR_INVALID_PARAM;
680     }
681     napi_value width = nullptr;
682     napi_get_named_property(env, optionObject, "width", &width);
683     if (!ConvertFromJsValue(env, width, option.width_)) {
684         WLOGFE("Failed to convert parameter to width.");
685         return DmErrorCode::DM_ERROR_INVALID_PARAM;
686     }
687     napi_value height = nullptr;
688     napi_get_named_property(env, optionObject, "height", &height);
689     if (!ConvertFromJsValue(env, height, option.height_)) {
690         WLOGFE("Failed to convert parameter to height.");
691         return DmErrorCode::DM_ERROR_INVALID_PARAM;
692     }
693     napi_value density = nullptr;
694     napi_get_named_property(env, optionObject, "density", &density);
695     double densityValue;
696     if (!ConvertFromJsValue(env, density, densityValue)) {
697         WLOGFE("Failed to convert parameter to density.");
698         return DmErrorCode::DM_ERROR_INVALID_PARAM;
699     }
700     option.density_ = static_cast<float>(densityValue);
701 
702     napi_value surfaceIdNapiValue = nullptr;
703     napi_get_named_property(env, optionObject, "surfaceId", &surfaceIdNapiValue);
704     if (!GetSurfaceFromJs(env, surfaceIdNapiValue, option.surface_)) {
705         return DmErrorCode::DM_ERROR_INVALID_PARAM;
706     }
707     return DmErrorCode::DM_OK;
708 }
709 
GetSurfaceFromJs(napi_env env,napi_value surfaceIdNapiValue,sptr<Surface> & surface)710 bool GetSurfaceFromJs(napi_env env, napi_value surfaceIdNapiValue, sptr<Surface>& surface)
711 {
712     if (surfaceIdNapiValue == nullptr || GetType(env, surfaceIdNapiValue) != napi_string) {
713         WLOGFE("Failed to convert parameter to surface. Invalidate params.");
714         return false;
715     }
716 
717     char buffer[PATH_MAX];
718     size_t length = 0;
719     uint64_t surfaceId = 0;
720     if (napi_get_value_string_utf8(env, surfaceIdNapiValue, buffer, PATH_MAX, &length) != napi_ok) {
721         WLOGFE("Failed to convert parameter to surface.");
722         return false;
723     }
724     std::istringstream inputStream(buffer);
725     inputStream >> surfaceId;
726     surface = SurfaceUtils::GetInstance()->GetSurface(surfaceId);
727     if (surface == nullptr) {
728         WLOGI("GetSurfaceFromJs failed, surfaceId:%{public}" PRIu64"", surfaceId);
729     }
730     return true;
731 }
732 
OnDestroyVirtualScreen(napi_env env,napi_callback_info info)733 napi_value OnDestroyVirtualScreen(napi_env env, napi_callback_info info)
734 {
735     WLOGI("JsScreenManager::OnDestroyVirtualScreen is called");
736     DmErrorCode errCode = DmErrorCode::DM_OK;
737     int64_t screenId = -1LL;
738     std::string errMsg = "";
739     size_t argc = 4;
740     napi_value argv[4] = {nullptr};
741     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
742     if (argc < ARGC_ONE) {
743         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
744         errMsg = "Invalid args count, need one arg at least!";
745         errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
746     } else {
747         if (!ConvertFromJsValue(env, argv[0], screenId)) {
748             WLOGFE("Failed to convert parameter to screen id.");
749             errMsg = "Failed to convert parameter to screen id.";
750             errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
751         }
752     }
753     if (errCode == DmErrorCode::DM_ERROR_INVALID_PARAM || screenId == -1LL) {
754         WLOGFE("JsScreenManager::OnDestroyVirtualScreen failed, Invalidate params.");
755         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
756     }
757     NapiAsyncTask::CompleteCallback complete =
758         [screenId](napi_env env, NapiAsyncTask& task, int32_t status) {
759             auto res = DM_JS_TO_ERROR_CODE_MAP.at(
760                 SingletonContainer::Get<ScreenManager>().DestroyVirtualScreen(screenId));
761             if (res != DmErrorCode::DM_OK) {
762                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(res),
763                     "ScreenManager::DestroyVirtualScreen failed."));
764                 WLOGFE("ScreenManager::DestroyVirtualScreen failed.");
765                 return;
766             }
767             task.Resolve(env, NapiGetUndefined(env));
768             WLOGI("JsScreenManager::OnDestroyVirtualScreen success");
769         };
770     napi_value lastParam = nullptr;
771     if (argc >= ARGC_TWO && argv[ARGC_TWO - 1] != nullptr &&
772         GetType(env, argv[ARGC_TWO - 1]) == napi_function) {
773         lastParam = argv[ARGC_TWO - 1];
774     }
775     napi_value result = nullptr;
776     NapiAsyncTask::Schedule("JsScreenManager::OnDestroyVirtualScreen",
777         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
778     return result;
779 }
780 
OnSetVirtualScreenSurface(napi_env env,napi_callback_info info)781 napi_value OnSetVirtualScreenSurface(napi_env env, napi_callback_info info)
782 {
783     WLOGI("JsScreenManager::OnSetVirtualScreenSurface is called");
784     DmErrorCode errCode = DmErrorCode::DM_OK;
785     int64_t screenId = -1LL;
786     sptr<Surface> surface;
787     size_t argc = 4;
788     std::string errMsg = "";
789     napi_value argv[4] = {nullptr};
790     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
791     if (argc < ARGC_TWO) {
792         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
793         errMsg = "Invalid args count, need 2 args at least!";
794         errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
795     } else {
796         if (!ConvertFromJsValue(env, argv[0], screenId)) {
797             errMsg = "Failed to convert parameter to screen id.";
798             errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
799         }
800         if (!GetSurfaceFromJs(env, argv[1], surface)) {
801             errMsg = "Failed to convert parameter.";
802             errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
803         }
804     }
805     if (errCode == DmErrorCode::DM_ERROR_INVALID_PARAM || surface == nullptr) {
806         WLOGFE("JsScreenManager::OnSetVirtualScreenSurface failed, Invalidate params.");
807         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
808     }
809     NapiAsyncTask::CompleteCallback complete =
810         [screenId, surface](napi_env env, NapiAsyncTask& task, int32_t status) {
811             auto res = DM_JS_TO_ERROR_CODE_MAP.at(
812                 SingletonContainer::Get<ScreenManager>().SetVirtualScreenSurface(screenId, surface));
813             if (res != DmErrorCode::DM_OK) {
814                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(res),
815                     "ScreenManager::SetVirtualScreenSurface failed."));
816                 WLOGFE("ScreenManager::SetVirtualScreenSurface failed.");
817                 return;
818             }
819             task.Resolve(env, NapiGetUndefined(env));
820             WLOGI("JsScreenManager::OnSetVirtualScreenSurface success");
821         };
822     napi_value lastParam = nullptr;
823     if (argc >= ARGC_THREE && argv[ARGC_THREE - 1] != nullptr &&
824         GetType(env, argv[ARGC_THREE - 1]) == napi_function) {
825         lastParam = argv[ARGC_THREE - 1];
826     }
827     napi_value result = nullptr;
828     NapiAsyncTask::Schedule("JsScreenManager::OnSetVirtualScreenSurface",
829         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
830     return result;
831 }
832 
OnIsScreenRotationLocked(napi_env env,napi_callback_info info)833 napi_value OnIsScreenRotationLocked(napi_env env, napi_callback_info info)
834 {
835     size_t argc = 4;
836     napi_value argv[4] = {nullptr};
837     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
838     WLOGI("OnIsScreenRotationLocked is called");
839     NapiAsyncTask::CompleteCallback complete =
840         [](napi_env env, NapiAsyncTask& task, int32_t status) {
841             bool isLocked = false;
842             auto res = DM_JS_TO_ERROR_CODE_MAP.at(
843                 SingletonContainer::Get<ScreenManager>().IsScreenRotationLocked(isLocked));
844             if (res == DmErrorCode::DM_OK) {
845                 task.Resolve(env, CreateJsValue(env, isLocked));
846                 WLOGFI("OnIsScreenRotationLocked success");
847             } else {
848                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(res),
849                                                 "JsScreenManager::OnIsScreenRotationLocked failed."));
850                 WLOGFE("OnIsScreenRotationLocked failed");
851             }
852         };
853     napi_value lastParam = nullptr;
854     if (argc >= ARGC_ONE && argv[ARGC_ONE - 1] != nullptr &&
855         GetType(env, argv[ARGC_ONE - 1]) == napi_function) {
856         lastParam = argv[ARGC_ONE - 1];
857     }
858     napi_value result = nullptr;
859     NapiAsyncTask::Schedule("JsScreenManager::OnIsScreenRotationLocked",
860         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
861     return result;
862 }
863 
OnSetScreenRotationLocked(napi_env env,napi_callback_info info)864 napi_value OnSetScreenRotationLocked(napi_env env, napi_callback_info info)
865 {
866     WLOGI("JsScreenManager::OnSetScreenRotationLocked is called");
867     DmErrorCode errCode = DmErrorCode::DM_OK;
868     size_t argc = 4;
869     std::string errMsg = "";
870     napi_value argv[4] = {nullptr};
871     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
872     if (argc < ARGC_ONE) {
873         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
874         errMsg = "Invalid args count, need one arg at least!";
875         errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
876     }
877     bool isLocked = false;
878     if (errCode == DmErrorCode::DM_OK) {
879         napi_value nativeVal = argv[0];
880         if (nativeVal == nullptr) {
881             WLOGFE("[NAPI]Failed to convert parameter to isLocked");
882             errMsg = "Failed to convert parameter to isLocked.";
883             errCode = DmErrorCode::DM_ERROR_INVALID_PARAM;
884         } else {
885             napi_get_value_bool(env, nativeVal, &isLocked);
886         }
887     }
888     if (errCode == DmErrorCode::DM_ERROR_INVALID_PARAM) {
889         WLOGFE("JsScreenManager::OnSetScreenRotationLocked failed, Invalidate params.");
890         return NapiThrowError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg);
891     }
892 
893     NapiAsyncTask::CompleteCallback complete =
894         [isLocked](napi_env env, NapiAsyncTask& task, int32_t status) {
895             auto res = DM_JS_TO_ERROR_CODE_MAP.at(
896                 SingletonContainer::Get<ScreenManager>().SetScreenRotationLocked(isLocked));
897             if (res == DmErrorCode::DM_OK) {
898                 task.Resolve(env, NapiGetUndefined(env));
899                 WLOGFI("OnSetScreenRotationLocked success");
900             } else {
901                 task.Reject(env, CreateJsError(env, static_cast<int32_t>(res),
902                                                   "JsScreenManager::OnSetScreenRotationLocked failed."));
903                 WLOGFE("OnSetScreenRotationLocked failed");
904             }
905         };
906     napi_value lastParam = (argc <= ARGC_ONE) ? nullptr :
907         ((argv[ARGC_TWO - 1] != nullptr && GetType(env, argv[ARGC_TWO - 1]) == napi_function) ?
908         argv[1] : nullptr);
909     napi_value result = nullptr;
910     NapiAsyncTask::Schedule("JsScreenManager::OnSetScreenRotationLocked",
911         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
912     return result;
913 }
914 };
915 
InitScreenOrientation(napi_env env)916 napi_value InitScreenOrientation(napi_env env)
917 {
918     WLOGD("JsScreenManager::InitScreenOrientation called");
919 
920     if (env == nullptr) {
921         WLOGFE("env is nullptr");
922         return nullptr;
923     }
924 
925     napi_value objValue = nullptr;
926     napi_create_object(env, &objValue);
927     if (objValue == nullptr) {
928         WLOGFE("Failed to get object");
929         return nullptr;
930     }
931 
932     napi_set_named_property(env, objValue, "UNSPECIFIED",
933         CreateJsValue(env, static_cast<int32_t>(Orientation::UNSPECIFIED)));
934     napi_set_named_property(env, objValue, "VERTICAL",
935         CreateJsValue(env, static_cast<int32_t>(Orientation::VERTICAL)));
936     napi_set_named_property(env, objValue, "HORIZONTAL",
937         CreateJsValue(env, static_cast<int32_t>(Orientation::HORIZONTAL)));
938     napi_set_named_property(env, objValue, "REVERSE_VERTICAL",
939         CreateJsValue(env, static_cast<int32_t>(Orientation::REVERSE_VERTICAL)));
940     napi_set_named_property(env, objValue, "REVERSE_HORIZONTAL",
941         CreateJsValue(env, static_cast<int32_t>(Orientation::REVERSE_HORIZONTAL)));
942     return objValue;
943 }
944 
InitScreenSourceMode(napi_env env)945 napi_value InitScreenSourceMode(napi_env env)
946 {
947     WLOGD("JsScreenManager::InitScreenSourceMode called");
948 
949     if (env == nullptr) {
950         WLOGFE("env is nullptr");
951         return nullptr;
952     }
953 
954     napi_value objValue = nullptr;
955     napi_create_object(env, &objValue);
956     if (objValue == nullptr) {
957         WLOGFE("Failed to get object");
958         return nullptr;
959     }
960 
961     napi_set_named_property(env, objValue, "SCREEN_MAIN",
962         CreateJsValue(env, static_cast<uint32_t>(ScreenSourceMode::SCREEN_MAIN)));
963     napi_set_named_property(env, objValue, "SCREEN_MIRROR",
964         CreateJsValue(env, static_cast<uint32_t>(ScreenSourceMode::SCREEN_MIRROR)));
965     napi_set_named_property(env, objValue, "SCREEN_EXTEND",
966         CreateJsValue(env, static_cast<uint32_t>(ScreenSourceMode::SCREEN_EXTEND)));
967     napi_set_named_property(env, objValue, "SCREEN_ALONE",
968         CreateJsValue(env, static_cast<uint32_t>(ScreenSourceMode::SCREEN_ALONE)));
969     return objValue;
970 }
971 
InitDisplayErrorCode(napi_env env)972 napi_value InitDisplayErrorCode(napi_env env)
973 {
974     WLOGD("JsDisplayManager::InitDisplayErrorCode called");
975 
976     if (env == nullptr) {
977         WLOGFE("env is nullptr");
978         return nullptr;
979     }
980 
981     napi_value objValue = nullptr;
982     napi_create_object(env, &objValue);
983     if (objValue == nullptr) {
984         WLOGFE("Failed to get object");
985         return nullptr;
986     }
987 
988     napi_set_named_property(env, objValue, "DM_ERROR_NO_PERMISSION",
989         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_NO_PERMISSION)));
990     napi_set_named_property(env, objValue, "DM_ERROR_NOT_SYSTEM_APP",
991         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_NOT_SYSTEM_APP)));
992     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_PARAM",
993         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_PARAM)));
994     napi_set_named_property(env, objValue, "DM_ERROR_DEVICE_NOT_SUPPORT",
995         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT)));
996     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_SCREEN",
997         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN)));
998     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_CALLING",
999         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_CALLING)));
1000     napi_set_named_property(env, objValue, "DM_ERROR_SYSTEM_INNORMAL",
1001         CreateJsValue(env, static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL)));
1002     return objValue;
1003 }
1004 
InitDisplayError(napi_env env)1005 napi_value InitDisplayError(napi_env env)
1006 {
1007     WLOGD("JsDisplayManager::InitDisplayError called");
1008 
1009     if (env == nullptr) {
1010         WLOGFE("env is nullptr");
1011         return nullptr;
1012     }
1013 
1014     napi_value objValue = nullptr;
1015     napi_create_object(env, &objValue);
1016     if (objValue == nullptr) {
1017         WLOGFE("Failed to get object");
1018         return nullptr;
1019     }
1020 
1021     napi_set_named_property(env, objValue, "DM_ERROR_INIT_DMS_PROXY_LOCKED",
1022         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED)));
1023     napi_set_named_property(env, objValue, "DM_ERROR_IPC_FAILED",
1024         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_IPC_FAILED)));
1025     napi_set_named_property(env, objValue, "DM_ERROR_REMOTE_CREATE_FAILED",
1026         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_REMOTE_CREATE_FAILED)));
1027     napi_set_named_property(env, objValue, "DM_ERROR_NULLPTR",
1028         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_NULLPTR)));
1029     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_PARAM",
1030         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_PARAM)));
1031     napi_set_named_property(env, objValue, "DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED",
1032         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED)));
1033     napi_set_named_property(env, objValue, "DM_ERROR_DEATH_RECIPIENT",
1034         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_DEATH_RECIPIENT)));
1035     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_MODE_ID",
1036         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_MODE_ID)));
1037     napi_set_named_property(env, objValue, "DM_ERROR_WRITE_DATA_FAILED",
1038         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_WRITE_DATA_FAILED)));
1039     napi_set_named_property(env, objValue, "DM_ERROR_RENDER_SERVICE_FAILED",
1040         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_RENDER_SERVICE_FAILED)));
1041     napi_set_named_property(env, objValue, "DM_ERROR_UNREGISTER_AGENT_FAILED",
1042         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_UNREGISTER_AGENT_FAILED)));
1043     napi_set_named_property(env, objValue, "DM_ERROR_INVALID_CALLING",
1044         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_INVALID_CALLING)));
1045     napi_set_named_property(env, objValue, "DM_ERROR_UNKNOWN",
1046         CreateJsValue(env, static_cast<int32_t>(DMError::DM_ERROR_UNKNOWN)));
1047     return objValue;
1048 }
1049 
JsScreenManagerInit(napi_env env,napi_value exportObj)1050 napi_value JsScreenManagerInit(napi_env env, napi_value exportObj)
1051 {
1052     WLOGD("JsScreenManagerInit is called");
1053 
1054     if (env == nullptr || exportObj == nullptr) {
1055         WLOGFE("JsScreenManagerInit env or exportObj is nullptr");
1056         return nullptr;
1057     }
1058 
1059     std::unique_ptr<JsScreenManager> jsScreenManager = std::make_unique<JsScreenManager>(env);
1060     napi_wrap(env, exportObj, jsScreenManager.release(), JsScreenManager::Finalizer, nullptr, nullptr);
1061     napi_set_named_property(env, exportObj, "Orientation", InitScreenOrientation(env));
1062     napi_set_named_property(env, exportObj, "ScreenSourceMode", InitScreenSourceMode(env));
1063     napi_set_named_property(env, exportObj, "DmErrorCode", InitDisplayErrorCode(env));
1064     napi_set_named_property(env, exportObj, "DMError", InitDisplayError(env));
1065 
1066     const char *moduleName = "JsScreenManager";
1067     BindNativeFunction(env, exportObj, "getAllScreens", moduleName, JsScreenManager::GetAllScreens);
1068     BindNativeFunction(env, exportObj, "on", moduleName, JsScreenManager::RegisterScreenManagerCallback);
1069     BindNativeFunction(env, exportObj, "off", moduleName, JsScreenManager::UnregisterScreenMangerCallback);
1070     BindNativeFunction(env, exportObj, "makeMirror", moduleName, JsScreenManager::MakeMirror);
1071     BindNativeFunction(env, exportObj, "makeExpand", moduleName, JsScreenManager::MakeExpand);
1072     BindNativeFunction(env, exportObj, "stopMirror", moduleName, JsScreenManager::StopMirror);
1073     BindNativeFunction(env, exportObj, "stopExpand", moduleName, JsScreenManager::StopExpand);
1074     BindNativeFunction(env, exportObj, "createVirtualScreen", moduleName, JsScreenManager::CreateVirtualScreen);
1075     BindNativeFunction(env, exportObj, "destroyVirtualScreen", moduleName, JsScreenManager::DestroyVirtualScreen);
1076     BindNativeFunction(env, exportObj, "setVirtualScreenSurface", moduleName,
1077         JsScreenManager::SetVirtualScreenSurface);
1078     BindNativeFunction(env, exportObj, "setScreenRotationLocked", moduleName,
1079         JsScreenManager::SetScreenRotationLocked);
1080     BindNativeFunction(env, exportObj, "isScreenRotationLocked", moduleName,
1081         JsScreenManager::IsScreenRotationLocked);
1082     return NapiGetUndefined(env);
1083 }
1084 }  // namespace Rosen
1085 }  // namespace OHOS
1086