1 /*
2 * Copyright (c) 2022-2023 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 "devicestatus_client.h"
17
18 #include <if_system_ability_manager.h>
19 #include <iservice_registry.h>
20 #include <system_ability_definition.h>
21
22 #include "iremote_broker.h"
23 #include "iremote_object.h"
24
25 #include "util.h"
26
27 #include "coordination_manager_impl.h"
28 #include "devicestatus_common.h"
29 #include "devicestatus_define.h"
30 #include "drag_manager_impl.h"
31 #ifdef OHOS_BUILD_ENABLE_RUST_IMPL
32 #include "fusion_data_binding_internal.h"
33 #include "fusion_frameworks_binding.h"
34 #endif // OHOS_BUILD_ENABLE_RUST_IMPL
35
36 namespace OHOS {
37 namespace Msdp {
38 namespace DeviceStatus {
39 namespace {
40 constexpr ::OHOS::HiviewDFX::HiLogLabel LABEL { LOG_CORE, MSDP_DOMAIN_ID, "DeviceStatusClient" };
41 } // namespace
42
DeviceStatusClient()43 DeviceStatusClient::DeviceStatusClient() {}
~DeviceStatusClient()44 DeviceStatusClient::~DeviceStatusClient()
45 {
46 if (devicestatusProxy_ != nullptr) {
47 auto remoteObject = devicestatusProxy_->AsObject();
48 if (remoteObject != nullptr) {
49 remoteObject->RemoveDeathRecipient(deathRecipient_);
50 }
51 }
52 }
53
Connect()54 ErrCode DeviceStatusClient::Connect()
55 {
56 std::lock_guard<std::mutex> lock(mutex_);
57 if (devicestatusProxy_ != nullptr) {
58 return RET_OK;
59 }
60
61 sptr<ISystemAbilityManager> sa = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
62 CHKPR(sa, E_DEVICESTATUS_GET_SYSTEM_ABILITY_MANAGER_FAILED);
63
64 sptr<IRemoteObject> remoteObject = sa->CheckSystemAbility(MSDP_DEVICESTATUS_SERVICE_ID);
65 CHKPR(remoteObject, E_DEVICESTATUS_GET_SERVICE_FAILED);
66
67 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new (std::nothrow) DeviceStatusDeathRecipient());
68 CHKPR(deathRecipient_, ERR_NO_MEMORY);
69
70 if (remoteObject->IsProxyObject()) {
71 if (!remoteObject->AddDeathRecipient(deathRecipient_)) {
72 FI_HILOGE("Add death recipient to DeviceStatus service failed");
73 return E_DEVICESTATUS_ADD_DEATH_RECIPIENT_FAILED;
74 }
75 }
76
77 devicestatusProxy_ = iface_cast<Idevicestatus>(remoteObject);
78 FI_HILOGD("Connecting DeviceStatusService success");
79 return RET_OK;
80 }
81
ResetProxy(const wptr<IRemoteObject> & remote)82 void DeviceStatusClient::ResetProxy(const wptr<IRemoteObject>& remote)
83 {
84 std::lock_guard<std::mutex> lock(mutex_);
85 CHKPV(devicestatusProxy_);
86 auto serviceRemote = devicestatusProxy_->AsObject();
87 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
88 serviceRemote->RemoveDeathRecipient(deathRecipient_);
89 devicestatusProxy_ = nullptr;
90 }
91 if (deathListener_ != nullptr) {
92 FI_HILOGI("notify death listner");
93 deathListener_();
94 }
95 }
96
OnRemoteDied(const wptr<IRemoteObject> & remote)97 void DeviceStatusClient::DeviceStatusDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
98 {
99 CHKPV(remote);
100 DeviceStatusClient::GetInstance().ResetProxy(remote);
101 FI_HILOGD("Recv death notice");
102 }
103
SubscribeCallback(Type type,ActivityEvent event,ReportLatencyNs latency,sptr<IRemoteDevStaCallback> callback)104 int32_t DeviceStatusClient::SubscribeCallback(Type type, ActivityEvent event, ReportLatencyNs latency,
105 sptr<IRemoteDevStaCallback> callback)
106 {
107 FI_HILOGI("Enter event:%{public}d, latency:%{public}d", event, latency);
108 auto [_, ret] = typeMap_.insert(std::make_pair(type, 1));
109 if (!ret) {
110 FI_HILOGW("Insert pair to typeMap_ failed");
111 }
112 FI_HILOGD("typeMap_:%{public}d, type:%{public}d", typeMap_[type], type);
113 CHKPR(callback, RET_ERR);
114
115 if (Connect() != RET_OK) {
116 FI_HILOGE("Connect failed");
117 return RET_ERR;
118 }
119 CHKPR(devicestatusProxy_, RET_ERR);
120
121 if (type > Type::TYPE_INVALID && type <= Type::TYPE_LID_OPEN) {
122 devicestatusProxy_->Subscribe(type, event, latency, callback);
123 }
124 return RET_OK;
125 }
126
UnsubscribeCallback(Type type,ActivityEvent event,sptr<IRemoteDevStaCallback> callback)127 int32_t DeviceStatusClient::UnsubscribeCallback(Type type, ActivityEvent event, sptr<IRemoteDevStaCallback> callback)
128 {
129 CALL_DEBUG_ENTER;
130 FI_HILOGI("UNevent:%{public}d", event);
131 typeMap_.erase(type);
132 FI_HILOGD("typeMap_ %{public}d", typeMap_[type]);
133 CHKPR(callback, RET_ERR);
134
135 if (Connect() != RET_OK) {
136 FI_HILOGE("Connect failed");
137 return RET_ERR;
138 }
139 CHKPR(devicestatusProxy_, RET_ERR);
140
141 if ((type < TYPE_INVALID) || (type > TYPE_MAX)) {
142 FI_HILOGE("type out of range");
143 return RET_ERR;
144 }
145 if (event < ActivityEvent::EVENT_INVALID || event > ActivityEvent::ENTER_EXIT) {
146 FI_HILOGE("event out of range");
147 return RET_ERR;
148 }
149 devicestatusProxy_->Unsubscribe(type, event, callback);
150 return RET_OK;
151 }
152
GetDeviceStatusData(Type type)153 Data DeviceStatusClient::GetDeviceStatusData(Type type)
154 {
155 CALL_DEBUG_ENTER;
156 Data devicestatusData;
157 devicestatusData.type = Type::TYPE_INVALID;
158 devicestatusData.value = OnChangedValue::VALUE_INVALID;
159 if (Connect() != RET_OK) {
160 FI_HILOGE("Connect failed");
161 return devicestatusData;
162 }
163 if (devicestatusProxy_ == nullptr) {
164 FI_HILOGE("devicestatusProxy_ is nullptr");
165 return devicestatusData;
166 }
167 if (type > Type::TYPE_INVALID
168 && type <= Type::TYPE_LID_OPEN) {
169 devicestatusData = devicestatusProxy_->GetCache(type);
170 }
171 return devicestatusData;
172 }
173
174 #ifdef OHOS_BUILD_ENABLE_RUST_IMPL
175
RegisterCoordinationListener()176 int32_t DeviceStatusClient::RegisterCoordinationListener()
177 {
178 CALL_DEBUG_ENTER;
179 return fusion_register_coordination_listener();
180 }
181
UnregisterCoordinationListener()182 int32_t DeviceStatusClient::UnregisterCoordinationListener()
183 {
184 CALL_DEBUG_ENTER;
185 return fusion_unregister_coordination_listener();
186 }
187
PrepareCoordination(int32_t userData)188 int32_t DeviceStatusClient::PrepareCoordination(int32_t userData)
189 {
190 CALL_DEBUG_ENTER;
191 return fusion_enable_coordination(userData);
192 }
193
UnprepareCoordination(int32_t userData)194 int32_t DeviceStatusClient::UnprepareCoordination(int32_t userData)
195 {
196 CALL_DEBUG_ENTER;
197 return fusion_disable_coordination(userData);
198 }
199
ActivateCoordination(int32_t userData,const std::string & remoteNetworkId,int32_t startDeviceId)200 int32_t DeviceStatusClient::ActivateCoordination(int32_t userData,
201 const std::string &remoteNetworkId, int32_t startDeviceId)
202 {
203 CALL_DEBUG_ENTER;
204 return fusion_start_coordination(userData, remoteNetworkId.c_str(), startDeviceId);
205 }
206
DeactivateCoordination(int32_t userData,bool isUnchained)207 int32_t DeviceStatusClient::DeactivateCoordination(int32_t userData, bool isUnchained)
208 {
209 CALL_DEBUG_ENTER;
210 return fusion_stop_coordination(userData, isUnchained);
211 }
212
GetCoordinationState(int32_t userData,const std::string & deviceId)213 int32_t DeviceStatusClient::GetCoordinationState(int32_t userData, const std::string &deviceId)
214 {
215 CALL_DEBUG_ENTER;
216 return fusion_get_coordination_state(userData, deviceId.c_str());
217 }
218
219 #else // OHOS_BUILD_ENABLE_RUST_IMPL
220
RegisterCoordinationListener()221 int32_t DeviceStatusClient::RegisterCoordinationListener()
222 {
223 CALL_DEBUG_ENTER;
224 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
225 return devicestatusProxy_->RegisterCoordinationListener();
226 }
227
UnregisterCoordinationListener()228 int32_t DeviceStatusClient::UnregisterCoordinationListener()
229 {
230 CALL_DEBUG_ENTER;
231 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
232 return devicestatusProxy_->UnregisterCoordinationListener();
233 }
234
PrepareCoordination(int32_t userData)235 int32_t DeviceStatusClient::PrepareCoordination(int32_t userData)
236 {
237 CALL_DEBUG_ENTER;
238 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
239 return devicestatusProxy_->PrepareCoordination(userData);
240 }
241
UnprepareCoordination(int32_t userData)242 int32_t DeviceStatusClient::UnprepareCoordination(int32_t userData)
243 {
244 CALL_DEBUG_ENTER;
245 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
246 return devicestatusProxy_->UnprepareCoordination(userData);
247 }
248
ActivateCoordination(int32_t userData,const std::string & remoteNetworkId,int32_t startDeviceId)249 int32_t DeviceStatusClient::ActivateCoordination(int32_t userData,
250 const std::string &remoteNetworkId, int32_t startDeviceId)
251 {
252 CALL_DEBUG_ENTER;
253 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
254 return devicestatusProxy_->ActivateCoordination(userData, remoteNetworkId, startDeviceId);
255 }
256
DeactivateCoordination(int32_t userData,bool isUnchained)257 int32_t DeviceStatusClient::DeactivateCoordination(int32_t userData, bool isUnchained)
258 {
259 CALL_DEBUG_ENTER;
260 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
261 return devicestatusProxy_->DeactivateCoordination(userData, isUnchained);
262 }
263
GetCoordinationState(int32_t userData,const std::string & deviceId)264 int32_t DeviceStatusClient::GetCoordinationState(int32_t userData, const std::string &deviceId)
265 {
266 CALL_DEBUG_ENTER;
267 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
268 return devicestatusProxy_->GetCoordinationState(userData, deviceId);
269 }
270
271 #endif // OHOS_BUILD_ENABLE_RUST_IMPL
272
UpdateDragStyle(DragCursorStyle style)273 int32_t DeviceStatusClient::UpdateDragStyle(DragCursorStyle style)
274 {
275 CALL_DEBUG_ENTER;
276 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
277 return devicestatusProxy_->UpdateDragStyle(style);
278 }
279
GetDragTargetPid()280 int32_t DeviceStatusClient::GetDragTargetPid()
281 {
282 CALL_DEBUG_ENTER;
283 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
284 return devicestatusProxy_->GetDragTargetPid();
285 }
286
GetUdKey(std::string & udKey)287 int32_t DeviceStatusClient::GetUdKey(std::string &udKey)
288 {
289 CALL_DEBUG_ENTER;
290 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
291 return devicestatusProxy_->GetUdKey(udKey);
292 }
293
294 #ifdef OHOS_BUILD_ENABLE_RUST_IMPL
295
AllocSocketPair(int32_t moduleType)296 int32_t DeviceStatusClient::AllocSocketPair(int32_t moduleType)
297 {
298 const std::string programName(GetProgramName());
299 int32_t ret = fusion_alloc_socket_fd(programName.c_str(), moduleType, &socketFd_, &tokenType_);
300 if (ret != RET_OK) {
301 FI_HILOGE("Fail to connect to server via socket:%{public}d", ret);
302 return RET_ERR;
303 }
304 FI_HILOGI("Connected successfully to server via socket, "
305 "socketFd_:%{public}d tokenType_:%{public}d",
306 socketFd_, tokenType_);
307 return RET_OK;
308 }
309
310 #else // OHOS_BUILD_ENABLE_RUST_IMPL
311
AllocSocketPair(int32_t moduleType)312 int32_t DeviceStatusClient::AllocSocketPair(int32_t moduleType)
313 {
314 CALL_DEBUG_ENTER;
315 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
316 std::lock_guard<std::mutex> guard(mutex_);
317 CHKPR(devicestatusProxy_, RET_ERR);
318 const std::string programName(GetProgramName());
319 int32_t result = devicestatusProxy_->AllocSocketFd(programName, moduleType, socketFd_, tokenType_);
320 if (result != RET_OK) {
321 FI_HILOGE("AllocSocketFd has error:%{public}d", result);
322 return RET_ERR;
323 }
324
325 FI_HILOGI("AllocSocketPair success, socketFd_:%{public}d, tokenType_:%{public}d", socketFd_, tokenType_);
326 return RET_OK;
327 }
328
329 #endif // OHOS_BUILD_ENABLE_RUST_IMPL
330
GetClientSocketFdOfAllocedSocketPair() const331 int32_t DeviceStatusClient::GetClientSocketFdOfAllocedSocketPair() const
332 {
333 CALL_DEBUG_ENTER;
334 return socketFd_;
335 }
336
RegisterDeathListener(std::function<void ()> deathListener)337 void DeviceStatusClient::RegisterDeathListener(std::function<void()> deathListener)
338 {
339 deathListener_ = deathListener;
340 }
341
342 #ifdef OHOS_BUILD_ENABLE_RUST_IMPL
343
StartDrag(const DragData & dragData)344 int32_t DeviceStatusClient::StartDrag(const DragData &dragData)
345 {
346 CALL_DEBUG_ENTER;
347 CDragData cDragData;
348 if (CDragDataFrom(&dragData, &cDragData) != RET_OK) {
349 FI_HILOGE("Conversion of DragData to CDragData failed");
350 return RET_ERR;
351 }
352 int32_t ret = fusion_start_drag(&cDragData);
353 CDragDataFree(&cDragData);
354 return ret;
355 }
356
357 #else // OHOS_BUILD_ENABLE_RUST_IMPL
358
StartDrag(const DragData & dragData)359 int32_t DeviceStatusClient::StartDrag(const DragData &dragData)
360 {
361 CALL_DEBUG_ENTER;
362 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
363 CHKPR(devicestatusProxy_, RET_ERR);
364 return devicestatusProxy_->StartDrag(dragData);
365 }
366
367 #endif // OHOS_BUILD_ENABLE_RUST_IMPL
368
StopDrag(DragResult result,bool hasCustomAnimation)369 int32_t DeviceStatusClient::StopDrag(DragResult result, bool hasCustomAnimation)
370 {
371 CALL_DEBUG_ENTER;
372 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
373 CHKPR(devicestatusProxy_, RET_ERR);
374 return devicestatusProxy_->StopDrag(result, hasCustomAnimation);
375 }
376
AddDraglistener()377 int32_t DeviceStatusClient::AddDraglistener()
378 {
379 CALL_DEBUG_ENTER;
380 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
381 return devicestatusProxy_->AddDraglistener();
382 }
383
RemoveDraglistener()384 int32_t DeviceStatusClient::RemoveDraglistener()
385 {
386 CALL_DEBUG_ENTER;
387 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
388 return devicestatusProxy_->RemoveDraglistener();
389 }
390
SetDragWindowVisible(bool visible)391 int32_t DeviceStatusClient::SetDragWindowVisible(bool visible)
392 {
393 CALL_DEBUG_ENTER;
394 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
395 return devicestatusProxy_->SetDragWindowVisible(visible);
396 }
397
GetShadowOffset(int32_t & offsetX,int32_t & offsetY,int32_t & width,int32_t & height)398 int32_t DeviceStatusClient::GetShadowOffset(int32_t& offsetX, int32_t& offsetY, int32_t& width, int32_t& height)
399 {
400 CALL_DEBUG_ENTER;
401 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
402 return devicestatusProxy_->GetShadowOffset(offsetX, offsetY, width, height);
403 }
404
UpdateShadowPic(const ShadowInfo & shadowInfo)405 int32_t DeviceStatusClient::UpdateShadowPic(const ShadowInfo &shadowInfo)
406 {
407 CALL_DEBUG_ENTER;
408 DEV_RET_IF_NULL_WITH_RET((Connect() != RET_OK), RET_ERR);
409 return devicestatusProxy_->UpdateShadowPic(shadowInfo);
410 }
411 } // namespace DeviceStatus
412 } // namespace Msdp
413 } // namespace OHOS
414