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_networking_collect.h"
17
18 #include "sam_log.h"
19 #include "sa_profiles.h"
20 #include "system_ability_manager.h"
21
22 using namespace std;
23
24 using namespace OHOS::DistributedHardware;
25
26 namespace OHOS {
27 namespace {
28 const std::string PKG_NAME = "Samgr_Networking";
29 const std::string SA_TAG_DEVICE_ON_LINE = "deviceonline";
30 constexpr uint32_t INIT_EVENT = 10;
31 constexpr uint32_t DM_DIED_EVENT = 11;
32 constexpr uint64_t DELAY_TIME = 1000;
33 constexpr int32_t DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID = 4802;
34 }
DeviceNetworkingCollect(const sptr<IReport> & report)35 DeviceNetworkingCollect::DeviceNetworkingCollect(const sptr<IReport>& report)
36 : ICollectPlugin(report)
37 {
38 }
39
CleanFfrt()40 void DeviceNetworkingCollect::CleanFfrt()
41 {
42 if (workHandler_ != nullptr) {
43 workHandler_->CleanFfrt();
44 }
45 }
46
SetFfrt()47 void DeviceNetworkingCollect::SetFfrt()
48 {
49 if (workHandler_ != nullptr) {
50 workHandler_->SetFfrt();
51 }
52 }
53
OnStart()54 int32_t DeviceNetworkingCollect::OnStart()
55 {
56 HILOGI("DeviceNetworkingCollect OnStart called");
57 workHandler_ = std::make_shared<WorkHandler>(this);
58 initCallback_ = std::make_shared<DeviceInitCallBack>(workHandler_);
59 stateCallback_ = std::make_shared<DeviceStateCallback>(this);
60 workHandler_->SendEvent(INIT_EVENT);
61 return ERR_OK;
62 }
63
OnStop()64 int32_t DeviceNetworkingCollect::OnStop()
65 {
66 DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
67 if (workHandler_ != nullptr) {
68 workHandler_ = nullptr;
69 }
70 initCallback_ = nullptr;
71 ClearDeviceOnlineSet();
72 stateCallback_ = nullptr;
73 return ERR_OK;
74 }
75
IsDmReady()76 bool DeviceNetworkingCollect::IsDmReady()
77 {
78 auto dmProxy = SystemAbilityManager::GetInstance()->CheckSystemAbility(
79 DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
80 if (dmProxy != nullptr) {
81 IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(dmProxy.GetRefPtr());
82 // make sure the proxy is not dead
83 if (proxy != nullptr && !proxy->IsObjectDead()) {
84 return true;
85 }
86 }
87 return false;
88 }
89
ReportMissedEvents()90 bool DeviceNetworkingCollect::ReportMissedEvents()
91 {
92 std::vector<DmDeviceInfo> devList;
93 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", devList);
94 if (ret != ERR_OK) {
95 HILOGE("DeviceNetworkingCollect GetTrustedDeviceList error");
96 return false;
97 }
98 bool isPreviousOnline = IsOnline();
99 if (isPreviousOnline) {
100 ClearDeviceOnlineSet();
101 if (devList.empty()) {
102 // send offline msg
103 OnDemandEvent event = { DEVICE_ONLINE, SA_TAG_DEVICE_ON_LINE, "off" };
104 ReportEvent(event);
105 } else {
106 // update the online set;
107 for (DmDeviceInfo& devInfo : devList) {
108 UpdateDeviceOnlineSet(devInfo.networkId);
109 }
110 }
111 } else {
112 // offline --> online
113 if (!devList.empty()) {
114 // update the online set;
115 for (DmDeviceInfo& devInfo : devList) {
116 UpdateDeviceOnlineSet(devInfo.networkId);
117 }
118 // send online msg
119 OnDemandEvent event = { DEVICE_ONLINE, SA_TAG_DEVICE_ON_LINE, "on" };
120 ReportEvent(event);
121 }
122 }
123 return true;
124 }
125
AddDeviceChangeListener()126 bool DeviceNetworkingCollect::AddDeviceChangeListener()
127 {
128 HILOGI("DeviceNetworkingCollect AddDeviceChangeListener called");
129 if (IsDmReady()) {
130 int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback_);
131 if (ret != ERR_OK) {
132 HILOGE("DeviceNetworkingCollect InitDeviceManager error");
133 return false;
134 }
135 if (!ReportMissedEvents()) {
136 HILOGE("DeviceNetworkingCollect ReportMissedEvents error");
137 return false;
138 }
139 ret = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback_);
140 if (ret != ERR_OK) {
141 DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
142 HILOGE("DeviceNetworkingCollect RegisterDevStateCallback error");
143 return false;
144 }
145 return true;
146 }
147 return false;
148 }
149
UpdateDeviceOnlineSet(const std::string & deviceId)150 void DeviceNetworkingCollect::UpdateDeviceOnlineSet(const std::string& deviceId)
151 {
152 if (stateCallback_ != nullptr) {
153 stateCallback_->UpdateDeviceOnlineSet(deviceId);
154 }
155 }
156
ClearDeviceOnlineSet()157 void DeviceNetworkingCollect::ClearDeviceOnlineSet()
158 {
159 if (stateCallback_ != nullptr) {
160 stateCallback_->ClearDeviceOnlineSet();
161 }
162 }
163
CheckCondition(const OnDemandCondition & condition)164 bool DeviceNetworkingCollect::CheckCondition(const OnDemandCondition& condition)
165 {
166 bool isOnline = IsOnline();
167 if (condition.value == "on" && isOnline) {
168 return true;
169 }
170 if (condition.value == "off" && !isOnline) {
171 return true;
172 }
173 return false;
174 }
175
IsOnline()176 bool DeviceNetworkingCollect::IsOnline()
177 {
178 if (stateCallback_ != nullptr) {
179 return stateCallback_->IsOnline();
180 }
181 return false;
182 }
183
OnRemoteDied()184 void DeviceInitCallBack::OnRemoteDied()
185 {
186 HILOGI("DeviceNetworkingCollect DeviceInitCallBack OnRemoteDied");
187 if (handler_ != nullptr) {
188 handler_->SendEvent(DM_DIED_EVENT, DELAY_TIME);
189 }
190 }
191
OnDeviceOnline(const DmDeviceInfo & deviceInfo)192 void DeviceStateCallback::OnDeviceOnline(const DmDeviceInfo& deviceInfo)
193 {
194 HILOGI("DeviceNetworkingCollect DeviceStateCallback OnDeviceOnline");
195 bool isOnline = false;
196 {
197 lock_guard<mutex> autoLock(deviceOnlineLock_);
198 isOnline = deviceOnlineSet_.empty();
199 deviceOnlineSet_.emplace(deviceInfo.networkId);
200 }
201 if (isOnline) {
202 OnDemandEvent event = { DEVICE_ONLINE, SA_TAG_DEVICE_ON_LINE, "on" };
203 if (collect_ != nullptr) {
204 collect_->ReportEvent(event);
205 }
206 }
207 }
208
OnDeviceOffline(const DmDeviceInfo & deviceInfo)209 void DeviceStateCallback::OnDeviceOffline(const DmDeviceInfo& deviceInfo)
210 {
211 HILOGI("DeviceNetworkingCollect DeviceStateCallback OnDeviceOffline");
212 bool isOffline = false;
213 {
214 lock_guard<mutex> autoLock(deviceOnlineLock_);
215 deviceOnlineSet_.erase(deviceInfo.networkId);
216 isOffline = deviceOnlineSet_.empty();
217 if (isOffline) {
218 isExistDeviceReady_ = false;
219 }
220 }
221 if (isOffline) {
222 OnDemandEvent event = { DEVICE_ONLINE, SA_TAG_DEVICE_ON_LINE, "off" };
223 if (collect_ != nullptr) {
224 collect_->ReportEvent(event);
225 }
226 }
227 }
228
ClearDeviceOnlineSet()229 void DeviceStateCallback::ClearDeviceOnlineSet()
230 {
231 lock_guard<mutex> autoLock(deviceOnlineLock_);
232 deviceOnlineSet_.clear();
233 }
234
IsOnline()235 bool DeviceStateCallback::IsOnline()
236 {
237 lock_guard<mutex> autoLock(deviceOnlineLock_);
238 return !deviceOnlineSet_.empty();
239 }
240
UpdateDeviceOnlineSet(const std::string & deviceId)241 void DeviceStateCallback::UpdateDeviceOnlineSet(const std::string& deviceId)
242 {
243 lock_guard<mutex> autoLock(deviceOnlineLock_);
244 deviceOnlineSet_.emplace(deviceId);
245 }
246
OnDeviceChanged(const DmDeviceInfo & deviceInfo)247 void DeviceStateCallback::OnDeviceChanged(const DmDeviceInfo& deviceInfo)
248 {
249 HILOGD("DeviceNetworkingCollect OnDeviceChanged called");
250 }
251
OnDeviceReady(const DmDeviceInfo & deviceInfo)252 void DeviceStateCallback::OnDeviceReady(const DmDeviceInfo& deviceInfo)
253 {
254 HILOGI("DeviceNetworkingCollect DeviceStateCallback OnDeviceReady");
255 lock_guard<mutex> autoLock(deviceOnlineLock_);
256 if (!isExistDeviceReady_) {
257 OnDemandEvent event = { DEVICE_ONLINE, SA_TAG_DEVICE_ON_LINE, "ready" };
258 if (collect_ != nullptr) {
259 collect_->ReportEvent(event);
260 }
261 isExistDeviceReady_ = true;
262 }
263 }
264
CleanFfrt()265 void WorkHandler::CleanFfrt()
266 {
267 if (handler_ != nullptr) {
268 handler_->CleanFfrt();
269 }
270 }
271
SetFfrt()272 void WorkHandler::SetFfrt()
273 {
274 if (handler_ != nullptr) {
275 handler_->SetFfrt("WorkHandler");
276 }
277 }
278
ProcessEvent(uint32_t eventId)279 void WorkHandler::ProcessEvent(uint32_t eventId)
280 {
281 if (collect_ == nullptr) {
282 HILOGE("DeviceNetworkingCollect ProcessEvent collect or event is null!");
283 return;
284 }
285 if (eventId != INIT_EVENT && eventId != DM_DIED_EVENT) {
286 HILOGE("DeviceNetworkingCollect ProcessEvent error event code!");
287 return;
288 }
289 if (handler_ == nullptr) {
290 HILOGE("DeviceNetworkingCollect SendEvent handler is null!");
291 return;
292 }
293 if (!collect_->AddDeviceChangeListener()) {
294 HILOGW("DeviceNetworkingCollect AddDeviceChangeListener retry");
295 auto task = std::bind(&WorkHandler::ProcessEvent, this, INIT_EVENT);
296 if (handler_ == nullptr) {
297 HILOGE("DeviceNetworkingCollect ProcessEvent handler is null!");
298 return;
299 }
300 handler_->PostTask(task, DELAY_TIME);
301 }
302 HILOGI("DeviceNetworkingCollect AddDeviceChangeListener success");
303 }
304
SendEvent(uint32_t eventId)305 bool WorkHandler::SendEvent(uint32_t eventId)
306 {
307 if (handler_ == nullptr) {
308 HILOGE("DeviceNetworkingCollect SendEvent handler is null!");
309 return false;
310 }
311 auto task = std::bind(&WorkHandler::ProcessEvent, this, eventId);
312 return handler_->PostTask(task);
313 }
314
SendEvent(uint32_t eventId,uint64_t delayTime)315 bool WorkHandler::SendEvent(uint32_t eventId, uint64_t delayTime)
316 {
317 if (handler_ == nullptr) {
318 HILOGE("DeviceNetworkingCollect SendEvent handler is null!");
319 return false;
320 }
321 auto task = std::bind(&WorkHandler::ProcessEvent, this, eventId);
322 return handler_->PostTask(task, delayTime);
323 }
324 } // namespace OHOS
325