• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <unistd.h>
17 
18 #include <map>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 #include <random>
24 #include <ios>
25 #include <sstream>
26 
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 #include "tokenid_kit.h"
30 
31 #include "mechbody_controller_log.h"
32 #include "js_mech_manager.h"
33 #include "js_mech_manager_service.h"
34 
35 namespace OHOS {
36 namespace MechBodyController {
37 namespace {
38     const std::string TAG = "MechManager";
39 
40     // all event type for on or off function
41     const std::string ATTACH_STATE_CHANGE_EVENT = "attachStateChange";
42     const std::string TRACKING_EVENT = "trackingStateChange";
43     const std::string ROTATE_AXIS_STATUS_CHANGE_EVENT = "rotationAxesStatusChange";
44     constexpr int32_t LAYOUT_MAX = 3;
45 }
46 
47 std::mutex MechManager::attachStateChangeStubMutex_;
48 sptr<JsMechManagerStub> MechManager::attachStateChangeStub_ = nullptr;
49 std::mutex MechManager::trackingEventStubMutex_;
50 sptr<JsMechManagerStub> MechManager::trackingEventStub_ = nullptr;
51 std::mutex MechManager::rotationAxesStatusChangeMutex_;
52 sptr<JsMechManagerStub> MechManager::rotationAxesStatusChangeStub_ = nullptr;
53 std::mutex MechManager::cmdChannelMutex_;
54 sptr<JsMechManagerStub> MechManager::cmdChannel_ = nullptr;
55 std::mutex MechManager::mechClientMutex_;
56 std::shared_ptr<MechClient> MechManager::mechClient_ = std::make_shared<MechClient>();
57 
On(napi_env env,napi_callback_info info)58 napi_value MechManager::On(napi_env env, napi_callback_info info)
59 {
60     HILOGI("Start to register the callback function.");
61     size_t argc = 2;
62     napi_value args[2];
63     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
64     if (argc < 2) {
65         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
66             "Wrong number of arguments");
67         HILOGE("Wrong number of arguments.");
68         return nullptr;
69     }
70 
71     napi_valuetype type;
72     napi_typeof(env, args[0], &type);
73     if (type != napi_string) {
74         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
75             "First argument must be a string");
76         HILOGE("First argument must be a string.");
77         return nullptr;
78     }
79 
80     size_t eventTypeLength = 0;
81     napi_get_value_string_utf8(env, args[0], nullptr, 0, &eventTypeLength);
82     std::string eventType(eventTypeLength, '\0');
83     if (napi_get_value_string_utf8(env, args[0], &eventType[0], eventTypeLength + 1, nullptr) != napi_ok) {
84         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
85             "Invalid event type.");
86         HILOGE("Invalid event type.");
87         return nullptr;
88     }
89 
90     napi_typeof(env, args[1], &type);
91     if (type != napi_function) {
92         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
93             "Second argument must be a function");
94         HILOGE("Second argument must be a function.");
95         return nullptr;
96     }
97     napi_ref callbackRef;
98     napi_create_reference(env, args[1], 1, &callbackRef);
99 
100     CallbackFunctionInfo callbackFunctionInfo = {env, callbackRef};
101     int32_t result = ExecuteOn(eventType, callbackFunctionInfo);
102     ProcessOnResultCode(env, result);
103     return nullptr;
104 }
105 
ExecuteOn(std::string & eventType,CallbackFunctionInfo & callbackFunctionInfo)106 int32_t MechManager::ExecuteOn(std::string &eventType, CallbackFunctionInfo &callbackFunctionInfo)
107 {
108     HILOGI("Register the callback function, event type:%{public}s;", eventType.c_str());
109     if (ATTACH_STATE_CHANGE_EVENT == eventType) {
110         return ExecuteOnForAttachStateChange(callbackFunctionInfo);
111     }
112 
113     if (TRACKING_EVENT == eventType) {
114         return ExecuteOnForTrackingEvent(callbackFunctionInfo);
115     }
116 
117     if (ROTATE_AXIS_STATUS_CHANGE_EVENT == eventType) {
118         return ExecuteOnForRotationAxesStatusChange(callbackFunctionInfo);
119     }
120     HILOGE("Register listener, no match event type for %{public}s", eventType.c_str());
121     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
122 }
123 
ExecuteOnForAttachStateChange(const CallbackFunctionInfo & callbackFunctionInfo)124 int32_t MechManager::ExecuteOnForAttachStateChange(const CallbackFunctionInfo &callbackFunctionInfo)
125 {
126     HILOGE("ATTACH_STATE_CHANGE_EVENT");
127     int32_t registerResult = ERR_OK;
128     std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().attachStateChangeCallbackMutex_);
129     if (JsMechManagerService::GetInstance().attachStateChangeCallback_.empty()) {
130         if (!InitMechClient()) {
131             HILOGE("Init Mech Client failed.");
132             return SYSTEM_WORK_ABNORMALLY;
133         }
134         if (!InitAttachStateChangeStub()) {
135             HILOGE("Init AttachStateChangeStub failed.");
136             return SYSTEM_WORK_ABNORMALLY;
137         }
138         registerResult = mechClient_->AttachStateChangeListenOn(attachStateChangeStub_);
139     }
140     if (registerResult != ERR_OK) {
141         return registerResult;
142     }
143     JsMechManagerService::GetInstance().attachStateChangeCallback_.insert(callbackFunctionInfo);
144     return registerResult;
145 }
146 
ExecuteOnForTrackingEvent(const CallbackFunctionInfo & callbackFunctionInfo)147 int32_t MechManager::ExecuteOnForTrackingEvent(const CallbackFunctionInfo &callbackFunctionInfo)
148 {
149     HILOGE("TRACKING_EVENT");
150     int32_t registerResult = ERR_OK;
151     std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().trackingEventCallbackMutex_);
152     if (JsMechManagerService::GetInstance().trackingEventCallback.empty()) {
153         if (!InitMechClient()) {
154             HILOGE("Init Mech Client failed.");
155             return MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY;
156         }
157         if (!InitTrackingEventStub()) {
158             HILOGE("Init TrackingEventStu failed.");
159             return MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY;
160         }
161         registerResult = mechClient_->TrackingEventListenOn(trackingEventStub_);
162     }
163     if (registerResult != ERR_OK) {
164         return registerResult;
165     }
166     JsMechManagerService::GetInstance().trackingEventCallback.insert(callbackFunctionInfo);
167     return registerResult;
168 }
169 
ExecuteOnForRotationAxesStatusChange(const CallbackFunctionInfo & callbackFunctionInfo)170 int32_t MechManager::ExecuteOnForRotationAxesStatusChange(const CallbackFunctionInfo &callbackFunctionInfo)
171 {
172     if (!IsSystemApp()) {
173         return PERMISSION_DENIED;
174     }
175     int32_t registerResult = ERR_OK;
176     std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().rotateAxisStatusChangeCallbackMutex_);
177     if (JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback.empty()) {
178         if (!InitMechClient()) {
179             HILOGE("Init Mech Client failed.");
180             return MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY;
181         }
182         if (!InitRotationAxesStatusChangeStub()) {
183             HILOGE("Init RotationAxesStatusChangeStub failed.");
184             return MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY;
185         }
186         registerResult = mechClient_->RotationAxesStatusChangeListenOn(rotationAxesStatusChangeStub_);
187     }
188     if (registerResult != ERR_OK) {
189         return registerResult;
190     }
191     JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback.insert(callbackFunctionInfo);
192     return registerResult;
193 }
194 
InitAttachStateChangeStub()195 bool MechManager::InitAttachStateChangeStub() {
196     if (attachStateChangeStub_ != nullptr) {
197         return true;
198     }
199     {
200         std::lock_guard<std::mutex> lock(attachStateChangeStubMutex_);
201         if (attachStateChangeStub_ != nullptr) {
202             return true;
203         }
204         sptr<JsMechManagerStub> stub = new JsMechManagerStub();
205         sptr <IRemoteObject::DeathRecipient> deathListener = new AttachStateChangeStubDeathListener();
206         stub->SetDeathRecipient(deathListener);
207         attachStateChangeStub_ = stub;
208         return attachStateChangeStub_ != nullptr;
209     }
210 }
211 
ProcessOnResultCode(napi_env env,int32_t & result)212 void MechManager::ProcessOnResultCode(napi_env env, int32_t &result) {
213     HILOGE("Register the callback function result code: %{public}d ", result);
214     if (result == MechNapiErrorCode::PARAMETER_CHECK_FAILED) {
215         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
216             "Invalid event type.");
217         return;
218     }
219     if (result == MechNapiErrorCode::PERMISSION_DENIED) {
220         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(),
221             "Not system application");
222         return;
223     }
224     if (result != ERR_OK) {
225         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
226             "System exception");
227         return;
228     }
229     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
230         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
231         return;
232     }
233 }
234 
InitTrackingEventStub()235 bool MechManager::InitTrackingEventStub(){
236     if(trackingEventStub_ != nullptr){
237         return true;
238     }
239     {
240         std::lock_guard<std::mutex> lock(trackingEventStubMutex_);
241         if(trackingEventStub_ != nullptr){
242             return true;
243         }
244         sptr<JsMechManagerStub> stub = new JsMechManagerStub();
245         sptr<IRemoteObject::DeathRecipient> deathListener = new TrackingEventStubDeathListener();
246         stub->SetDeathRecipient(deathListener);
247         trackingEventStub_ = stub;
248         return trackingEventStub_ != nullptr;
249     }
250 }
251 
InitRotationAxesStatusChangeStub()252 bool MechManager::InitRotationAxesStatusChangeStub(){
253     if(rotationAxesStatusChangeStub_ != nullptr){
254         return true;
255     }
256     {
257         std::lock_guard<std::mutex> lock(rotationAxesStatusChangeMutex_);
258         if(rotationAxesStatusChangeStub_ != nullptr){
259             return true;
260         }
261         sptr<JsMechManagerStub> stub = new JsMechManagerStub();
262         sptr<IRemoteObject::DeathRecipient> deathListener = new RotationAxesStatusChangeStubDeathListener();
263         stub->SetDeathRecipient(deathListener);
264         rotationAxesStatusChangeStub_ = stub;
265         return rotationAxesStatusChangeStub_ != nullptr;
266     }
267 }
268 
Off(napi_env env,napi_callback_info info)269 napi_value MechManager::Off(napi_env env, napi_callback_info info)
270 {
271     HILOGI("Start to unregister the callback function.");
272     size_t argc = 2;
273     napi_value args[2];
274     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
275     if (argc < 1) {
276         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
277             "Wrong number of arguments");
278         HILOGE("Wrong number of arguments.");
279         return nullptr;
280     }
281     napi_valuetype type;
282     napi_typeof(env, args[0], &type);
283     if (type != napi_string) {
284         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
285             "Argument must be a string");
286         HILOGE("Argument must be a string.");
287         return nullptr;
288     }
289     size_t eventTypeLength = 0;
290     napi_get_value_string_utf8(env, args[0], nullptr, 0, &eventTypeLength);
291     std::string eventType(eventTypeLength, '\0');
292     if (napi_get_value_string_utf8(env, args[0], &eventType[0], eventTypeLength + 1, nullptr) != napi_ok) {
293         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
294             "Invalid event type.");
295         HILOGE("Invalid event type.");
296         return nullptr;
297     }
298     int32_t result;
299     if (argc == 2) {
300         napi_typeof(env, args[1], &type);
301         if (type != napi_function) {
302             napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
303                 "Second argument must be a function");
304             HILOGE("Second argument must be a function.");
305             return nullptr;
306         }
307         napi_ref callbackRef;
308         napi_create_reference(env, args[1], 1, &callbackRef);
309         CallbackFunctionInfo callbackFunctionInfo = {env, callbackRef};
310         result = ExecuteOff(eventType, callbackFunctionInfo);
311     } else {
312         result = ExecuteOff(eventType);
313     }
314     ProcessOffResultCode(env, result);
315     return nullptr;
316 }
317 
ExecuteOff(std::string & eventType)318 int32_t MechManager::ExecuteOff(std::string &eventType)
319 {
320     HILOGE("Unregister listener, event type:%{public}s;", eventType.c_str());
321     if (!InitMechClient()) {
322         HILOGE("Init Mech Client failed.");
323         return MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY;
324     }
325     if (ATTACH_STATE_CHANGE_EVENT == eventType) {
326         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().attachStateChangeCallbackMutex_);
327         int32_t unRegisterResult = mechClient_->AttachStateChangeListenOff();
328         if (unRegisterResult == ERR_OK) {
329             JsMechManagerService::GetInstance().attachStateChangeCallback_.clear();
330         }
331         return unRegisterResult;
332     }
333 
334     if (TRACKING_EVENT == eventType) {
335         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().trackingEventCallbackMutex_);
336         int32_t unRegisterResult = mechClient_->TrackingEventListenOff();
337         if (unRegisterResult == ERR_OK) {
338             JsMechManagerService::GetInstance().trackingEventCallback.clear();
339         }
340         return unRegisterResult;
341     }
342 
343     if (ROTATE_AXIS_STATUS_CHANGE_EVENT == eventType) {
344         if (!IsSystemApp()) {
345             return PERMISSION_DENIED;
346         }
347         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().rotateAxisStatusChangeCallbackMutex_);
348         int32_t unRegisterResult = mechClient_->RotationAxesStatusChangeListenOff();
349         if (unRegisterResult == ERR_OK) {
350             JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback.clear();
351         }
352         return unRegisterResult;
353     }
354     HILOGE("Unregister listener, no match event type.");
355     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
356 }
357 
ExecuteOff(std::string & eventType,CallbackFunctionInfo & callbackFunctionInfo)358 int32_t MechManager::ExecuteOff(std::string &eventType, CallbackFunctionInfo &callbackFunctionInfo)
359 {
360     HILOGE("Unregister listener, event type:%{public}s;", eventType.c_str());
361     if (ATTACH_STATE_CHANGE_EVENT == eventType) {
362         return ExecuteOffForAttachStateChange(callbackFunctionInfo);
363     }
364     if (TRACKING_EVENT == eventType) {
365         return ExecuteOffForTrackingEvent(callbackFunctionInfo);
366     }
367     if (ROTATE_AXIS_STATUS_CHANGE_EVENT == eventType) {
368         return ExecuteOffForRotationAxesStatusChange(callbackFunctionInfo);
369     }
370     HILOGE("Unregister listener, no match event type.");
371     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
372 }
373 
ExecuteOffForAttachStateChange(CallbackFunctionInfo & callbackFunctionInfo)374 int32_t MechManager::ExecuteOffForAttachStateChange(CallbackFunctionInfo &callbackFunctionInfo)
375 {
376     std::lock_guard<std::mutex> lock(
377             JsMechManagerService::GetInstance().attachStateChangeCallbackMutex_);
378     if (JsMechManagerService::GetInstance().attachStateChangeCallback_.size() == 1 &&
379         HasSameCallbackFunction(JsMechManagerService::GetInstance().attachStateChangeCallback_,
380                                 callbackFunctionInfo)) {
381         int32_t unRegisterResult = mechClient_->AttachStateChangeListenOff();
382         if (unRegisterResult == ERR_OK) {
383             JsMechManagerService::GetInstance().attachStateChangeCallback_.clear();
384         }
385         return unRegisterResult;
386     } else {
387         RemoveSameCallbackFunction(JsMechManagerService::GetInstance().attachStateChangeCallback_,
388                                    callbackFunctionInfo);
389         return ERR_OK;
390     }
391     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
392 }
393 
ExecuteOffForTrackingEvent(CallbackFunctionInfo & callbackFunctionInfo)394 int32_t MechManager::ExecuteOffForTrackingEvent(CallbackFunctionInfo &callbackFunctionInfo)
395 {
396     HILOGE("TRACKING_EVENT");
397     std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().trackingEventCallbackMutex_);
398     if (JsMechManagerService::GetInstance().trackingEventCallback.size() == 1 &&
399         HasSameCallbackFunction(JsMechManagerService::GetInstance().trackingEventCallback,
400                                 callbackFunctionInfo)) {
401         int32_t unRegisterResult = mechClient_->TrackingEventListenOff();
402         if (unRegisterResult == ERR_OK) {
403             JsMechManagerService::GetInstance().trackingEventCallback.clear();
404         }
405         return unRegisterResult;
406     } else {
407         RemoveSameCallbackFunction(JsMechManagerService::GetInstance().trackingEventCallback,
408                                    callbackFunctionInfo);
409         return ERR_OK;
410     }
411     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
412 }
413 
ExecuteOffForRotationAxesStatusChange(CallbackFunctionInfo & callbackFunctionInfo)414 int32_t MechManager::ExecuteOffForRotationAxesStatusChange(CallbackFunctionInfo &callbackFunctionInfo)
415 {
416     HILOGE("ROTATE_AXIS_STATUS_CHANGE_EVENT");
417     if (!IsSystemApp()) {
418         return PERMISSION_DENIED;
419     }
420     std::lock_guard<std::mutex> lock(
421             JsMechManagerService::GetInstance().rotateAxisStatusChangeCallbackMutex_);
422     if (JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback.size() == 1 &&
423         HasSameCallbackFunction(JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback,
424                                 callbackFunctionInfo)) {
425         int32_t unRegisterResult = mechClient_->RotationAxesStatusChangeListenOff();
426         if (unRegisterResult == ERR_OK) {
427             JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback.clear();
428         }
429         return unRegisterResult;
430     } else {
431         RemoveSameCallbackFunction(JsMechManagerService::GetInstance().rotateAxisStatusChangeCallback,
432                                    callbackFunctionInfo);
433         return ERR_OK;
434     }
435     return MechNapiErrorCode::PARAMETER_CHECK_FAILED;
436 }
437 
HasSameCallbackFunction(std::set<CallbackFunctionInfo> & cacheInfo,CallbackFunctionInfo & callbackFunctionInfo)438 bool MechManager::HasSameCallbackFunction(std::set<CallbackFunctionInfo> &cacheInfo,
439     CallbackFunctionInfo &callbackFunctionInfo)
440 {
441     auto it = cacheInfo.find(callbackFunctionInfo);
442     return (it != cacheInfo.end());
443 }
444 
RemoveSameCallbackFunction(std::set<CallbackFunctionInfo> & cacheInfo,CallbackFunctionInfo & callbackFunctionInfo)445 bool MechManager::RemoveSameCallbackFunction(std::set<CallbackFunctionInfo> &cacheInfo,
446     CallbackFunctionInfo &callbackFunctionInfo)
447 {
448     auto it = cacheInfo.find(callbackFunctionInfo);
449     if (it != cacheInfo.end()) {
450         napi_delete_reference(it->env, it->callbackRef);
451         cacheInfo.erase(it);
452         HILOGE("Remove ok.");
453         return true;
454     }
455     return false;
456 }
457 
ProcessOffResultCode(napi_env env,int32_t & result)458 void MechManager::ProcessOffResultCode(napi_env env, int32_t &result)
459 {
460     HILOGE("UnRegister the callback function result code: %{public}d ", result);
461     if (result == MechNapiErrorCode::PARAMETER_CHECK_FAILED) {
462         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
463             "Invalid event type.");
464         return;
465     }
466     if (result != ERR_OK) {
467         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
468             "System exception");
469         return;
470     }
471 }
472 
GetAttachedDevices(napi_env env,napi_callback_info info)473 napi_value MechManager::GetAttachedDevices(napi_env env, napi_callback_info info)
474 {
475     if (!InitMechClient()) {
476         HILOGE("Init Mech Client failed.");
477         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
478             "System exception");
479         return nullptr;
480     }
481     std::vector<std::shared_ptr<MechInfo>> mechInfos;
482     int32_t result = mechClient_->GetAttachedDevices(mechInfos);
483     HILOGE("result code: %{public}d ", result);
484     if (result != ERR_OK) {
485         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
486             "System exception");
487         return nullptr;
488     }
489 
490     napi_value mechInfosResult;
491     napi_create_array_with_length(env, mechInfos.size(), &mechInfosResult);
492     for (size_t i = 0; i < mechInfos.size(); i++) {
493         napi_value element = MechInfoToNapiObject(env, mechInfos[i]);
494         napi_set_element(env, mechInfosResult, i, element);
495     }
496     return mechInfosResult;
497 }
498 
MechInfoToNapiObject(napi_env env,const std::shared_ptr<MechInfo> & info)499 napi_value MechManager::MechInfoToNapiObject(napi_env env, const std::shared_ptr<MechInfo> &info)
500 {
501     napi_value obj;
502     napi_create_object(env, &obj);
503 
504     napi_value mechId;
505     napi_create_int32(env, info->mechId, &mechId);
506     napi_set_named_property(env, obj, "mechId", mechId);
507 
508     napi_value mechType;
509     napi_create_int32(env, static_cast<int32_t>(info->mechType), &mechType);
510     napi_set_named_property(env, obj, "mechDeviceType", mechType);
511 
512     napi_value mechName;
513     napi_create_string_utf8(env, info->mechName.c_str(), info->mechName.size(), &mechName);
514     napi_set_named_property(env, obj, "mechName", mechName);
515 
516     return obj;
517 }
518 
SetUserOperation(napi_env env,napi_callback_info info)519 napi_value MechManager::SetUserOperation(napi_env env, napi_callback_info info)
520 {
521     if (!IsSystemApp()) {
522         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
523         return nullptr;
524     }
525     size_t argc = 3;
526     napi_value args[3];
527     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
528 
529     if (argc < 3) {
530         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
531             "Wrong number of arguments");
532         HILOGE("Wrong number of arguments.");
533         return nullptr;
534     }
535 
536     int32_t jsOperation;
537     napi_get_value_int32(env, args[0], &jsOperation);
538     if (jsOperation != 0 && jsOperation != 1) {
539         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(), "Operation error.");
540         return nullptr;
541     }
542 
543     auto operation = static_cast<Operation>(jsOperation);
544 
545     size_t macLength = 0;
546     napi_get_value_string_utf8(env, args[1], nullptr, 0, &macLength);
547     std::string mac(macLength, '\0');
548     if (napi_get_value_string_utf8(env, args[1], &mac[0], macLength + 1, nullptr) != napi_ok
549         || mac.empty() || mac == "") {
550         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(), "Invalid mac.");
551         return nullptr;
552     }
553     size_t paramLength = 0;
554     napi_get_value_string_utf8(env, args[2], nullptr, 0, &paramLength);
555     std::string param(paramLength, '\0');
556     if (napi_get_value_string_utf8(env, args[2], &param[0], paramLength + 1, nullptr) != napi_ok) {
557         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(), "Invalid param.");
558         HILOGE("Invalid param.");
559         return nullptr;
560     }
561     if (!InitMechClient()) {
562         HILOGE("Init Mech Client failed.");
563         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
564         return nullptr;
565     }
566     int32_t result = mechClient_->SetUserOperation(operation, mac, param);
567     HILOGE("result code: %{public}d ", result);
568     if (result != ERR_OK) {
569         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
570         return nullptr;
571     }
572     return nullptr;
573 }
574 
SetCameraTrackingEnabled(napi_env env,napi_callback_info info)575 napi_value MechManager::SetCameraTrackingEnabled(napi_env env, napi_callback_info info)
576 {
577     size_t argc = 1;
578     napi_value args[1];
579     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
580 
581     if (argc < 1) {
582         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
583             "Wrong number of arguments.");
584         HILOGE("Wrong number of arguments.");
585         return nullptr;
586     }
587 
588     bool isEnabled;
589     napi_status status = napi_get_value_bool(env, args[0], &isEnabled);
590     if (status != napi_ok) {
591         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
592             "Invalid camera tracking status.");
593         HILOGE("Invalid camera tracking status.");
594         return nullptr;
595     }
596     if (!InitMechClient()) {
597         HILOGE("Init Mech Client failed.");
598         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
599         return nullptr;
600     }
601     int32_t result = mechClient_->SetCameraTrackingEnabled(isEnabled);
602     HILOGI("result code: %{public}d ", result);
603     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
604         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
605         return nullptr;
606     }
607     if (result == MechNapiErrorCode::DEVICE_NOT_SUPPORTED) {
608         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_SUPPORTED).c_str(), "Device not supported");
609         return nullptr;
610     }
611     if (result != ERR_OK) {
612         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
613                          "System exception");
614         return nullptr;
615     }
616     return nullptr;
617 }
618 
GetCameraTrackingEnabled(napi_env env,napi_callback_info info)619 napi_value MechManager::GetCameraTrackingEnabled(napi_env env, napi_callback_info info)
620 {
621     bool isEnabled;
622     if (!InitMechClient()) {
623         HILOGE("Init Mech Client failed.");
624         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
625         return nullptr;
626     }
627     int32_t result = mechClient_->GetCameraTrackingEnabled(isEnabled);
628     HILOGI("result code: %{public}d ", result);
629     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
630         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
631         return nullptr;
632     }
633     if (result != ERR_OK) {
634         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
635         return nullptr;
636     }
637     napi_value isEnabledResult;
638     napi_get_boolean(env, isEnabled, &isEnabledResult);
639     return isEnabledResult;
640 }
641 
SetCameraTrackingLayout(napi_env env,napi_callback_info info)642 napi_value MechManager::SetCameraTrackingLayout(napi_env env, napi_callback_info info)
643 {
644     if (!IsSystemApp()) {
645         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
646         return nullptr;
647     }
648     size_t argc = 1;
649     napi_value args[1];
650     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
651 
652     if (argc < 1) {
653         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
654             "Wrong number of arguments");
655         return nullptr;
656     }
657 
658     int32_t jsLayout;
659     napi_status status = napi_get_value_int32(env, args[0], &jsLayout);
660     if (status != napi_ok) {
661         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
662             "trackingLayout must be a number");
663         return nullptr;
664     }
665     if (jsLayout > LAYOUT_MAX || jsLayout < 0) {
666         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
667             "trackingLayout out of range ");
668         return nullptr;
669     }
670     auto layout = static_cast<CameraTrackingLayout>(jsLayout);
671     if (!InitMechClient()) {
672         HILOGE("Init Mech Client failed.");
673         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
674         return nullptr;
675     }
676     int32_t result = mechClient_->SetCameraTrackingLayout(layout);
677     HILOGI("result code: %{public}d ", result);
678     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
679         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
680         return nullptr;
681     }
682     if (result == MechNapiErrorCode::DEVICE_NOT_SUPPORTED) {
683         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_SUPPORTED).c_str(), "Device not supported");
684         return nullptr;
685     }
686     if (result != ERR_OK) {
687         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
688         return nullptr;
689     }
690     return nullptr;
691 }
692 
GetCameraTrackingLayout(napi_env env,napi_callback_info info)693 napi_value MechManager::GetCameraTrackingLayout(napi_env env, napi_callback_info info)
694 {
695     CameraTrackingLayout layout;
696     if (!InitMechClient()) {
697         HILOGE("Init Mech Client failed.");
698         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
699         return nullptr;
700     }
701     int32_t result = mechClient_->GetCameraTrackingLayout(layout);
702     HILOGI("result code: %{public}d ", result);
703     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
704         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
705         return nullptr;
706     }
707     if (result != ERR_OK) {
708         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
709         return nullptr;
710     }
711 
712     napi_value getCameraTrackingLayoutResult;
713     napi_create_int32(env, static_cast<int32_t>(layout), &getCameraTrackingLayoutResult);
714     return getCameraTrackingLayoutResult;
715 }
716 
Rotate(napi_env env,napi_callback_info info)717 napi_value MechManager::Rotate(napi_env env, napi_callback_info info)
718 {
719     HILOGI("start");
720     if (!IsSystemApp()) {
721         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
722         return nullptr;
723     }
724     RotateByDegreeParam rotateParam;
725     int32_t mechId;
726     if (!GetRotateParam(env, info, rotateParam, mechId)) {
727         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
728             "create param failed.");
729         return nullptr;
730     }
731     napi_deferred deferred;
732     napi_value promise;
733     napi_create_promise(env, &deferred, &promise);
734     std::shared_ptr<RotatePrimiseFulfillmentParam> rotatePromiseParam =
735         std::make_shared<RotatePrimiseFulfillmentParam>();
736     rotatePromiseParam->cmdId = GenerateUniqueID();
737     rotatePromiseParam->deferred = deferred;
738     rotatePromiseParam->env = env;
739     {
740         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
741         JsMechManagerService::GetInstance().promiseParams_[rotatePromiseParam->cmdId] = rotatePromiseParam;
742     }
743     if (!InitMechClient() || !RegisterCmdChannel()) {
744         HILOGE("InitMechClient or RegisterCmdChannel failed;");
745         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
746         return nullptr;
747     }
748     int32_t result = mechClient_->Rotate(mechId, rotatePromiseParam->cmdId, rotateParam);
749     HILOGI("result code: %{public}d ", result);
750     if (result != ERR_OK) {
751         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
752         JsMechManagerService::GetInstance().promiseParams_.erase(rotatePromiseParam->cmdId);
753     }
754     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
755         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
756         return nullptr;
757     }
758     if (result != ERR_OK) {
759         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
760         return nullptr;
761     }
762     return promise;
763 }
764 
RegisterCmdChannel()765 bool MechManager::RegisterCmdChannel(){
766     if(cmdChannel_ != nullptr){
767         return true;
768     }
769     {
770         std::lock_guard<std::mutex> lock(cmdChannelMutex_);
771         if(cmdChannel_ != nullptr){
772             return true;
773         }
774         if(!InitMechClient()) {
775             return false;
776         }
777         sptr<JsMechManagerStub> stub = new JsMechManagerStub();;
778         sptr<IRemoteObject::DeathRecipient> deathListener = new CmdChannelDeathListener();
779         stub->SetDeathRecipient(deathListener);
780         int32_t result = mechClient_->RegisterCmdChannel(stub);
781         if(result == ERR_OK){
782             cmdChannel_ = stub;
783             return true;
784         }
785     }
786     return false;
787 }
788 
GetRotateParam(napi_env env,napi_callback_info info,RotateByDegreeParam & rotateParam,int32_t & mechId)789 bool MechManager::GetRotateParam(napi_env env, napi_callback_info info, RotateByDegreeParam &rotateParam,
790     int32_t &mechId)
791 {
792     size_t argc = 3;
793     napi_value args[3];
794     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
795 
796     if (argc < 3) {
797         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
798             "Wrong number of arguments");
799         return false;
800     }
801 
802     napi_status status = napi_get_value_int32(env, args[0], &mechId);
803     if (status != napi_ok) {
804         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
805             "mechId must be a number");
806         return false;
807     }
808 
809     int32_t duration;
810     status = napi_get_value_int32(env, args[2], &duration);
811     if (status != napi_ok) {
812         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
813             "mechId must be a number");
814         return false;
815     }
816 
817     napi_value degreeObj = args[1];
818     rotateParam.duration = duration;
819 
820     napi_value yawValue;
821     napi_value rollValue;
822     napi_value pitchValue;
823     double value = 0.0f;
824     if (napi_get_named_property(env, degreeObj, "yaw", &yawValue) == napi_ok) {
825         napi_get_value_double(env, yawValue, &value);
826         rotateParam.degree.yaw = static_cast<float>(value);
827     }
828     if (napi_get_named_property(env, degreeObj, "roll", &rollValue) == napi_ok) {
829         napi_get_value_double(env, rollValue, &value);
830         rotateParam.degree.roll = static_cast<float>(value);
831     }
832     if (napi_get_named_property(env, degreeObj, "pitch", &pitchValue) == napi_ok) {
833         napi_get_value_double(env, pitchValue, &value);
834         rotateParam.degree.pitch = static_cast<float>(value);
835     }
836     return true;
837 }
838 
839 
840 
RotateToEulerAngles(napi_env env,napi_callback_info info)841 napi_value MechManager::RotateToEulerAngles(napi_env env, napi_callback_info info)
842 {
843     if (!IsSystemApp()) {
844         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
845         return nullptr;
846     }
847     RotateToEulerAnglesParam rotateToEulerAnglesParam;
848     int32_t mechId;
849     if (!GetRotateToEulerAnglesParam(env, info, rotateToEulerAnglesParam, mechId)) {
850         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
851             "create param failed.");
852         return nullptr;
853     }
854 
855     napi_deferred deferred;
856     napi_value promise;
857     napi_create_promise(env, &deferred, &promise);
858 
859     std::shared_ptr<RotatePrimiseFulfillmentParam> rotatePromiseParam =
860         std::make_shared<RotatePrimiseFulfillmentParam>();
861     rotatePromiseParam->cmdId = GenerateUniqueID();
862     rotatePromiseParam->deferred = deferred;
863     rotatePromiseParam->env = env;
864     {
865         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
866         JsMechManagerService::GetInstance().promiseParams_[rotatePromiseParam->cmdId] = rotatePromiseParam;
867     }
868 
869     if(!InitMechClient() || !RegisterCmdChannel()){
870         HILOGE("RegisterCmdChannel failed;");
871         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
872                          "System exception");
873         return nullptr;
874     }
875     int32_t result = mechClient_->RotateToEulerAngles(mechId, rotatePromiseParam->cmdId, rotateToEulerAnglesParam);
876     HILOGI("result code: %{public}d ", result);
877     if (result != ERR_OK) {
878         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
879         JsMechManagerService::GetInstance().promiseParams_.erase(rotatePromiseParam->cmdId);
880     }
881     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
882         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(),
883                          "Device not connected");
884         return nullptr;
885     }
886     if (result != ERR_OK) {
887         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
888                          "System exception");
889         return nullptr;
890     }
891     return promise;
892 }
893 
GetRotateToEulerAnglesParam(napi_env env,napi_callback_info info,RotateToEulerAnglesParam & rotateToEulerAnglesParam,int32_t & mechId)894 bool MechManager::GetRotateToEulerAnglesParam(napi_env env, napi_callback_info info,
895     RotateToEulerAnglesParam &rotateToEulerAnglesParam, int32_t &mechId)
896 {
897     size_t argc = 3;
898     napi_value args[3];
899     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
900 
901     if (argc < 3) {
902         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
903             "Wrong number of arguments");
904         return false;
905     }
906 
907     napi_status status = napi_get_value_int32(env, args[0], &mechId);
908     if (status != napi_ok) {
909         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
910             "mechId must be a number");
911         return false;
912     }
913 
914     int32_t duration;
915     status = napi_get_value_int32(env, args[2], &duration);
916     if (status != napi_ok) {
917         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
918             "mechId must be a number");
919         return false;
920     }
921 
922     napi_value degreeObj = args[1];
923     rotateToEulerAnglesParam.duration = duration;
924 
925     napi_value yawValue;
926     napi_value rollValue;
927     napi_value pitchValue;
928     double value = 0.0f;
929     if (napi_get_named_property(env, degreeObj, "yaw", &yawValue) == napi_ok) {
930         napi_get_value_double(env, yawValue, &value);
931         rotateToEulerAnglesParam.angles.yaw = static_cast<float>(value);
932     }
933     if (napi_get_named_property(env, degreeObj, "roll", &rollValue) == napi_ok) {
934         napi_get_value_double(env, rollValue, &value);
935         rotateToEulerAnglesParam.angles.roll = static_cast<float>(value);
936     }
937     if (napi_get_named_property(env, degreeObj, "pitch", &pitchValue) == napi_ok) {
938         napi_get_value_double(env, pitchValue, &value);
939         rotateToEulerAnglesParam.angles.pitch = static_cast<float>(value);
940     }
941     return true;
942 }
943 
GetMaxRotationTime(napi_env env,napi_callback_info info)944 napi_value MechManager::GetMaxRotationTime(napi_env env, napi_callback_info info)
945 {
946     if (!IsSystemApp()) {
947         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
948         return nullptr;
949     }
950     size_t argc = 1;
951     napi_value args[1];
952     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
953 
954     if (argc < 1) {
955         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
956             "Wrong number of arguments");
957         return nullptr;
958     }
959 
960     int32_t mechId;
961     napi_status status = napi_get_value_int32(env, args[0], &mechId);
962     if (status != napi_ok) {
963         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
964             "mechId must be a number");
965         return nullptr;
966     }
967 
968     TimeLimit timeLimit;
969     if (!InitMechClient()) {
970         HILOGE("Init Mech Client failed.");
971         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
972             "System exception");
973         return nullptr;
974     }
975     int32_t result = mechClient_->GetMaxRotationTime(mechId, timeLimit);
976     HILOGE("result: %{public}d;", result);
977     if (result != ERR_OK) {
978         HILOGE("time limit query failed, result: %{public}d;", result);
979         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
980         return nullptr;
981     }
982     HILOGE("time limit query success, min: %{public}f; max: %{public}f;", timeLimit.min, timeLimit.max);
983     napi_value getSpeedControlMaxTimeResult;
984     napi_create_double(env, timeLimit.max, &getSpeedControlMaxTimeResult);
985     return getSpeedControlMaxTimeResult;
986 }
987 
GetMaxRotationSpeed(napi_env env,napi_callback_info info)988 napi_value MechManager::GetMaxRotationSpeed(napi_env env, napi_callback_info info)
989 {
990     if (!IsSystemApp()) {
991         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
992         return nullptr;
993     }
994     size_t argc = 1;
995     napi_value args[1];
996     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
997 
998     if (argc < 1) {
999         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1000             "Wrong number of arguments");
1001         return nullptr;
1002     }
1003 
1004     int32_t mechId;
1005     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1006     if (status != napi_ok) {
1007         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1008             "mechId must be a number");
1009         return nullptr;
1010     }
1011 
1012     RotateSpeedLimit rotateSpeedLimit;
1013     if (!InitMechClient()) {
1014         HILOGE("Init Mech Client failed.");
1015         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1016         return nullptr;
1017     }
1018     int32_t result = mechClient_->GetMaxRotationSpeed(mechId, rotateSpeedLimit);
1019     HILOGE("result: %{public}d;", result);
1020     if (result != ERR_OK) {
1021         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1022         return nullptr;
1023     }
1024 
1025     napi_value getRotateSpeedLimitResult;
1026     napi_create_object(env, &getRotateSpeedLimitResult);
1027     napi_value speedMax = RotateSpeedToNapi(env, rotateSpeedLimit.speedMax);
1028     napi_set_named_property(env, getRotateSpeedLimitResult, "speedMax", speedMax);
1029     napi_value speedMin = RotateSpeedToNapi(env, rotateSpeedLimit.speedMin);
1030     napi_set_named_property(env, getRotateSpeedLimitResult, "speedMin", speedMin);
1031 
1032     return getRotateSpeedLimitResult;
1033 }
1034 
RotateSpeedToNapi(napi_env env,const RotateSpeed & speed)1035 napi_value MechManager::RotateSpeedToNapi(napi_env env, const RotateSpeed &speed)
1036 {
1037     napi_value obj;
1038     napi_create_object(env, &obj);
1039 
1040     napi_value yawSpeed;
1041     napi_create_double(env, speed.yawSpeed, &yawSpeed);
1042     napi_set_named_property(env, obj, "yawSpeed", yawSpeed);
1043 
1044     napi_value rollSpeed;
1045     napi_create_double(env, speed.rollSpeed, &rollSpeed);
1046     napi_set_named_property(env, obj, "rollSpeed", rollSpeed);
1047 
1048     napi_value pitchSpeed;
1049     napi_create_double(env, speed.pitchSpeed, &pitchSpeed);
1050     napi_set_named_property(env, obj, "pitchSpeed", pitchSpeed);
1051 
1052     return obj;
1053 }
1054 
RotateBySpeed(napi_env env,napi_callback_info info)1055 napi_value MechManager::RotateBySpeed(napi_env env, napi_callback_info info)
1056 {
1057     if (!IsSystemApp()) {
1058         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
1059         return nullptr;
1060     }
1061     RotateBySpeedParam rotateBySpeedParam;
1062     int32_t mechId;
1063     if(!GetRotateBySpeedParam(env, info, rotateBySpeedParam, mechId)){
1064         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1065             "create param failed.");
1066         return nullptr;
1067     }
1068 
1069     napi_deferred deferred;
1070     napi_value promise;
1071     napi_create_promise(env, &deferred, &promise);
1072 
1073     std::shared_ptr<RotatePrimiseFulfillmentParam> rotatePromiseParam =
1074         std::make_shared<RotatePrimiseFulfillmentParam>();
1075     rotatePromiseParam->cmdId = GenerateUniqueID();
1076     rotatePromiseParam->deferred = deferred;
1077     rotatePromiseParam->env = env;
1078     {
1079         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
1080         JsMechManagerService::GetInstance().promiseParams_[rotatePromiseParam->cmdId] = rotatePromiseParam;
1081     }
1082 
1083     if (!InitMechClient() || !RegisterCmdChannel()) {
1084         HILOGE("RegisterCmdChannel failed;");
1085         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1086         return nullptr;
1087     }
1088     int32_t result = mechClient_->RotateBySpeed(mechId, rotatePromiseParam->cmdId, rotateBySpeedParam);
1089     HILOGI("result code: %{public}d ", result);
1090     if (result != ERR_OK) {
1091         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
1092         JsMechManagerService::GetInstance().promiseParams_.erase(rotatePromiseParam->cmdId);
1093     }
1094     if (result == MechNapiErrorCode::DEVICE_NOT_CONNECTED) {
1095         napi_throw_error(env, std::to_string(MechNapiErrorCode::DEVICE_NOT_CONNECTED).c_str(), "Device not connected");
1096         return nullptr;
1097     }
1098     if (result != ERR_OK) {
1099         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1100         return nullptr;
1101     }
1102     return promise;
1103 }
1104 
GetRotateBySpeedParam(napi_env env,napi_callback_info info,RotateBySpeedParam & rotateBySpeedParam,int32_t & mechId)1105 bool MechManager::GetRotateBySpeedParam(napi_env env, napi_callback_info info,
1106     RotateBySpeedParam &rotateBySpeedParam, int32_t &mechId)
1107 {
1108     size_t argc = 3;
1109     napi_value args[3];
1110     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1111 
1112     if (argc < 3) {
1113         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1114             "Wrong number of arguments");
1115         return false;
1116     }
1117 
1118     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1119     if (status != napi_ok) {
1120         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1121             "mechId must be a number");
1122         return false;
1123     }
1124 
1125     double duration;
1126     status = napi_get_value_double(env, args[2], &duration);
1127     if (status != napi_ok) {
1128         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1129             "mechId must be a number");
1130         return false;
1131     }
1132 
1133     napi_value degreeObj = args[1];
1134     rotateBySpeedParam.duration = static_cast<float>(duration);
1135 
1136     napi_value yawValue;
1137     napi_value rollValue;
1138     napi_value pitchValue;
1139     double value = 0.0f;
1140     if (napi_get_named_property(env, degreeObj, "yawSpeed", &yawValue) == napi_ok) {
1141         napi_get_value_double(env, yawValue, &value);
1142         rotateBySpeedParam.speed.yawSpeed = static_cast<float>(value);
1143     }
1144     if (napi_get_named_property(env, degreeObj, "rollSpeed", &rollValue) == napi_ok) {
1145         napi_get_value_double(env, rollValue, &value);
1146         rotateBySpeedParam.speed.rollSpeed = static_cast<float>(value);
1147     }
1148     if (napi_get_named_property(env, degreeObj, "pitchSpeed", &pitchValue) == napi_ok) {
1149         napi_get_value_double(env, pitchValue, &value);
1150         rotateBySpeedParam.speed.pitchSpeed = static_cast<float>(value);
1151     }
1152     return true;
1153 }
1154 
StopMoving(napi_env env,napi_callback_info info)1155 napi_value MechManager::StopMoving(napi_env env, napi_callback_info info)
1156 {
1157     if (!IsSystemApp()) {
1158         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
1159         return nullptr;
1160     }
1161     size_t argc = 1;
1162     napi_value args[1];
1163     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1164     if (argc < 1) {
1165         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1166             "Wrong number of arguments");
1167         return nullptr;
1168     }
1169     int32_t mechId;
1170     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1171     if (status != napi_ok) {
1172         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1173             "mechId must be a number");
1174         return nullptr;
1175     }
1176     napi_deferred deferred;
1177     napi_value promise;
1178     napi_create_promise(env, &deferred, &promise);
1179     std::shared_ptr<RotatePrimiseFulfillmentParam> rotatePromiseParam =
1180         std::make_shared<RotatePrimiseFulfillmentParam>();
1181     rotatePromiseParam->cmdId = GenerateUniqueID();
1182     rotatePromiseParam->deferred = deferred;
1183     rotatePromiseParam->env = env;
1184     {
1185         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
1186         JsMechManagerService::GetInstance().promiseParams_[rotatePromiseParam->cmdId] = rotatePromiseParam;
1187     }
1188 
1189     if (!InitMechClient() || !RegisterCmdChannel()) {
1190         HILOGE("RegisterCmdChannel failed;");
1191         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1192         return nullptr;
1193     }
1194     int32_t result = mechClient_->StopMoving(mechId, rotatePromiseParam->cmdId);
1195     HILOGI("result code: %{public}d ", result);
1196     if (result != ERR_OK) {
1197         std::lock_guard<std::mutex> lock(JsMechManagerService::GetInstance().promiseParamsMutex_);
1198         JsMechManagerService::GetInstance().promiseParams_.erase(rotatePromiseParam->cmdId);
1199     }
1200     ProcessOnResultCode(env, result);
1201     return promise;
1202 }
1203 
GetCurrentAngles(napi_env env,napi_callback_info info)1204 napi_value MechManager::GetCurrentAngles(napi_env env, napi_callback_info info)
1205 {
1206     if (!IsSystemApp()) {
1207         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
1208         return nullptr;
1209     }
1210     size_t argc = 1;
1211     napi_value args[1];
1212     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1213 
1214     if (argc < 1) {
1215         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1216             "Wrong number of arguments");
1217         return nullptr;
1218     }
1219 
1220     int32_t mechId;
1221     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1222     if (status != napi_ok) {
1223         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1224             "mechId must be a number");
1225         return nullptr;
1226     }
1227 
1228     EulerAngles rotationAngles;
1229     if (!InitMechClient()) {
1230         HILOGE("Init Mech Client failed.");
1231         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1232         return nullptr;
1233     }
1234     int32_t result = mechClient_->GetRotationAngles(mechId, rotationAngles);
1235     HILOGE("result: %{public}d;", result);
1236     if (result != ERR_OK) {
1237         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1238         return nullptr;
1239     }
1240     return CreateEulerAngles(env, rotationAngles);
1241 }
1242 
GetRotationLimits(napi_env env,napi_callback_info info)1243 napi_value MechManager::GetRotationLimits(napi_env env, napi_callback_info info)
1244 {
1245     if (!IsSystemApp()) {
1246         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
1247         return nullptr;
1248     }
1249     size_t argc = 1;
1250     napi_value args[1];
1251     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1252 
1253     if (argc < 1) {
1254         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1255             "Wrong number of arguments");
1256         return nullptr;
1257     }
1258 
1259     int32_t mechId;
1260     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1261     if (status != napi_ok) {
1262         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1263             "mechId must be a number");
1264         return nullptr;
1265     }
1266 
1267     RotateDegreeLimit rotateDegreeLimit;
1268     if(!InitMechClient()){
1269         HILOGE("Init Mech Client failed.");
1270         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(),
1271             "System exception");
1272         return nullptr;
1273     }
1274     int32_t result = mechClient_->GetRotationDegreeLimits(mechId, rotateDegreeLimit);
1275     HILOGE("result: %{public}d;", result);
1276     if (result != ERR_OK) {
1277         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1278         return nullptr;
1279     }
1280     HILOGE("RotateDegreeLimit query success: %{public}s;", rotateDegreeLimit.ToString().c_str());
1281     return CreateRotationLimit(env, rotateDegreeLimit);
1282 }
1283 
GetRotationAxesStatus(napi_env env,napi_callback_info info)1284 napi_value MechManager::GetRotationAxesStatus(napi_env env, napi_callback_info info)
1285 {
1286     if (!IsSystemApp()) {
1287         napi_throw_error(env, std::to_string(MechNapiErrorCode::PERMISSION_DENIED).c_str(), "Not system application");
1288         return nullptr;
1289     }
1290     size_t argc = 1;
1291     napi_value args[1];
1292     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
1293 
1294     if (argc < 1) {
1295         napi_throw_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1296             "Wrong number of arguments");
1297         return nullptr;
1298     }
1299 
1300     int32_t mechId;
1301     napi_status status = napi_get_value_int32(env, args[0], &mechId);
1302     if (status != napi_ok) {
1303         napi_throw_type_error(env, std::to_string(MechNapiErrorCode::PARAMETER_CHECK_FAILED).c_str(),
1304             "mechId must be a number");
1305         return nullptr;
1306     }
1307 
1308     RotationAxesStatus axesStatus{};
1309     if (!InitMechClient()) {
1310         HILOGE("Init Mech Client failed.");
1311         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1312         return nullptr;
1313     }
1314     int32_t result = mechClient_->GetRotationAxesStatus(mechId, axesStatus);
1315     HILOGE("result: %{public}d;", result);
1316     if (result != ERR_OK) {
1317         napi_throw_error(env, std::to_string(MechNapiErrorCode::SYSTEM_WORK_ABNORMALLY).c_str(), "System exception");
1318         return nullptr;
1319     }
1320     return CreateRotationAxesStatus(env, axesStatus);
1321 }
1322 
CreateEnumObject(napi_env env,const std::vector<std::pair<std::string,int32_t>> & pairs)1323 napi_value CreateEnumObject(napi_env env, const std::vector<std::pair<std::string, int32_t>> &pairs)
1324 {
1325     napi_value result;
1326     napi_create_object(env, &result);
1327 
1328     for (const auto &pair: pairs) {
1329         napi_value value;
1330         napi_create_int32(env, pair.second, &value);
1331         napi_set_named_property(env, result, pair.first.c_str(), value);
1332     }
1333 
1334     return result;
1335 }
1336 
CreateEulerAngles(napi_env env,const EulerAngles & degree)1337 napi_value MechManager::CreateEulerAngles(napi_env env, const EulerAngles &degree)
1338 {
1339     napi_value obj;
1340     napi_create_object(env, &obj);
1341 
1342     napi_value yaw;
1343     napi_create_double(env, degree.yaw, &yaw);
1344     napi_set_named_property(env, obj, "yaw", yaw);
1345 
1346     napi_value roll;
1347     napi_create_double(env, degree.roll, &roll);
1348     napi_set_named_property(env, obj, "roll", roll);
1349 
1350     napi_value pitch;
1351     napi_create_double(env, degree.pitch, &pitch);
1352     napi_set_named_property(env, obj, "pitch", pitch);
1353 
1354     return obj;
1355 }
1356 
CreateRotationLimit(napi_env env,const RotateDegreeLimit & limit)1357 napi_value MechManager::CreateRotationLimit(napi_env env, const RotateDegreeLimit &limit)
1358 {
1359     napi_value obj;
1360     napi_create_object(env, &obj);
1361 
1362     napi_value negMax = CreateEulerAngles(env, limit.negMax);
1363     napi_set_named_property(env, obj, "negMax", negMax);
1364 
1365     napi_value posMax = CreateEulerAngles(env, limit.posMax);
1366     napi_set_named_property(env, obj, "posMax", posMax);
1367 
1368     return obj;
1369 }
1370 
CreateRotationAxesStatus(napi_env env,const RotationAxesStatus & status)1371 napi_value MechManager::CreateRotationAxesStatus(napi_env env, const RotationAxesStatus &status)
1372 {
1373     napi_value obj;
1374     napi_create_object(env, &obj);
1375 
1376     napi_value yawEnabled;
1377     napi_get_boolean(env, status.yawEnabled, &yawEnabled);
1378     napi_set_named_property(env, obj, "yawEnabled", yawEnabled);
1379 
1380     napi_value rollEnabled;
1381     napi_get_boolean(env, status.rollEnabled, &rollEnabled);
1382     napi_set_named_property(env, obj, "rollEnabled", rollEnabled);
1383 
1384     napi_value pitchEnabled;
1385     napi_get_boolean(env, status.pitchEnabled, &pitchEnabled);
1386     napi_set_named_property(env, obj, "pitchEnabled", pitchEnabled);
1387 
1388     napi_value yawLimited;
1389     napi_create_int32(env, static_cast<int32_t>(status.yawLimited), &yawLimited);
1390     napi_set_named_property(env, obj, "yawLimited", yawLimited);
1391 
1392     napi_value rollLimited;
1393     napi_create_int32(env, static_cast<int32_t>(status.rollLimited), &rollLimited);
1394     napi_set_named_property(env, obj, "rollLimited", rollLimited);
1395 
1396     napi_value pitchLimited;
1397     napi_create_int32(env, static_cast<int32_t>(status.pitchLimited), &pitchLimited);
1398     napi_set_named_property(env, obj, "pitchLimited", pitchLimited);
1399 
1400     return obj;
1401 }
1402 
IsSystemApp()1403 bool MechManager::IsSystemApp()
1404 {
1405     static bool isSystemApp = []() {
1406         uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
1407         return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1408     }();
1409     return isSystemApp;
1410 }
1411 
InitMechClient()1412 bool MechManager::InitMechClient()
1413 {
1414     if(mechClient_ != nullptr){
1415         return true;
1416     }
1417     {
1418         std::lock_guard<std::mutex> lock(mechClientMutex_);
1419         if(mechClient_ == nullptr){
1420             mechClient_ = std::make_shared<MechClient>();
1421         }
1422     }
1423     return mechClient_ != nullptr;
1424 }
1425 
GenerateUniqueID()1426 std::string MechManager::GenerateUniqueID(){
1427     // 获取当前时间戳
1428     auto now = std::chrono::system_clock::now();
1429     auto now_c = std::chrono::system_clock::to_time_t(now);
1430 
1431     // 初始化随机数生成器
1432     std::mt19937 generator(now_c);
1433 
1434     // 生成随机数
1435     std::uniform_int_distribution<int> distribution(0, 15);
1436     std::uniform_int_distribution<int> distribution2(8, 11);
1437 
1438     // 生成UUID
1439     std::stringstream ss;
1440     ss << std::hex << std::uppercase;
1441     for (int i = 0; i < 32; ++i) {
1442         if (i == 8 || i == 13 || i == 18 || i == 23) {
1443             ss << "-";
1444         }
1445         if (i == 13) {
1446             ss << distribution2(generator);
1447         } else {
1448             ss << distribution(generator);
1449         }
1450     }
1451     return ss.str();
1452 }
1453 
OnRemoteDied(const wptr<IRemoteObject> & object)1454 void MechManager::AttachStateChangeStubDeathListener::OnRemoteDied(const wptr <IRemoteObject> &object)
1455 {
1456     HILOGE("AttachStateChangeStub RemoteObject dead; ");
1457     std::lock_guard<std::mutex> lock(attachStateChangeStubMutex_);
1458     attachStateChangeStub_ = nullptr;
1459 }
1460 
OnRemoteDied(const wptr<IRemoteObject> & object)1461 void MechManager::TrackingEventStubDeathListener::OnRemoteDied(const wptr <IRemoteObject> &object)
1462 {
1463     HILOGE("TrackingEventStub RemoteObject dead; ");
1464     std::lock_guard<std::mutex> lock(trackingEventStubMutex_);
1465     trackingEventStub_ = nullptr;
1466 }
1467 
OnRemoteDied(const wptr<IRemoteObject> & object)1468 void MechManager::RotationAxesStatusChangeStubDeathListener::OnRemoteDied(const wptr <IRemoteObject> &object)
1469 {
1470     HILOGE("RotationAxesStatusChangeStub RemoteObject dead; ");
1471     std::lock_guard<std::mutex> lock(rotationAxesStatusChangeMutex_);
1472     rotationAxesStatusChangeStub_ = nullptr;
1473 }
1474 
OnRemoteDied(const wptr<IRemoteObject> & object)1475 void MechManager::CmdChannelDeathListener::OnRemoteDied(const wptr <IRemoteObject> &object)
1476 {
1477     HILOGE("CmdChannel RemoteObject dead; ");
1478     std::lock_guard<std::mutex> lock(cmdChannelMutex_);
1479     cmdChannel_ = nullptr;
1480 }
1481 
1482 
Init(napi_env env,napi_value exports)1483 napi_value Init(napi_env env, napi_value exports)
1484 {
1485     napi_value rotationAxisLimitedEnum =
1486         CreateEnumObject(env, {{"NOT_LIMITED", 0}, {"NEGATIVE_LIMITED", 1}, {"POSITIVE_LIMITED", 2}});
1487     napi_set_named_property(env, exports, "RotationAxisLimited", rotationAxisLimitedEnum);
1488     napi_value operationEnum = CreateEnumObject(env, {{"CONNECT", 0}, {"DISCONNECT", 1}});
1489     napi_set_named_property(env, exports, "Operation", operationEnum);
1490     napi_value trackingEventEnum =
1491         CreateEnumObject(env, {{"CAMERA_TRACKING_USER_ENABLED", 0}, {"CAMERA_TRACKING_USER_DISABLED", 1},
1492                                {"CAMERA_TRACKING_LAYOUT_CHANGED", 2}});
1493     napi_set_named_property(env, exports, "TrackingEvent", trackingEventEnum);
1494     napi_value resultEnum =
1495         CreateEnumObject(env, {{"COMPLETED", 0}, {"INTERRUPTED", 1}, {"LIMITED", 2},
1496                                {"TIMEOUT",3}, {"SYSTEM_ERROR", 100}});
1497     napi_set_named_property(env, exports, "Result", resultEnum);
1498     napi_value mechDeviceTypeEnum = CreateEnumObject(env, {{"GIMBAL_DEVICE", 0}});
1499     napi_set_named_property(env, exports, "MechDeviceType", mechDeviceTypeEnum);
1500     napi_value attachStateEnum = CreateEnumObject(env, {{"ATTACHED", 0}, {"DETACHED", 1}});
1501     napi_set_named_property(env, exports, "AttachState", attachStateEnum);
1502     napi_value cameraTrackingLayoutEnum =
1503         CreateEnumObject(env, {{"DEFAULT", 0}, {"LEFT", 1}, {"MIDDLE", 2}, {"RIGHT", 3}});
1504     napi_set_named_property(env, exports, "CameraTrackingLayout", cameraTrackingLayoutEnum);
1505     napi_value MechManager;
1506     napi_create_object(env, &MechManager);
1507     napi_property_descriptor desc[] = {
1508             DECLARE_NAPI_FUNCTION("on", MechManager::On),
1509             DECLARE_NAPI_FUNCTION("off", MechManager::Off),
1510 
1511             DECLARE_NAPI_FUNCTION("getAttachedMechDevices", MechManager::GetAttachedDevices),
1512             DECLARE_NAPI_FUNCTION("setUserOperation", MechManager::SetUserOperation),
1513 
1514             DECLARE_NAPI_FUNCTION("setCameraTrackingEnabled", MechManager::SetCameraTrackingEnabled),
1515             DECLARE_NAPI_FUNCTION("getCameraTrackingEnabled", MechManager::GetCameraTrackingEnabled),
1516             DECLARE_NAPI_FUNCTION("setCameraTrackingLayout", MechManager::SetCameraTrackingLayout),
1517             DECLARE_NAPI_FUNCTION("getCameraTrackingLayout", MechManager::GetCameraTrackingLayout),
1518 
1519             DECLARE_NAPI_FUNCTION("rotate", MechManager::Rotate),
1520             DECLARE_NAPI_FUNCTION("rotateToEulerAngles", MechManager::RotateToEulerAngles),
1521             DECLARE_NAPI_FUNCTION("getMaxRotationTime", MechManager::GetMaxRotationTime),
1522             DECLARE_NAPI_FUNCTION("getMaxRotationSpeed", MechManager::GetMaxRotationSpeed),
1523             DECLARE_NAPI_FUNCTION("rotateBySpeed", MechManager::RotateBySpeed),
1524             DECLARE_NAPI_FUNCTION("stopMoving", MechManager::StopMoving),
1525             DECLARE_NAPI_FUNCTION("getCurrentAngles", MechManager::GetCurrentAngles),
1526             DECLARE_NAPI_FUNCTION("getRotationLimits", MechManager::GetRotationLimits),
1527             DECLARE_NAPI_FUNCTION("getRotationAxesStatus", MechManager::GetRotationAxesStatus),
1528     };
1529     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1530     return exports;
1531 }
1532 
1533 static napi_module mechManagerModule = {
1534         .nm_filename = "distributedHardware/libmechanicmanager_napi.so/mechanicmanager.js",
1535         .nm_register_func = Init,
1536         .nm_modname = "distributedHardware.mechanicManager",
1537 };
1538 
MechManagerModuleRegister()1539 extern "C" __attribute__((constructor)) void MechManagerModuleRegister()
1540 {
1541     napi_module_register(&mechManagerModule);
1542 }
1543 } // namespace MechManager
1544 } // namespace OHOS