• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_adapter.h"
17 
18 #include <algorithm>
19 #include <mutex>
20 
21 #include "distributed_device_profile_client.h"
22 #include "input_device_cooperate_util.h"
23 #include "service_characteristic_profile.h"
24 #include "sync_options.h"
25 
26 namespace OHOS {
27 namespace MMI {
28 using namespace OHOS::DeviceProfile;
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "DeviceProfileAdapter" };
31 const std::string SERVICE_ID = "InputDeviceCooperation";
32 const std::string SERVICE_TYPE = "InputDeviceCooperation";
33 const std::string CHARACTERISTICS_NAME = "CurrentState";
34 } // namespace
35 
DeviceProfileAdapter()36 DeviceProfileAdapter::DeviceProfileAdapter() {}
37 
~DeviceProfileAdapter()38 DeviceProfileAdapter::~DeviceProfileAdapter()
39 {
40     std::lock_guard<std::mutex> guard(adapterLock_);
41     profileEventCallbacks_.clear();
42     callbacks_.clear();
43 }
44 
UpdateCrossingSwitchState(bool state,const std::vector<std::string> & deviceIds)45 int32_t DeviceProfileAdapter::UpdateCrossingSwitchState(bool state, const std::vector<std::string> &deviceIds)
46 {
47     CALL_INFO_TRACE;
48     ServiceCharacteristicProfile profile;
49     profile.SetServiceId(SERVICE_ID);
50     profile.SetServiceType(SERVICE_TYPE);
51     cJSON *data = cJSON_CreateObject();
52     cJSON_AddItemToObject(data, CHARACTERISTICS_NAME.c_str(), cJSON_CreateBool(state));
53     char *smsg = cJSON_Print(data);
54     cJSON_Delete(data);
55     profile.SetCharacteristicProfileJson(smsg);
56     cJSON_free(smsg);
57 
58     int32_t ret = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
59     if (ret != 0) {
60         MMI_HILOGE("Put device profile failed, ret:%{public}d", ret);
61         return ret;
62     }
63     SyncOptions syncOptions;
64     std::for_each(deviceIds.begin(), deviceIds.end(),
65                   [&syncOptions](auto &deviceId) {
66                       syncOptions.AddDevice(deviceId);
67                       MMI_HILOGD("Add device success");
68                   });
69     auto syncCallback = std::make_shared<DeviceProfileAdapter::ProfileEventCallbackImpl>();
70     ret =
71         DistributedDeviceProfileClient::GetInstance().SyncDeviceProfile(syncOptions, syncCallback);
72     if (ret != 0) {
73         MMI_HILOGE("Sync device profile failed");
74     }
75     return ret;
76 }
77 
UpdateCrossingSwitchState(bool state)78 int32_t DeviceProfileAdapter::UpdateCrossingSwitchState(bool state)
79 {
80     CALL_INFO_TRACE;
81     ServiceCharacteristicProfile profile;
82     profile.SetServiceId(SERVICE_ID);
83     profile.SetServiceType(SERVICE_TYPE);
84     cJSON *data = cJSON_CreateObject();
85     cJSON_AddItemToObject(data, CHARACTERISTICS_NAME.c_str(), cJSON_CreateBool(state));
86     char *smsg = cJSON_Print(data);
87     cJSON_Delete(data);
88     profile.SetCharacteristicProfileJson(smsg);
89     cJSON_free(smsg);
90 
91     return DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
92 }
93 
GetCrossingSwitchState(const std::string & deviceId)94 bool DeviceProfileAdapter::GetCrossingSwitchState(const std::string &deviceId)
95 {
96     CALL_INFO_TRACE;
97     ServiceCharacteristicProfile profile;
98     DistributedDeviceProfileClient::GetInstance().GetDeviceProfile(deviceId, SERVICE_ID, profile);
99     std::string jsonData = profile.GetCharacteristicProfileJson();
100     JsonParser parser;
101     parser.json_ = cJSON_Parse(jsonData.c_str());
102     if (!cJSON_IsObject(parser.json_)) {
103         MMI_HILOGE("Parser.json_ is not object");
104         return false;
105     }
106     cJSON* state = cJSON_GetObjectItemCaseSensitive(parser.json_, CHARACTERISTICS_NAME.c_str());
107     if (!cJSON_IsBool(state)) {
108         MMI_HILOGE("State is not bool type");
109         return false;
110     }
111     return cJSON_IsTrue(state);
112 }
113 
RegisterCrossingStateListener(const std::string & deviceId,DPCallback callback)114 int32_t DeviceProfileAdapter::RegisterCrossingStateListener(const std::string &deviceId, DPCallback callback)
115 {
116     CHKPR(callback, RET_ERR);
117     if (deviceId.empty()) {
118         MMI_HILOGE("DeviceId is nullptr");
119         return RET_ERR;
120     }
121     std::lock_guard<std::mutex> guard(adapterLock_);
122     auto callbackIter = callbacks_.find(deviceId);
123     if (callbackIter != callbacks_.end()) {
124         callbackIter->second = callback;
125         MMI_HILOGW("Callback is updated");
126         return RET_OK;
127     }
128     callbacks_[deviceId] = callback;
129     MMI_HILOGI("Register crossing state listener success");
130     if (RegisterProfileListener(deviceId) != RET_OK) {
131         MMI_HILOGE("Register profile listener failed");
132         return RET_ERR;
133     }
134     return RET_OK;
135 }
136 
UnregisterCrossingStateListener(const std::string & deviceId)137 int32_t DeviceProfileAdapter::UnregisterCrossingStateListener(const std::string &deviceId)
138 {
139     CALL_INFO_TRACE;
140     if (deviceId.empty()) {
141         MMI_HILOGE("DeviceId is empty");
142         return RET_ERR;
143     }
144     std::lock_guard<std::mutex> guard(adapterLock_);
145     auto it = profileEventCallbacks_.find(deviceId);
146     if (it != profileEventCallbacks_.end()) {
147         std::list<ProfileEvent> profileEvents;
148         profileEvents.emplace_back(ProfileEvent::EVENT_PROFILE_CHANGED);
149         std::list<ProfileEvent> failedEvents;
150         DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(profileEvents,
151             it->second, failedEvents);
152         profileEventCallbacks_.erase(it);
153     }
154     auto callbackIter = callbacks_.find(deviceId);
155     if (callbackIter == callbacks_.end()) {
156         MMI_HILOGW("This device has no callback");
157         return RET_OK;
158     }
159     callbacks_.erase(callbackIter);
160     return RET_OK;
161 }
162 
RegisterProfileListener(const std::string & deviceId)163 int32_t DeviceProfileAdapter::RegisterProfileListener(const std::string &deviceId)
164 {
165     CALL_INFO_TRACE;
166     std::list<std::string> serviceIdList;
167     serviceIdList.emplace_back(SERVICE_ID);
168     ExtraInfo extraInfo;
169     extraInfo["deviceId"] = deviceId;
170     extraInfo["serviceIds"] = serviceIdList;
171     SubscribeInfo changeEventInfo;
172     changeEventInfo.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
173     changeEventInfo.extraInfo = std::move(extraInfo);
174     std::list<SubscribeInfo> subscribeInfos;
175     subscribeInfos.emplace_back(changeEventInfo);
176     SubscribeInfo syncEventInfo;
177     syncEventInfo.profileEvent = ProfileEvent::EVENT_SYNC_COMPLETED;
178     subscribeInfos.emplace_back(syncEventInfo);
179     std::list<ProfileEvent> failedEvents;
180     auto it = profileEventCallbacks_.find(deviceId);
181     if (it == profileEventCallbacks_.end() || it->second == nullptr) {
182         profileEventCallbacks_[deviceId] = std::make_shared<DeviceProfileAdapter::ProfileEventCallbackImpl>();
183     }
184     return DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvents(
185         subscribeInfos, profileEventCallbacks_[deviceId], failedEvents);
186 }
187 
OnProfileChanged(const std::string & deviceId)188 void DeviceProfileAdapter::OnProfileChanged(const std::string &deviceId)
189 {
190     std::lock_guard<std::mutex> guard(adapterLock_);
191     auto it = callbacks_.find(deviceId);
192     if (it == callbacks_.end()) {
193         MMI_HILOGW("The device has no callback");
194         return;
195     }
196     if (it->second != nullptr) {
197         auto state = GetCrossingSwitchState(deviceId);
198         it->second(deviceId, state);
199     } else {
200         callbacks_.erase(it);
201     }
202 }
203 
OnProfileChanged(const ProfileChangeNotification & changeNotification)204 void DeviceProfileAdapter::ProfileEventCallbackImpl::OnProfileChanged(
205     const ProfileChangeNotification &changeNotification)
206 {
207     CALL_INFO_TRACE;
208     std::string deviceId = changeNotification.GetDeviceId();
209     DProfileAdapter->OnProfileChanged(deviceId);
210 }
211 
OnSyncCompleted(const DeviceProfile::SyncResult & syncResults)212 void DeviceProfileAdapter::ProfileEventCallbackImpl::OnSyncCompleted(const DeviceProfile::SyncResult &syncResults)
213 {
214     std::for_each(syncResults.begin(), syncResults.end(), [](const auto &syncResult) {
215         MMI_HILOGD("Sync result:%{public}d", syncResult.second);
216     });
217 }
218 } // namespace MMI
219 } // namespace OHOS
220