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 "mechbody_controller_service.h"
17
18 #include "cJSON.h"
19 #include <string>
20
21 #include "accesstoken_kit.h"
22 #include "ble_send_manager.h"
23 #include "mechbody_controller_log.h"
24 #include "mechbody_controller_utils.h"
25 #include "mc_controller_manager.h"
26 #include "mc_controller_ipc_death_listener.h"
27 #include "mechbody_controller_ipc_interface_code.h"
28 #include "tokenid_kit.h"
29
30 namespace OHOS {
31 namespace MechBodyController {
32 namespace {
33 const std::string TAG = "MechBodyControllerService";
34 const std::string PERMISSION_NAME = "ohos.permission.CONNECT_MECHANIC_HARDWARE";
35 }
36
GetInstance()37 MechBodyControllerService& MechBodyControllerService::GetInstance()
38 {
39 static auto instance = new MechBodyControllerService();
40 return *instance;
41 }
42
43 const bool REGISTER_RESULT =
44 SystemAbility::MakeAndRegisterAbility(&MechBodyControllerService::GetInstance());
45
MechBodyControllerService()46 MechBodyControllerService::MechBodyControllerService() : SystemAbility(MECH_SERVICE_SA_ID, true)
47 {
48 }
49
~MechBodyControllerService()50 MechBodyControllerService::~MechBodyControllerService()
51 {
52 HILOGI("~MechBodyControllerService.");
53 }
54
OnStart()55 void MechBodyControllerService::OnStart()
56 {
57 // LCOV_EXCL_START
58 HILOGI("MechBodyControllerService start.");
59 bool res = Publish(this);
60 if (!res) {
61 HILOGE("MechBodyControllerService start failed.");
62 }
63 MechConnectManager::GetInstance().Init();
64
65 if (sendAdapter_ == nullptr) {
66 sendAdapter_ = std::make_shared<TransportSendAdapter>();
67 sendAdapter_->RegisterBluetoothListener();
68 }
69 BleSendManager::GetInstance().Init();
70
71 HILOGI("MechBodyControllerService start end.");
72 // LCOV_EXCL_STOP
73 }
74
OnStop()75 void MechBodyControllerService::OnStop()
76 {
77 if (sendAdapter_ != nullptr) {
78 sendAdapter_->UnRegisterBluetoothListener();
79 sendAdapter_ = nullptr;
80 }
81 BleSendManager::GetInstance().UnInit();
82 McCameraTrackingController::GetInstance().UnInit();
83 MechConnectManager::GetInstance().UnInit();
84 }
85
RegisterAttachStateChangeCallback(const sptr<IRemoteObject> callback)86 int32_t MechBodyControllerService::RegisterAttachStateChangeCallback(const sptr<IRemoteObject> callback)
87 {
88 // LCOV_EXCL_START
89 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
90 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
91 if (callback == nullptr) {
92 HILOGE("callback is nullptr");
93 return INVALID_REMOTE_OBJECT;
94 }
95
96 sptr <MechControllerIpcDeathListener> diedListener = new MechControllerIpcDeathListener();
97 diedListener->tokenId_ = tokenId;
98 diedListener->objectType_ = RemoteObjectType::DEVICE_ATTACH_CALLBACK;
99 callback->AddDeathRecipient(diedListener);
100 {
101 std::lock_guard<std::mutex> lock(deviceAttachCallbackMutex);
102 deviceAttachCallback_[tokenId] = callback;
103 HILOGI("callback add success, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
104 if (listener_ == nullptr) {
105 listener_ = std::make_shared<MechConnectListenerImpl>();
106 int32_t registerListenerResult = MechConnectManager::GetInstance().AddDeviceChangeListener(listener_);
107 HILOGI("Register listener to MechConnectManager %{public}s, tokenId: %{public}s;",
108 registerListenerResult == ERR_OK ? "success" : "failed", GetAnonymUint32(tokenId).c_str());
109 if (registerListenerResult != ERR_OK) {
110 deviceAttachCallback_.erase(tokenId);
111 return REGISTER_CALLBACK_FAILED;
112 }
113 } else {
114 HILOGI("DeviceChangeListener has registered");
115 }
116 }
117 HILOGI("end, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
118 return ERR_OK;
119 // LCOV_EXCL_STOP
120 }
121
UnRegisterAttachStateChangeCallback()122 int32_t MechBodyControllerService::UnRegisterAttachStateChangeCallback()
123 {
124 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
125 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
126 std::lock_guard<std::mutex> lock(deviceAttachCallbackMutex);
127 if (deviceAttachCallback_.size() == 1 &&
128 deviceAttachCallback_.find(tokenId) != deviceAttachCallback_.end()) {
129 int32_t unRegisterResult = MechConnectManager::GetInstance().RemoveDeviceChangeListener(listener_);
130 HILOGI("Unregister listener from MechConnectManager %{public}s, tokenId: %{public}s;",
131 unRegisterResult == ERR_OK ? "success" : "failed", GetAnonymUint32(tokenId).c_str());
132 if (unRegisterResult != ERR_OK) {
133 return UNREGISTER_CALLBACK_FAILED;
134 }
135 listener_ = nullptr;
136 deviceAttachCallback_.clear();
137 HILOGI("Callback clean success, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
138 } else {
139 deviceAttachCallback_.erase(tokenId);
140 HILOGI("Callback remove success, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
141 }
142 HILOGI("end, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
143 return ERR_OK;
144 }
145
OnAttachStateChange(const AttachmentState & attachmentState,const MechInfo & mechInfo)146 int32_t MechBodyControllerService::OnAttachStateChange(const AttachmentState &attachmentState,
147 const MechInfo &mechInfo)
148 {
149 HILOGI("start");
150 std::lock_guard<std::mutex> lock(deviceAttachCallbackMutex);
151 for (const auto &item: deviceAttachCallback_) {
152 uint32_t tokenId = item.first;
153 HILOGI("start send callback data to tokenId: %{public}s; mech info: %{public}s",
154 GetAnonymUint32(tokenId).c_str(),
155 mechInfo.ToString().c_str());
156 sptr <IRemoteObject> callback = item.second;
157 MessageParcel data;
158 if (!data.WriteInterfaceToken(MECH_SERVICE_IPC_TOKEN)) {
159 HILOGE("Write interface token failed, tokenId: %{public}s, mechId: %{public}d, event: %{public}s",
160 GetAnonymUint32(tokenId).c_str(),
161 mechInfo.mechId, mechInfo.ToString().c_str());
162 continue;
163 }
164
165 if (!data.WriteInt32(static_cast<int32_t>(attachmentState))) {
166 HILOGE("Write mechId failed, tokenId: %{public}s, mechId: %{public}d, attachmentState: %{public}d",
167 GetAnonymUint32(tokenId).c_str(),
168 mechInfo.mechId, static_cast<int32_t>(attachmentState));
169 return SEND_CALLBACK_INFO_FAILED;
170 }
171
172 if (!data.WriteParcelable(&mechInfo)) {
173 HILOGE("Write state failed");
174 return SEND_CALLBACK_INFO_FAILED;
175 }
176
177 if (callback == nullptr) {
178 HILOGE("Remote object is null");
179 return SEND_CALLBACK_INFO_FAILED;
180 }
181
182 MessageParcel reply;
183 MessageOption option;
184 int32_t error =
185 callback->SendRequest(static_cast<uint32_t>(IMechBodyControllerCode::ATTACH_STATE_CHANGE_CALLBACK),
186 data, reply, option);
187 HILOGI("Send callback data %{public}s, result code: %{public}d",
188 error == ERR_NONE ? "success" : "failed", error);
189 }
190 HILOGI("end");
191 return ERR_OK;
192 }
193
SetUserOperation(const std::shared_ptr<Operation> & operation,const std::string & mac,const std::string & param)194 int32_t MechBodyControllerService::SetUserOperation(const std::shared_ptr<Operation> &operation,
195 const std::string &mac, const std::string ¶m)
196 {
197 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
198 HILOGI("start,tokenId: %{public}s; user operation: %{public}d; mac: %{public}s;",
199 GetAnonymUint32(tokenId).c_str(), static_cast<int32_t>(*operation),
200 GetAnonymStr(mac).c_str());
201 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, PERMISSION_NAME);
202 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
203 HILOGE("%{public}s: PERMISSION_DENIED", PERMISSION_NAME.c_str());
204 return PERMISSION_DENIED;
205 }
206 if (!IsSystemApp()) {
207 HILOGE("current app is not system app.");
208 return PERMISSION_DENIED;
209 }
210 cJSON *rootValue = cJSON_Parse(param.c_str());
211 if (rootValue == nullptr) {
212 HILOGE("Parse param json error.");
213 return INVALID_PARAMETERS_ERR;
214 }
215 cJSON *deviceNameJson = cJSON_GetObjectItemCaseSensitive(rootValue, "device_name");
216 if (deviceNameJson == nullptr || !cJSON_IsString(deviceNameJson) || (deviceNameJson->valuestring == nullptr)) {
217 cJSON_Delete(rootValue);
218 HILOGE("Parse deviceName error.");
219 return INVALID_PARAMETERS_ERR;
220 }
221 std::string deviceName = deviceNameJson->valuestring;
222 cJSON_Delete(rootValue);
223 BleSendManager::GetInstance().MechbodyConnect(mac, deviceName);
224 return ERR_OK;
225 }
226
OnDeviceConnected(int32_t mechId)227 int32_t MechBodyControllerService::OnDeviceConnected(int32_t mechId)
228 {
229 HILOGI("enter. mechId %{public}d", mechId);
230 std::lock_guard<std::mutex> lock(motionManagersMutex);
231 if (motionManagers_.empty() || motionManagers_.find(mechId) == motionManagers_.end()) {
232 HILOGI("create new. mechId %{public}d", mechId);
233 if (sendAdapter_ == nullptr) {
234 sendAdapter_ = std::make_shared<TransportSendAdapter>();
235 sendAdapter_->RegisterBluetoothListener();
236 }
237 std::shared_ptr<MotionManager> manager = std::make_shared<MotionManager>(sendAdapter_, mechId);
238 manager->RegisterEventListener();
239 motionManagers_[mechId] = manager;
240 }
241 HILOGI("end");
242 return ERR_OK;
243 }
244
OnDeviceDisconnected(int32_t mechId)245 int32_t MechBodyControllerService::OnDeviceDisconnected(int32_t mechId)
246 {
247 HILOGI("enter. mechId %{public}d", mechId);
248 std::lock_guard<std::mutex> lock(motionManagersMutex);
249 if (motionManagers_.empty()) {
250 HILOGD("motionManagers_ is empty.");
251 return ERR_OK;
252 }
253 auto it = motionManagers_.find(mechId);
254 if (it != motionManagers_.end()) {
255 HILOGD("find to erase.");
256 it->second->UnRegisterNotifyEvent();
257 it->second = nullptr;
258 motionManagers_.erase(it);
259 }
260 return ERR_OK;
261 }
262
GetAttachedDevices(std::set<MechInfo> & mechInfo)263 int32_t MechBodyControllerService::GetAttachedDevices(std::set<MechInfo> &mechInfo)
264 {
265 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
266 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
267 if (!MechConnectManager::GetInstance().GetConnectMechList(mechInfo)) {
268 mechInfo.clear();
269 HILOGE("Get attached devices failed.");
270 }
271 HILOGI("end, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
272 return ERR_OK;
273 }
274
SetTrackingEnabled(bool & isEnabled)275 int32_t MechBodyControllerService::SetTrackingEnabled(bool &isEnabled)
276 {
277 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
278 HILOGI("start, tokenId: %{public}s; isEnabled: %{public}s;",
279 GetAnonymUint32(tokenId).c_str(), isEnabled ? "true" : "false");
280 int32_t setResult = McControllerManager::GetInstance().SetTrackingEnabled(tokenId, isEnabled);
281 HILOGI("end. Set Tracking Enabled result: %{public}d.", setResult);
282 return setResult;
283 }
284
GetTrackingEnabled(bool & isEnabled)285 int32_t MechBodyControllerService::GetTrackingEnabled(bool &isEnabled)
286 {
287 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
288 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
289 int32_t getResult = McControllerManager::GetInstance().GetTrackingEnabled(tokenId, isEnabled);
290 HILOGI("end. Get Tracking Enabled result: %{public}d.", getResult);
291 return getResult;
292 }
293
RegisterTrackingEventCallback(sptr<IRemoteObject> callback)294 int32_t MechBodyControllerService::RegisterTrackingEventCallback(sptr <IRemoteObject> callback)
295 {
296 // LCOV_EXCL_START
297 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
298 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
299 if (callback == nullptr) {
300 HILOGE("callback is nullptr");
301 return INVALID_REMOTE_OBJECT;
302 }
303 int32_t registerResult = McControllerManager::GetInstance().RegisterTrackingEventCallback(tokenId,
304 callback);
305 HILOGI("end. Register tracking event callback result: %{public}d.", registerResult);
306 return registerResult;
307 // LCOV_EXCL_STOP
308 }
309
UnRegisterTrackingEventCallback()310 int32_t MechBodyControllerService::UnRegisterTrackingEventCallback()
311 {
312 // LCOV_EXCL_START
313 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
314 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
315 int32_t unregisterResult = McControllerManager::GetInstance().UnRegisterTrackingEventCallback(tokenId);
316 HILOGI("end. Unregister tracking event callback result: %{public}d.", unregisterResult);
317 return unregisterResult;
318 // LCOV_EXCL_STOP
319 }
320
SetTrackingLayout(CameraTrackingLayout & cameraTrackingLayout)321 int32_t MechBodyControllerService::SetTrackingLayout(CameraTrackingLayout &cameraTrackingLayout)
322 {
323 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
324 HILOGI("start, tokenId: %{public}s; CameraTrackingLayout: %{public}d;", GetAnonymUint32(tokenId).c_str(),
325 static_cast<int32_t>(cameraTrackingLayout));
326 if (!IsSystemApp()) {
327 HILOGE("current app is not system app.");
328 return PERMISSION_DENIED;
329 }
330 int32_t setTrackingLayoutResult = McControllerManager::GetInstance()
331 .SetTrackingLayout(tokenId, cameraTrackingLayout);
332 HILOGI("end. Set tracking layout result: %{public}d.", setTrackingLayoutResult);
333 return setTrackingLayoutResult;
334 }
335
GetTrackingLayout(CameraTrackingLayout & cameraTrackingLayout)336 int32_t MechBodyControllerService::GetTrackingLayout(CameraTrackingLayout &cameraTrackingLayout)
337 {
338 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
339 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
340 int32_t getTrackingLayoutResult =
341 McControllerManager::GetInstance().GetTrackingLayout(tokenId, cameraTrackingLayout);
342 HILOGI("end. Get tracking layout result: %{public}d.", getTrackingLayoutResult);
343 return getTrackingLayoutResult;
344 }
345
RegisterCmdChannel(const sptr<IRemoteObject> callback)346 int32_t MechBodyControllerService::RegisterCmdChannel(const sptr<IRemoteObject> callback)
347 {
348 // LCOV_EXCL_START
349 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
350 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
351 sptr <MechControllerIpcDeathListener> diedListener = new MechControllerIpcDeathListener();
352 diedListener->tokenId_ = tokenId;
353 diedListener->objectType_ = RemoteObjectType::COMMAND_CHANNEL;
354 CHECK_POINTER_RETURN_VALUE(callback, INVALID_PARAMETERS_ERR, "callback");
355 callback->AddDeathRecipient(diedListener);
356 {
357 std::lock_guard<std::mutex> lock(cmdChannelMutex_);
358 cmdChannels_[tokenId] = callback;
359 }
360 HILOGI("command channel add success, tokenid: %{public}s;", GetAnonymUint32(tokenId).c_str());
361 return ERR_OK;
362 // LCOV_EXCL_STOP
363 }
364
RotateByDegree(const int32_t & mechId,std::string & cmdId,const std::shared_ptr<RotateByDegreeParam> & rotateByDegreeParam)365 int32_t MechBodyControllerService::RotateByDegree(const int32_t &mechId, std::string &cmdId,
366 const std::shared_ptr<RotateByDegreeParam> &rotateByDegreeParam)
367 {
368 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
369 if (!IsSystemApp()) {
370 HILOGE("current app is not system app.");
371 return PERMISSION_DENIED;
372 }
373 if (mechId < 0) {
374 HILOGE("Invalid mech id");
375 return INVALID_MECH_ID;
376 }
377 if (!rotateByDegreeParam) {
378 HILOGE("Invalid rotateByDegreeParam");
379 return INVALID_ROTATE_PARAM;
380 }
381 if (rotateByDegreeParam->duration < 0) {
382 HILOGE("Invalid duration");
383 return INVALID_ROTATE_PARAM;
384 }
385 HILOGI("start, tokenId: %{public}s; mechId: %{public}d; rotate param: %{public}s",
386 GetAnonymUint32(tokenId).c_str(), mechId, rotateByDegreeParam->ToString().c_str());
387 if (rotateByDegreeParam->duration == 0) {
388 NotifyOperationResult(tokenId, cmdId, ExecResult::COMPLETED);
389 return ERR_OK;
390 }
391 std::shared_ptr<RotateParam> rotateParam = std::make_shared<RotateParam>();
392 rotateParam->degree.yaw = rotateByDegreeParam->degree.yaw;
393 rotateParam->degree.roll = rotateByDegreeParam->degree.roll;
394 rotateParam->degree.pitch = rotateByDegreeParam->degree.pitch;
395 rotateParam->duration = rotateByDegreeParam->duration;
396 rotateParam->isRelative = true;
397 HILOGI("RotateParam: %{public}s", rotateParam->ToString().c_str());
398
399 std::lock_guard<std::mutex> lock(motionManagersMutex);
400 if (motionManagers_.empty()) {
401 return DEVICE_NOT_CONNECTED;
402 }
403 auto it = motionManagers_.find(mechId);
404 if (it == motionManagers_.end()) {
405 return DEVICE_NOT_CONNECTED;
406 }
407 std::shared_ptr<MotionManager> motionManager = it->second;
408 if (motionManager == nullptr) {
409 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
410 GetAnonymUint32(tokenId).c_str(), mechId);
411 return DEVICE_NOT_CONNECTED;
412 }
413 int32_t result = motionManager->Rotate(rotateParam, tokenId, cmdId);
414 HILOGI("end. Rotate By Degree execute result: %{public}d.", result);
415 return result;
416 }
417
NotifyOperationResult(const uint32_t & tokenId,const std::string & cmdId,const ExecResult & result)418 int32_t MechBodyControllerService::NotifyOperationResult(const uint32_t &tokenId, const std::string &cmdId,
419 const ExecResult &result)
420 {
421 HILOGI("start, result: %{public}d;", result);
422 MessageParcel data;
423 if (!data.WriteInterfaceToken(MECH_SERVICE_IPC_TOKEN)) {
424 HILOGE("Write interface token failed");
425 return SEND_CALLBACK_INFO_FAILED;
426 }
427
428 if (!data.WriteString(cmdId)) {
429 HILOGE("Write cmdId failed");
430 return SEND_CALLBACK_INFO_FAILED;
431 }
432 if (!data.WriteInt32(static_cast<int32_t>(result))) {
433 HILOGE("Write result failed");
434 return SEND_CALLBACK_INFO_FAILED;
435 }
436 MessageParcel reply;
437 MessageOption option;
438 {
439 std::lock_guard<std::mutex> lock(cmdChannelMutex_);
440 sptr<IRemoteObject> callback = cmdChannels_[tokenId];
441 if (callback == nullptr) {
442 HILOGI("command channel is nullptr for tokenId: %{public}s", GetAnonymUint32(tokenId).c_str());
443 return NAPI_SEND_DATA_FAIL;
444 }
445 int32_t error =
446 callback->SendRequest(static_cast<uint32_t>(IMechBodyControllerCode::ROTATE_CALLBACK),
447 data, reply, option);
448 HILOGI("Send callback data %{public}s", error == ERR_NONE ? "success" : "failed");
449 }
450
451 return ERR_OK;
452 }
453
RotateToEulerAngles(const int32_t & mechId,std::string & cmdId,const std::shared_ptr<RotateToEulerAnglesParam> & rotateToEulerAnglesParam)454 int32_t MechBodyControllerService::RotateToEulerAngles(const int32_t &mechId, std::string &cmdId,
455 const std::shared_ptr<RotateToEulerAnglesParam> &rotateToEulerAnglesParam)
456 {
457 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
458 if (!IsSystemApp()) {
459 HILOGE("current app is not system app.");
460 return PERMISSION_DENIED;
461 }
462 if (mechId < 0) {
463 HILOGE("Invalid mech id");
464 return INVALID_MECH_ID;
465 }
466 if (!rotateToEulerAnglesParam) {
467 HILOGE("Invalid rotateToEulerAnglesParam");
468 return INVALID_ROTATE_PARAM;
469 }
470 if (rotateToEulerAnglesParam->duration < 0) {
471 HILOGE("Invalid duration");
472 return INVALID_ROTATE_PARAM;
473 }
474 HILOGI("start, tokenId: %{public}s; mechId: %{public}d; rotate param: %{public}s",
475 GetAnonymUint32(tokenId).c_str(), mechId, rotateToEulerAnglesParam->ToString().c_str());
476 if (rotateToEulerAnglesParam->duration == 0) {
477 NotifyOperationResult(tokenId, cmdId, ExecResult::COMPLETED);
478 return ERR_OK;
479 }
480 std::shared_ptr<RotateParam> rotateParam = std::make_shared<RotateParam>();
481 rotateParam->degree.yaw = rotateToEulerAnglesParam->angles.yaw;
482 rotateParam->degree.roll = rotateToEulerAnglesParam->angles.roll;
483 rotateParam->degree.pitch = rotateToEulerAnglesParam->angles.pitch;
484 rotateParam->duration = rotateToEulerAnglesParam->duration;
485 rotateParam->isRelative = false;
486 HILOGI("RotateParam: %{public}s", rotateParam->ToString().c_str());
487
488 std::lock_guard<std::mutex> lock(motionManagersMutex);
489 if (motionManagers_.empty()) {
490 return DEVICE_NOT_CONNECTED;
491 }
492 auto it = motionManagers_.find(mechId);
493 if (it == motionManagers_.end()) {
494 return DEVICE_NOT_CONNECTED;
495 }
496 std::shared_ptr<MotionManager> motionManager = it->second;
497 if (motionManager == nullptr) {
498 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
499 GetAnonymUint32(tokenId).c_str(), mechId);
500 return DEVICE_NOT_CONNECTED;
501 }
502 int32_t result = motionManager->Rotate(rotateParam, tokenId, cmdId);
503 HILOGI("end. execute result: %{public}d.", result);
504 return result;
505 }
506
GetMaxRotationTime(const int32_t & mechId,std::shared_ptr<TimeLimit> & timeLimit)507 int32_t MechBodyControllerService::GetMaxRotationTime(const int32_t &mechId,
508 std::shared_ptr<TimeLimit> &timeLimit)
509 {
510 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
511 if (!IsSystemApp()) {
512 HILOGE("current app is not system app.");
513 return PERMISSION_DENIED;
514 }
515 if (mechId < 0) {
516 HILOGE("Invalid mech id");
517 return INVALID_MECH_ID;
518 }
519 HILOGI("start, tokenId: %{public}s; mechId: %{public}d;", GetAnonymUint32(tokenId).c_str(), mechId);
520
521 std::lock_guard<std::mutex> lock(motionManagersMutex);
522 if (motionManagers_.empty()) {
523 return DEVICE_NOT_CONNECTED;
524 }
525 auto it = motionManagers_.find(mechId);
526 if (it == motionManagers_.end()) {
527 return DEVICE_NOT_CONNECTED;
528 }
529 std::shared_ptr<MotionManager> motionManager = it->second;
530 if (motionManager == nullptr) {
531 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
532 GetAnonymUint32(tokenId).c_str(), mechId);
533 return DEVICE_NOT_CONNECTED;
534 }
535 int32_t result = motionManager->GetSpeedControlTimeLimit(timeLimit);
536 HILOGI("end. result: %{public}d.", result);
537 return result;
538 }
539
GetMaxRotationSpeed(const int32_t & mechId,RotateSpeedLimit & speedLimit)540 int32_t MechBodyControllerService::GetMaxRotationSpeed(const int32_t &mechId,
541 RotateSpeedLimit &speedLimit)
542 {
543 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
544 if (!IsSystemApp()) {
545 HILOGE("current app is not system app.");
546 return PERMISSION_DENIED;
547 }
548 if (mechId < 0) {
549 HILOGE("Invalid mech id");
550 return INVALID_MECH_ID;
551 }
552 HILOGI("start, tokenId: %{public}s; mechId: %{public}d;", GetAnonymUint32(tokenId).c_str(), mechId);
553
554 std::lock_guard<std::mutex> lock(motionManagersMutex);
555 if (motionManagers_.empty()) {
556 return DEVICE_NOT_CONNECTED;
557 }
558 auto it = motionManagers_.find(mechId);
559 if (it == motionManagers_.end()) {
560 return DEVICE_NOT_CONNECTED;
561 }
562 std::shared_ptr<MotionManager> motionManager = it->second;
563 if (motionManager == nullptr) {
564 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
565 GetAnonymUint32(tokenId).c_str(), mechId);
566 return DEVICE_NOT_CONNECTED;
567 }
568 int32_t result = motionManager->GetRotateSpeedLimit(speedLimit);
569 HILOGI("end. result: %{public}d.", result);
570 return result;
571 }
572
RotateBySpeed(const int32_t & mechId,std::string & cmdId,const std::shared_ptr<RotateBySpeedParam> & rotateBySpeedParam)573 int32_t MechBodyControllerService::RotateBySpeed(const int32_t &mechId, std::string &cmdId,
574 const std::shared_ptr<RotateBySpeedParam> &rotateBySpeedParam)
575 {
576 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
577 if (!IsSystemApp()) {
578 HILOGE("current app is not system app.");
579 return PERMISSION_DENIED;
580 }
581 if (mechId < 0) {
582 HILOGE("Invalid mech id");
583 return INVALID_MECH_ID;
584 }
585 if (rotateBySpeedParam == nullptr) {
586 HILOGE("rotateBySpeedParam is nullptr.");
587 return INVALID_ROTATE_PARAM;
588 }
589 HILOGI("start, tokenId: %{public}s; mechId: %{public}d; rotate speed param: %{public}s",
590 GetAnonymUint32(tokenId).c_str(), mechId, rotateBySpeedParam->ToString().c_str());
591
592 if (rotateBySpeedParam->duration == 0) {
593 NotifyOperationResult(tokenId, cmdId, ExecResult::COMPLETED);
594 return ERR_OK;
595 }
596 std::lock_guard<std::mutex> lock(motionManagersMutex);
597 if (motionManagers_.empty()) {
598 return DEVICE_NOT_CONNECTED;
599 }
600 auto it = motionManagers_.find(mechId);
601 if (it == motionManagers_.end()) {
602 return DEVICE_NOT_CONNECTED;
603 }
604 std::shared_ptr<MotionManager> motionManager = it->second;
605 if (motionManager == nullptr) {
606 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
607 GetAnonymUint32(tokenId).c_str(), mechId);
608 return DEVICE_NOT_CONNECTED;
609 }
610 int32_t result = motionManager->RotateBySpeed(rotateBySpeedParam, tokenId, cmdId);
611 HILOGI("end. execute result: %{public}d.", result);
612 return result;
613 }
614
StopMoving(const int32_t & mechId,std::string & cmdId)615 int32_t MechBodyControllerService::StopMoving(const int32_t &mechId, std::string &cmdId)
616 {
617 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
618 if (!IsSystemApp()) {
619 HILOGE("current app is not system app.");
620 return PERMISSION_DENIED;
621 }
622 if (mechId < 0) {
623 HILOGE("Invalid mech id");
624 return INVALID_MECH_ID;
625 }
626 HILOGI("start, tokenId: %{public}s; mechId: %{public}d; cmdId: %{public}s",
627 GetAnonymUint32(tokenId).c_str(), mechId, cmdId.c_str());
628
629 std::lock_guard<std::mutex> lock(motionManagersMutex);
630 if (motionManagers_.empty()) {
631 return DEVICE_NOT_CONNECTED;
632 }
633 auto it = motionManagers_.find(mechId);
634 if (it == motionManagers_.end()) {
635 return DEVICE_NOT_CONNECTED;
636 }
637 std::shared_ptr<MotionManager> motionManager = it->second;
638 if (motionManager == nullptr) {
639 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
640 GetAnonymUint32(tokenId).c_str(), mechId);
641 return DEVICE_NOT_CONNECTED;
642 }
643 int32_t result = motionManager->StopRotate(tokenId, cmdId);
644 HILOGI("end. execute result: %{public}d.", result);
645 return result;
646 }
647
GetRotationAngles(const int32_t & mechId,std::shared_ptr<EulerAngles> & eulerAngles)648 int32_t MechBodyControllerService::GetRotationAngles(const int32_t &mechId,
649 std::shared_ptr<EulerAngles> &eulerAngles)
650 {
651 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
652 if (!IsSystemApp()) {
653 HILOGE("current app is not system app.");
654 return PERMISSION_DENIED;
655 }
656 if (mechId < 0) {
657 HILOGE("Invalid mech id");
658 return INVALID_MECH_ID;
659 }
660 HILOGI("start, tokenId: %{public}s; mechId: %{public}d;", GetAnonymUint32(tokenId).c_str(), mechId);
661 std::lock_guard<std::mutex> lock(motionManagersMutex);
662 if (motionManagers_.empty()) {
663 return DEVICE_NOT_CONNECTED;
664 }
665 auto it = motionManagers_.find(mechId);
666 if (it == motionManagers_.end()) {
667 return DEVICE_NOT_CONNECTED;
668 }
669 std::shared_ptr<MotionManager> motionManager = it->second;
670 if (motionManager == nullptr) {
671 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
672 GetAnonymUint32(tokenId).c_str(), mechId);
673 return DEVICE_NOT_CONNECTED;
674 }
675 int32_t result = motionManager->GetCurrentPosition(eulerAngles);
676 HILOGI("end. query result: %{public}d.", result);
677 return result;
678 }
679
GetRotationDegreeLimits(const int32_t & mechId,RotateDegreeLimit & rotationLimit)680 int32_t MechBodyControllerService::GetRotationDegreeLimits(const int32_t &mechId,
681 RotateDegreeLimit &rotationLimit)
682 {
683 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
684 if (!IsSystemApp()) {
685 HILOGE("current app is not system app.");
686 return PERMISSION_DENIED;
687 }
688 if (mechId < 0) {
689 HILOGE("Invalid mech id");
690 return INVALID_MECH_ID;
691 }
692 HILOGI("start, tokenId: %{public}s; mechId: %{public}d;", GetAnonymUint32(tokenId).c_str(), mechId);
693 std::lock_guard<std::mutex> lock(motionManagersMutex);
694 if (motionManagers_.empty()) {
695 return DEVICE_NOT_CONNECTED;
696 }
697 auto it = motionManagers_.find(mechId);
698 if (it == motionManagers_.end()) {
699 return DEVICE_NOT_CONNECTED;
700 }
701 std::shared_ptr<MotionManager> motionManager = it->second;
702 if (motionManager == nullptr) {
703 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
704 GetAnonymUint32(tokenId).c_str(), mechId);
705 return DEVICE_NOT_CONNECTED;
706 }
707 int32_t result = motionManager->GetRotationLimit(rotationLimit);
708 HILOGI("end. query result: %{public}d.", result);
709 return result;
710 }
711
GetRotationAxesStatus(const int32_t & mechId,RotationAxesStatus & axesStatus)712 int32_t MechBodyControllerService::GetRotationAxesStatus(const int32_t &mechId,
713 RotationAxesStatus &axesStatus)
714 {
715 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
716 if (!IsSystemApp()) {
717 HILOGE("current app is not system app.");
718 return PERMISSION_DENIED;
719 }
720 if (mechId < 0) {
721 HILOGE("Invalid mech id");
722 return INVALID_MECH_ID;
723 }
724 HILOGI("start, tokenId: %{public}s; mechId: %{public}d;", GetAnonymUint32(tokenId).c_str(), mechId);
725 std::lock_guard<std::mutex> lock(motionManagersMutex);
726 if (motionManagers_.empty()) {
727 return DEVICE_NOT_CONNECTED;
728 }
729 auto it = motionManagers_.find(mechId);
730 if (it == motionManagers_.end()) {
731 return DEVICE_NOT_CONNECTED;
732 }
733 std::shared_ptr<MotionManager> motionManager = it->second;
734 if (motionManager == nullptr) {
735 HILOGE("motionManager not exist. tokenId: %{public}s; mechId: %{public}d",
736 GetAnonymUint32(tokenId).c_str(), mechId);
737 return DEVICE_NOT_CONNECTED;
738 }
739 int32_t result = motionManager->GetRotationAxesStatus(mechId, axesStatus);
740 HILOGI("end. query result: %{public}d.", result);
741 return result;
742 }
743
RegisterRotationAxesStatusChangeCallback(const sptr<IRemoteObject> callback)744 int32_t MechBodyControllerService::RegisterRotationAxesStatusChangeCallback(const sptr <IRemoteObject> callback)
745 {
746 // LCOV_EXCL_START
747 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
748 HILOGI("start tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
749 if (!IsSystemApp()) {
750 HILOGE("current app is not system app.");
751 return PERMISSION_DENIED;
752 }
753 if (callback == nullptr) {
754 HILOGE("callback is nullptr");
755 return INVALID_REMOTE_OBJECT;
756 }
757
758 sptr <MechControllerIpcDeathListener> diedListener = new MechControllerIpcDeathListener();
759 diedListener->tokenId_ = tokenId;
760 diedListener->objectType_ = RemoteObjectType::ROTATION_AXES_STATUS_CALLBACK;
761 callback->AddDeathRecipient(diedListener);
762 {
763 std::lock_guard<std::mutex> lock(AxesStatusChangeCallbackMutex_);
764 rotationAxesStatusChangeCallback_[tokenId] = callback;
765 }
766 HILOGI("end, callback add success, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
767 return ERR_OK;
768 // LCOV_EXCL_STOP
769 }
770
UnRegisterRotationAxesStatusChangeCallback()771 int32_t MechBodyControllerService::UnRegisterRotationAxesStatusChangeCallback()
772 {
773 // LCOV_EXCL_START
774 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
775 HILOGI("start, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
776 if (!IsSystemApp()) {
777 HILOGE("current app is not system app.");
778 return PERMISSION_DENIED;
779 }
780 std::lock_guard<std::mutex> lock(AxesStatusChangeCallbackMutex_);
781 rotationAxesStatusChangeCallback_.erase(tokenId);
782 HILOGI("end, callback remove success, tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
783 return ERR_OK;
784 // LCOV_EXCL_STOP
785 }
786
OnRotationAxesStatusChange(const int32_t & mechId,const RotationAxesStatus & axesStatus)787 int32_t MechBodyControllerService::OnRotationAxesStatusChange(const int32_t &mechId,
788 const RotationAxesStatus &axesStatus)
789 {
790 HILOGI("start notify Rotation Axes Status Change, mechId: %{public}d; axesStatus: %{public}s", mechId,
791 axesStatus.ToString().c_str());
792 std::lock_guard<std::mutex> lock(AxesStatusChangeCallbackMutex_);
793 for (const auto &item: rotationAxesStatusChangeCallback_) {
794 int32_t tokenId = item.first;
795 HILOGI("notify Rotation Axes Status to tokenId: %{public}s;", GetAnonymUint32(tokenId).c_str());
796 sptr <IRemoteObject> callback = item.second;
797 MessageParcel data;
798 if (!data.WriteInterfaceToken(MECH_SERVICE_IPC_TOKEN)) {
799 HILOGE("Write interface token failed");
800 continue;
801 }
802
803 if (!data.WriteInt32(mechId)) {
804 HILOGE("Write mechId failed.");
805 continue;
806 }
807
808 if (!data.WriteParcelable(&axesStatus)) {
809 HILOGE("Write axesStatus failed");
810 continue;
811 }
812 MessageParcel reply;
813 MessageOption option;
814 int32_t error =
815 callback->SendRequest(static_cast<uint32_t>(IMechBodyControllerCode::ROTATION_AXES_STATUS_CHANGE_CALLBACK),
816 data, reply, option);
817 HILOGI("notify tracking event to tokenId: %{public}s; axesStatus: %{public}s", GetAnonymUint32(tokenId).c_str(),
818 error == ERR_NONE ? "success" : "failed");
819 }
820 return ERR_OK;
821 }
822
IsSystemApp()823 bool MechBodyControllerService::IsSystemApp()
824 {
825 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
826 return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
827 }
828
829 } // namespace MechBodyController
830 } // namespace OHOS
831