1 /*
2 * Copyright (c) 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 "fusion_device_profile.h"
17
18 #include <sstream>
19
20 #include "distributed_device_profile_client.h"
21
22 #include "devicestatus_define.h"
23
24 using namespace OHOS::DeviceProfile;
25
26 #undef LOG_TAG
27 #define LOG_TAG "FusionDeviceProfile"
28
29 namespace {
30 const std::string SERVICE_ID { "deviceStatus" };
31 } // namespace
32
33 class ProfileEventCallbackImpl final : public IProfileEventCallback {
34 public:
35 explicit ProfileEventCallbackImpl(CIProfileEventCb* eventCb);
36 ~ProfileEventCallbackImpl();
37
38 void OnProfileChanged(const ProfileChangeNotification &changeNotification) override;
39
40 private:
41 CIProfileEventCb* eventCb_ { nullptr };
42 };
43
ProfileEventCallbackImpl(CIProfileEventCb * eventCb)44 ProfileEventCallbackImpl::ProfileEventCallbackImpl(CIProfileEventCb* eventCb)
45 {
46 if ((eventCb != nullptr) && (eventCb->clone != nullptr)) {
47 eventCb_ = eventCb->clone(eventCb);
48 }
49 }
50
~ProfileEventCallbackImpl()51 ProfileEventCallbackImpl::~ProfileEventCallbackImpl()
52 {
53 if (eventCb_ != nullptr && eventCb_->destruct != nullptr) {
54 eventCb_->destruct(eventCb_);
55 }
56 }
57
OnProfileChanged(const ProfileChangeNotification & changeNotification)58 void ProfileEventCallbackImpl::OnProfileChanged(const ProfileChangeNotification &changeNotification)
59 {
60 CALL_INFO_TRACE;
61 }
62
Destruct(CIProfileEvents * target)63 static void Destruct(CIProfileEvents* target)
64 {
65 CHKPV(target);
66 if (target->profileEvents == nullptr) {
67 delete target;
68 } else {
69 delete [] target->profileEvents;
70 delete target;
71 }
72 }
73
PutDeviceProfile(const CServiceCharacteristicProfile * profile)74 int32_t PutDeviceProfile(const CServiceCharacteristicProfile* profile)
75 {
76 CALL_DEBUG_ENTER;
77 return RET_ERR;
78 }
79
GetDeviceProfile(const char * udId,const char * serviceId,CServiceCharacteristicProfile * profile)80 int32_t GetDeviceProfile(const char* udId, const char* serviceId, CServiceCharacteristicProfile* profile)
81 {
82 CALL_DEBUG_ENTER;
83 return RET_ERR;
84 }
85
SubscribeProfileEvents(const CISubscribeInfos * subscribeInfos,CIProfileEventCb * eventCb,CIProfileEvents ** failedEvents)86 int32_t SubscribeProfileEvents(const CISubscribeInfos* subscribeInfos,
87 CIProfileEventCb* eventCb,
88 CIProfileEvents** failedEvents)
89 {
90 CALL_DEBUG_ENTER;
91 CHKPR(subscribeInfos, RET_ERR);
92 CHKPR(subscribeInfos->subscribeInfos, RET_ERR);
93 std::list<SubscribeInfo> subscriptions;
94
95 for (size_t index = 0; index < subscribeInfos->nSubscribeInfos; ++index) {
96 const CSubscribeInfo &cSub = subscribeInfos->subscribeInfos[index];
97
98 if ((cSub.profileEvent >= ProfileEvent::EVENT_UNKNOWN) &&
99 (cSub.profileEvent < ProfileEvent::EVENT_PROFILE_END)) {
100 CHKPC(cSub.extraInfo);
101 SubscribeInfo subscription;
102 subscription.profileEvent = static_cast<ProfileEvent>(cSub.profileEvent);
103 subscription.extraInfo = nlohmann::json::parse(cSub.extraInfo, nullptr, false);
104 subscriptions.push_back(subscription);
105 }
106 }
107
108 auto callback = std::make_shared<ProfileEventCallbackImpl>(eventCb);
109 std::list<ProfileEvent> fails;
110
111 int32_t ret = DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvents(
112 subscriptions, callback, fails);
113
114 if (!fails.empty()) {
115 CIProfileEvents* events = new (std::nothrow) CIProfileEvents;
116 CHKPR(events, RET_ERR);
117 events->numOfProfileEvents = fails.size();
118 events->profileEvents = new (std::nothrow) uint32_t[fails.size()];
119 if (events->profileEvents == nullptr) {
120 delete events;
121 FI_HILOGE("Failed to allocate memory for profileEvents");
122 return RET_ERR;
123 }
124 events->clone = nullptr;
125 events->destruct = &Destruct;
126
127 size_t index = 0;
128 for (const auto &profile_event: fails) {
129 events->profileEvents[index++] = profile_event;
130 }
131 *failedEvents = events;
132 events->destruct(events);
133 } else {
134 *failedEvents = nullptr;
135 }
136 return ret;
137 }
138
UnsubscribeProfileEvents(const CIProfileEvents * profileEvents,CIProfileEventCb * eventCb,CIProfileEvents ** failedEvents)139 int32_t UnsubscribeProfileEvents(const CIProfileEvents* profileEvents,
140 CIProfileEventCb* eventCb,
141 CIProfileEvents** failedEvents)
142 {
143 CALL_DEBUG_ENTER;
144 CHKPR(profileEvents, RET_ERR);
145 std::list<ProfileEvent> profiles;
146
147 for (size_t index = 0; index < profileEvents->numOfProfileEvents; ++index) {
148 uint32_t cPro = profileEvents->profileEvents[index];
149 if ((cPro >= static_cast<uint32_t>(ProfileEvent::EVENT_UNKNOWN)) &&
150 (cPro < static_cast<uint32_t>(ProfileEvent::EVENT_PROFILE_END))) {
151 ProfileEvent profile = static_cast<ProfileEvent>(cPro);
152 profiles.push_back(profile);
153 }
154 }
155
156 auto callback = std::make_shared<ProfileEventCallbackImpl>(eventCb);
157 std::list<ProfileEvent> fails;
158
159 int32_t ret = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(
160 profiles, callback, fails);
161
162 if (!fails.empty()) {
163 CIProfileEvents* events = new (std::nothrow) CIProfileEvents;
164 CHKPR(events, RET_ERR);
165 events->numOfProfileEvents = fails.size();
166 events->profileEvents = new (std::nothrow) uint32_t[fails.size()];
167 if (events->profileEvents == nullptr) {
168 delete events;
169 FI_HILOGE("Failed to allocate memory for profileEvents");
170 return RET_ERR;
171 }
172 events->clone = nullptr;
173 events->destruct = &Destruct;
174
175 size_t index = 0;
176 for (const auto &profile_event: fails) {
177 events->profileEvents[index++] = profile_event;
178 }
179 *failedEvents = events;
180 events->destruct(events);
181 } else {
182 *failedEvents = nullptr;
183 }
184 return ret;
185 }
186
187