• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_input_device_context.h"
17 
18 namespace OHOS {
19 namespace MMI {
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "JsInputDeviceContext" }; // namespace
22 }
23 
JsInputDeviceContext()24 JsInputDeviceContext::JsInputDeviceContext()
25 {
26     mager_ = std::make_shared<JsInputDeviceManager>();
27     CHKPL(mager_);
28 }
29 
~JsInputDeviceContext()30 JsInputDeviceContext::~JsInputDeviceContext()
31 {
32     std::lock_guard<std::mutex> guard(mtx_);
33     auto jsInputDeviceMgr =  mager_;
34     mager_.reset();
35     if (jsInputDeviceMgr) {
36         jsInputDeviceMgr->ResetEnv();
37     }
38 }
39 
CreateInstance(napi_env env)40 napi_value JsInputDeviceContext::CreateInstance(napi_env env)
41 {
42     MMI_LOGD("begin");
43     napi_value global = nullptr;
44     napi_status status = napi_get_global(env, &global);
45     if (status != napi_ok) {
46         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to call napi_get_global");
47         MMI_LOGE("failed to call napi_get_global");
48         return nullptr;
49     }
50 
51     constexpr char className[] = "JsInputDeviceContext";
52     napi_value jsClass = nullptr;
53     napi_property_descriptor desc[] = {};
54     status = napi_define_class(env, className, sizeof(className), JsInputDeviceContext::JsConstructor, nullptr,
55         sizeof(desc) / sizeof(desc[0]), nullptr, &jsClass);
56     if (status != napi_ok) {
57         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to call napi_define_class");
58         MMI_LOGE("failed to call napi_define_class");
59         return nullptr;
60     }
61 
62     status = napi_set_named_property(env, global, "multimodalinput_input_device_class", jsClass);
63     if (status != napi_ok) {
64         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to set jsClass property");
65         MMI_LOGE("failed to set jsClass property");
66         return nullptr;
67     }
68 
69     napi_value jsInstance = nullptr;
70     status = napi_new_instance(env, jsClass, 0, nullptr, &jsInstance);
71     if (status != napi_ok) {
72         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to create jsInstance");
73         MMI_LOGE("failed to create jsInstance");
74         return nullptr;
75     }
76     status = napi_set_named_property(env, global, "multimodal_input_device", jsInstance);
77     if (status != napi_ok) {
78         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to set jsInstance property");
79         MMI_LOGE("failed to set jsInstance property");
80         return nullptr;
81     }
82 
83     JsInputDeviceContext *jsContext = nullptr;
84     status = napi_unwrap(env, jsInstance, (void**)&jsContext);
85     if (status != napi_ok) {
86         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get jsContext");
87         MMI_LOGE("failed to get jsContext");
88         return nullptr;
89     }
90     CHKPP(jsContext);
91     status = napi_create_reference(env, jsInstance, 1, &(jsContext->contextRef_));
92     if (status != napi_ok) {
93         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to create contextRef_");
94         MMI_LOGE("failed to create contextRef_");
95         return nullptr;
96     }
97 
98     uint32_t refCount = 0;
99     status = napi_reference_ref(env, jsContext->contextRef_, &refCount);
100     if (status != napi_ok) {
101         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to create contextRef_ reference");
102         MMI_LOGE("failed to create contextRef_ reference");
103         return nullptr;
104     }
105     MMI_LOGD("end");
106     return jsInstance;
107 }
108 
JsConstructor(napi_env env,napi_callback_info info)109 napi_value JsInputDeviceContext::JsConstructor(napi_env env, napi_callback_info info)
110 {
111     MMI_LOGD("begin");
112     napi_value thisVar = nullptr;
113     void *data = nullptr;
114     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
115     if (status != napi_ok) {
116         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get thisVar");
117         MMI_LOGE("failed to get thisVar");
118         return nullptr;
119     }
120 
121     JsInputDeviceContext *jsContext = new (std::nothrow) JsInputDeviceContext();
122     CHKPP(jsContext);
123     status = napi_wrap(env, thisVar, jsContext, [](napi_env env, void* data, void* hin) {
124         MMI_LOGI("jsvm ends");
125         JsInputDeviceContext *context = (JsInputDeviceContext*)data;
126         delete context;
127     }, nullptr, nullptr);
128     if (status != napi_ok) {
129         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to wrap jsContext");
130         MMI_LOGE("failed to wrap jsContext");
131         return nullptr;
132     }
133     MMI_LOGD("end");
134     return thisVar;
135 }
136 
GetInstance(napi_env env)137 JsInputDeviceContext* JsInputDeviceContext::GetInstance(napi_env env)
138 {
139     MMI_LOGD("begin");
140     napi_value global = nullptr;
141     napi_status status = napi_get_global(env, &global);
142     if (status != napi_ok) {
143         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get global");
144         MMI_LOGE("failed to get global");
145         return nullptr;
146     }
147 
148     bool result = false;
149     napi_has_named_property(env, global, "multimodal_input_device", &result);
150     if (!result) {
151         napi_throw_error(env, nullptr, "JsInputDeviceContext: multimodal_input_device was not found");
152         MMI_LOGE("multimodal_input_device was not found");
153         return nullptr;
154     }
155 
156     napi_value object = nullptr;
157     status = napi_get_named_property(env, global, "multimodal_input_device", &object);
158     if (status != napi_ok) {
159         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get multimodal_input_device");
160         MMI_LOGE("failed to get multimodal_input_device");
161         return nullptr;
162     }
163     if (object == nullptr) {
164         napi_throw_error(env, nullptr, "JsInputDeviceContext: object is nullptr");
165         MMI_LOGE("object is nullptr");
166         return nullptr;
167     }
168 
169     JsInputDeviceContext *instance = nullptr;
170     status = napi_unwrap(env, object, (void**)&instance);
171     if (status != napi_ok) {
172         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get instance");
173         MMI_LOGE("failed to get instance");
174         return nullptr;
175     }
176     if (instance == nullptr) {
177         napi_throw_error(env, nullptr, "JsInputDeviceContext: instance is nullptr");
178         MMI_LOGE("instance is nullptr");
179         return nullptr;
180     }
181     MMI_LOGD("end");
182     return instance;
183 }
184 
GetJsInputDeviceMgr()185 std::shared_ptr<JsInputDeviceManager> JsInputDeviceContext::GetJsInputDeviceMgr()
186 {
187     return mager_;
188 }
189 
GetDeviceIds(napi_env env,napi_callback_info info)190 napi_value JsInputDeviceContext::GetDeviceIds(napi_env env, napi_callback_info info)
191 {
192     MMI_LOGD("begin");
193     size_t argc = 1;
194     napi_value argv[1];
195     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
196     if (status != napi_ok) {
197         MMI_LOGE("parameter acquisition failed");
198         napi_throw_error(env, nullptr, "JsInputDeviceContext: parameter acquisition failed");
199         return nullptr;
200     }
201     if (argc > 1) {
202         MMI_LOGE("too many parameters");
203         napi_throw_error(env, nullptr, "JsInputDeviceContext: too many parameters");
204         return nullptr;
205     }
206 
207     JsInputDeviceContext *jsIds = JsInputDeviceContext::GetInstance(env);
208     auto jsInputDeviceMgr = jsIds->GetJsInputDeviceMgr();
209     if (argc == 0) {
210         return jsInputDeviceMgr->GetDeviceIds(env);
211     }
212 
213     napi_valuetype valueType = napi_undefined;
214     status = napi_typeof(env, argv[0], &valueType);
215     if (status != napi_ok) {
216         MMI_LOGE("failed to get the first parameter type");
217         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get the first parameter type");
218         return nullptr;
219     }
220     if (valueType != napi_function) {
221         MMI_LOGE("the first parameter is not a function");
222         napi_throw_error(env, nullptr, "JsInputDeviceContext: the first parameter is not a function");
223         return nullptr;
224     }
225     jsInputDeviceMgr->GetDeviceIds(env, argv[0]);
226     MMI_LOGD("end");
227     return nullptr;
228 }
229 
GetDevice(napi_env env,napi_callback_info info)230 napi_value JsInputDeviceContext::GetDevice(napi_env env, napi_callback_info info)
231 {
232     MMI_LOGD("begin");
233     size_t argc = 2;
234     napi_value argv[2];
235     napi_status status = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
236     if (status != napi_ok) {
237         napi_throw_error(env, nullptr, "JsInputDeviceContext: parameter acquisition failed");
238         return nullptr;
239     }
240     if (argc < 1 || argc > 2) {
241         MMI_LOGE("the number of parameters is not as expected");
242         napi_throw_error(env, nullptr, "JsInputDeviceContext: the number of parameters is not as expected");
243         return nullptr;
244     }
245 
246     napi_valuetype valueType = napi_undefined;
247     status = napi_typeof(env, argv[0], &valueType);
248     if (status != napi_ok) {
249         MMI_LOGE("failed to get the first parameter type");
250         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get the first parameter type");
251         return nullptr;
252     }
253     if (valueType != napi_number) {
254         MMI_LOGE("the first parameter is not a number");
255         napi_throw_error(env, nullptr, "JsInputDeviceContext: the first parameter is not a number");
256         return nullptr;
257     }
258     int32_t id = 0;
259     status = napi_get_value_int32(env, argv[0], &id);
260     if (status != napi_ok) {
261         MMI_LOGE("failed to get id");
262         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get id");
263         return nullptr;
264     }
265 
266     JsInputDeviceContext *jsDev = JsInputDeviceContext::GetInstance(env);
267     auto jsInputDeviceMgr = jsDev->GetJsInputDeviceMgr();
268     if (argc == 1) {
269         MMI_LOGD("promise end");
270         return jsInputDeviceMgr->GetDevice(id, env);
271     }
272     status = napi_typeof(env, argv[1], &valueType);
273     if (status != napi_ok) {
274         MMI_LOGE("failed to get the second parameter type");
275         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to get the second parameter type");
276         return nullptr;
277     }
278     if (valueType != napi_function) {
279         MMI_LOGE("the second parameter is not a function");
280         napi_throw_error(env, nullptr, "JsInputDeviceContext: the second parameter is not a function");
281         return nullptr;
282     }
283     jsInputDeviceMgr->GetDevice(id, env, argv[1]);
284     MMI_LOGD("end");
285     return nullptr;
286 }
287 
Export(napi_env env,napi_value exports)288 napi_value JsInputDeviceContext::Export(napi_env env, napi_value exports)
289 {
290     MMI_LOGD("begin");
291     auto instance = CreateInstance(env);
292     if (instance == nullptr) {
293         napi_throw_error(env, nullptr, "JsInputDeviceContext: failed to create instance");
294         MMI_LOGE("failed to create instance");
295         return nullptr;
296     }
297     napi_property_descriptor desc[] = {
298         DECLARE_NAPI_STATIC_FUNCTION("getDevice", GetDevice),
299         DECLARE_NAPI_STATIC_FUNCTION("getDeviceIds", GetDeviceIds),
300     };
301     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
302     MMI_LOGD("end");
303     return exports;
304 }
305 } // namespace MMI
306 } // namespace OHOS
307