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 "device_profile_client.h"
17
18 #include <chrono>
19
20 #include "distributed_device_profile_errors.h"
21 #include "distributed_device_profile_proxy.h"
22 #include "iservice_registry.h"
23 #include "pasteboard_hilog.h"
24 #include "system_ability_definition.h"
25
26 namespace OHOS {
27 namespace DistributedDeviceProfile {
28 using namespace OHOS::MiscServices;
29
30 constexpr int32_t LOAD_SA_TIMEOUT_MS = 10000;
31
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)32 void DeviceProfileLoadCb::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
33 {
34 DeviceProfileClient::GetInstance().LoadSystemAbilitySuccess(remoteObject);
35 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "on load system ability success");
36 }
37
OnLoadSystemAbilityFail(int32_t systemAbilityId)38 void DeviceProfileLoadCb::OnLoadSystemAbilityFail(int32_t systemAbilityId)
39 {
40 DeviceProfileClient::GetInstance().LoadSystemAbilityFail();
41 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "on load system ability failed");
42 }
43
GetInstance()44 DeviceProfileClient &DeviceProfileClient::GetInstance()
45 {
46 static DeviceProfileClient instance;
47 return instance;
48 }
49
GetDeviceProfileService()50 sptr<IDistributedDeviceProfile> DeviceProfileClient::GetDeviceProfileService()
51 {
52 {
53 std::lock_guard lock(serviceLock_);
54 if (dpProxy_ != nullptr) {
55 return dpProxy_;
56 }
57
58 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
59 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(samgr != nullptr, nullptr, PASTEBOARD_MODULE_COMMON,
60 "get samgr failed");
61
62 auto object = samgr->CheckSystemAbility(DISTRIBUTED_DEVICE_PROFILE_SA_ID);
63 if (object != nullptr) {
64 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "get dp service success");
65 dpProxy_ = new DistributedDeviceProfileProxy(object);
66 return dpProxy_;
67 }
68 }
69
70 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_COMMON, "remoteObject is null");
71 bool loadSucc = LoadDeviceProfileService();
72 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(loadSucc, nullptr, PASTEBOARD_MODULE_COMMON,
73 "load dp service failed");
74
75 std::lock_guard lock(serviceLock_);
76 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dpProxy_ != nullptr, nullptr, PASTEBOARD_MODULE_COMMON,
77 "load dp service failed");
78 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "load dp service success");
79 return dpProxy_;
80 }
81
LoadDeviceProfileService()82 sptr<IDistributedDeviceProfile> DeviceProfileClient::LoadDeviceProfileService()
83 {
84 sptr<DeviceProfileLoadCb> loadCallback = sptr<DeviceProfileLoadCb>::MakeSptr();
85 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(loadCallback != nullptr, nullptr, PASTEBOARD_MODULE_COMMON,
86 "loadCallback is null");
87
88 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
89 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(samgr != nullptr, nullptr, PASTEBOARD_MODULE_COMMON,
90 "get samgr failed");
91
92 int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_DEVICE_PROFILE_SA_ID, loadCallback);
93 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == ERR_OK, nullptr, PASTEBOARD_MODULE_COMMON,
94 "load dp service failed, ret=%{public}d", ret);
95
96 std::unique_lock lock(serviceLock_);
97 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(LOAD_SA_TIMEOUT_MS),
98 [this]() { return dpProxy_ != nullptr; });
99 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(waitStatus && dpProxy_ != nullptr, nullptr, PASTEBOARD_MODULE_COMMON,
100 "load dp service timeout");
101
102 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "load dp service success");
103 return dpProxy_;
104 }
105
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)106 void DeviceProfileClient::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
107 {
108 PASTEBOARD_CHECK_AND_RETURN_LOGE(remoteObject != nullptr, PASTEBOARD_MODULE_COMMON, "remoteObject is null");
109
110 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "enter");
111 std::lock_guard lock(serviceLock_);
112 dpProxy_ = new DistributedDeviceProfileProxy(remoteObject);
113 proxyConVar_.notify_one();
114 }
115
LoadSystemAbilityFail()116 void DeviceProfileClient::LoadSystemAbilityFail()
117 {
118 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "enter");
119 std::lock_guard lock(serviceLock_);
120 dpProxy_ = nullptr;
121 proxyConVar_.notify_one();
122 }
123
ClearDeviceProfileService()124 void DeviceProfileClient::ClearDeviceProfileService()
125 {
126 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "enter");
127 std::lock_guard lock(serviceLock_);
128 dpProxy_ = nullptr;
129 }
130
SendSubscribeInfos()131 void DeviceProfileClient::SendSubscribeInfos()
132 {
133 auto dpService = GetDeviceProfileService();
134 PASTEBOARD_CHECK_AND_RETURN_LOGE(dpService != nullptr, PASTEBOARD_MODULE_COMMON, "get dp service failed");
135 std::lock_guard lock(subscribeLock_);
136 PASTEBOARD_CHECK_AND_RETURN_LOGI(!subscribeInfos_.empty(), PASTEBOARD_MODULE_COMMON, "no subscribe info");
137 dpService->SendSubscribeInfos(subscribeInfos_);
138 }
139
PutCharacteristicProfile(const CharacteristicProfile & characteristicProfile)140 int32_t DeviceProfileClient::PutCharacteristicProfile(const CharacteristicProfile &characteristicProfile)
141 {
142 auto dpService = GetDeviceProfileService();
143 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dpService != nullptr, DP_GET_SERVICE_FAILED, PASTEBOARD_MODULE_COMMON,
144 "get dp service failed");
145 return dpService->PutCharacteristicProfile(characteristicProfile);
146 }
147
GetCharacteristicProfile(const std::string & deviceId,const std::string & serviceName,const std::string & characteristicId,CharacteristicProfile & characteristicProfile)148 int32_t DeviceProfileClient::GetCharacteristicProfile(const std::string &deviceId, const std::string &serviceName,
149 const std::string &characteristicId, CharacteristicProfile &characteristicProfile)
150 {
151 auto dpService = GetDeviceProfileService();
152 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dpService != nullptr, DP_GET_SERVICE_FAILED, PASTEBOARD_MODULE_COMMON,
153 "get dp service failed");
154 return dpService->GetCharacteristicProfile(deviceId, serviceName, characteristicId, characteristicProfile);
155 }
156
SubscribeDeviceProfile(const SubscribeInfo & subscribeInfo)157 int32_t DeviceProfileClient::SubscribeDeviceProfile(const SubscribeInfo &subscribeInfo)
158 {
159 auto dpService = GetDeviceProfileService();
160 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dpService != nullptr, DP_GET_SERVICE_FAILED, PASTEBOARD_MODULE_COMMON,
161 "get dp service failed");
162 {
163 std::lock_guard lock(subscribeLock_);
164 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(subscribeInfos_.size() < MAX_SUBSCRIBE_INFO_SIZE,
165 DP_EXCEED_MAX_SIZE_FAIL, PASTEBOARD_MODULE_COMMON,
166 "subscribe info size=%{public}zu", subscribeInfos_.size());
167
168 std::string subscribeTag =
169 subscribeInfo.GetSubscribeKey() + SEPARATOR + std::to_string(subscribeInfo.GetSaId());
170 subscribeInfos_[subscribeTag] = subscribeInfo;
171 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "subscribe info size=%{public}zu", subscribeInfos_.size());
172 }
173 return dpService->SubscribeDeviceProfile(subscribeInfo);
174 }
175
UnSubscribeDeviceProfile(const SubscribeInfo & subscribeInfo)176 int32_t DeviceProfileClient::UnSubscribeDeviceProfile(const SubscribeInfo &subscribeInfo)
177 {
178 auto dpService = GetDeviceProfileService();
179 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dpService != nullptr, DP_GET_SERVICE_FAILED, PASTEBOARD_MODULE_COMMON,
180 "get dp service failed");
181 {
182 std::lock_guard lock(subscribeLock_);
183 std::string subscribeTag =
184 subscribeInfo.GetSubscribeKey() + SEPARATOR + std::to_string(subscribeInfo.GetSaId());
185 subscribeInfos_.erase(subscribeTag);
186 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "subscribe info size=%{public}zu", subscribeInfos_.size());
187 }
188 return dpService->UnSubscribeDeviceProfile(subscribeInfo);
189 }
190 } // namespace DistributedDeviceProfile
191 } // namespace OHOS
192