1 /*
2  * Copyright (c) 2024 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 "mission/dms_continue_recv_manager.h"
17 
18 #include <sys/prctl.h>
19 
20 #include "datetime_ex.h"
21 
22 #include "datashare_manager.h"
23 #include "dfx/distributed_radar.h"
24 #include "dfx/distributed_ue.h"
25 #include "distributed_sched_utils.h"
26 #include "distributed_sched_adapter.h"
27 #include "dtbschedmgr_device_info_storage.h"
28 #include "dtbschedmgr_log.h"
29 #include "mission/dsched_sync_e2e.h"
30 #include "mission/wifi_state_adapter.h"
31 #include "parcel_helper.h"
32 #include "softbus_adapter/softbus_adapter.h"
33 #include "switch_status_dependency.h"
34 #include "os_account_manager.h"
35 
36 namespace OHOS {
37 namespace DistributedSchedule {
38 namespace {
39 constexpr int32_t ON_CALLBACK = 0;
40 constexpr int32_t ACTIVE = 0;
41 constexpr int32_t INACTIVE = 1;
42 constexpr int32_t INDEX_2 = 2;
43 constexpr int32_t INDEX_3 = 3;
44 constexpr int32_t DBMS_RETRY_MAX_TIME = 5;
45 constexpr int32_t DBMS_RETRY_DELAY = 2000;
46 const std::string TAG = "DMSContinueRecvMgr";
47 const std::string DBMS_RETRY_TASK = "retry_on_boradcast_task";
48 const std::u16string DESCRIPTOR = u"ohos.aafwk.RemoteOnListener";
49 }
50 
51 IMPLEMENT_SINGLE_INSTANCE(DMSContinueRecvMgr);
52 
Init()53 void DMSContinueRecvMgr::Init()
54 {
55     HILOGI("Init start");
56     if (eventHandler_ != nullptr) {
57         HILOGI("Already inited, end.");
58         return;
59     }
60     {
61         std::shared_ptr<SoftbusAdapterListener> missionBroadcastListener =
62             std::make_shared<DistributedMissionBroadcastListener>();
63         int32_t ret = SoftbusAdapter::GetInstance().RegisterSoftbusEventListener(missionBroadcastListener);
64         if (ret != ERR_OK) {
65             HILOGE("get RegisterSoftbusEventListener failed, ret: %{public}d", ret);
66             return;
67         }
68         hasRegSoftbusEventListener_ = true;
69         missionDiedListener_ = new DistributedMissionDiedListener();
70         eventThread_ = std::thread(&DMSContinueRecvMgr::StartEvent, this);
71         std::unique_lock<std::mutex> lock(eventMutex_);
72         eventCon_.wait(lock, [this] {
73             return eventHandler_ != nullptr;
74         });
75     }
76     HILOGI("Init end");
77 }
78 
UnInit()79 void DMSContinueRecvMgr::UnInit()
80 {
81     HILOGI("UnInit start");
82     if (eventHandler_ != nullptr && eventHandler_->GetEventRunner() != nullptr) {
83         eventHandler_->GetEventRunner()->Stop();
84         eventThread_.join();
85         eventHandler_ = nullptr;
86     } else {
87         HILOGE("eventHandler_ is nullptr");
88     }
89     HILOGI("UnInit end");
90 }
91 
NotifyDataRecv(std::string & senderNetworkId,uint8_t * payload,uint32_t dataLen)92 void DMSContinueRecvMgr::NotifyDataRecv(std::string& senderNetworkId,
93     uint8_t* payload, uint32_t dataLen)
94 {
95     HILOGI("NotifyDataRecv start, senderNetworkId: %{public}s, dataLen: %{public}u.",
96         GetAnonymStr(senderNetworkId).c_str(), dataLen);
97     if (!DataShareManager::GetInstance().IsCurrentContinueSwitchOn()) {
98         HILOGE("ContinueSwitch status is off");
99         return;
100     }
101     if (!WifiStateAdapter::GetInstance().IsWifiActive()) {
102         HILOGE("wifi is not activated");
103         return;
104     }
105     if (dataLen < DMS_SEND_LEN) {
106         HILOGE("dataLen error, dataLen: %{public}u", dataLen);
107         return;
108     }
109     uint8_t type = (payload[0] & DMS_0XF0) >> CONTINUE_SHIFT_04;
110     uint8_t len = payload[0] & DMS_0X0F;
111     if (len < DMS_DATA_LEN || (type > DMS_0X0F)) {
112         HILOGE("len or type error, len: %{public}u, type: %{public}u", len, type);
113         return;
114     }
115     uint16_t bundleNameId = (payload[1] << CONTINUE_SHIFT_08) | payload[INDEX_2];
116     uint8_t continueTypeId = payload[INDEX_3];
117     HILOGI("bundleNameId: %{public}u, continueTypeId: %{public}u", bundleNameId, continueTypeId);
118     int32_t state = ACTIVE;
119     if (type == DMS_UNFOCUSED_TYPE) {
120         state = INACTIVE;
121     }
122     PostOnBroadcastBusiness(senderNetworkId, bundleNameId, continueTypeId, state);
123     HILOGI("NotifyDataRecv end");
124 }
125 
RegisterOnListener(const std::string & type,const sptr<IRemoteObject> & obj)126 int32_t DMSContinueRecvMgr::RegisterOnListener(const std::string& type, const sptr<IRemoteObject>& obj)
127 {
128     HILOGI("RegisterOnListener start, type: %{public}s", type.c_str());
129     if (obj == nullptr) {
130         HILOGE("obj is null, type: %{public}s", type.c_str());
131         return INVALID_PARAMETERS_ERR;
132     }
133     onType_ = type;
134     std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
135     auto iterItem = registerOnListener_.find(type);
136     if (iterItem == registerOnListener_.end()) {
137         HILOGD("The itemItem does not exist in the registerOnListener_, adding, type: %{public}s", type.c_str());
138         std::vector<sptr<IRemoteObject>> objs;
139         obj->AddDeathRecipient(missionDiedListener_);
140         objs.emplace_back(obj);
141         registerOnListener_[type] = objs;
142         HILOGI("RegisterOnListener end");
143         return ERR_OK;
144     }
145     for (auto iter : iterItem->second) {
146         if (iter == obj) {
147             HILOGI("already have obj");
148             return NO_MISSION_INFO_FOR_MISSION_ID;
149         }
150     }
151     obj->AddDeathRecipient(missionDiedListener_);
152     iterItem->second.emplace_back(obj);
153     HILOGI("RegisterOnListener end");
154     return ERR_OK;
155 }
156 
RegisterOffListener(const std::string & type,const sptr<IRemoteObject> & obj)157 int32_t DMSContinueRecvMgr::RegisterOffListener(const std::string& type,
158     const sptr<IRemoteObject>& obj)
159 {
160     HILOGI("RegisterOffListener start, type: %{public}s", type.c_str());
161     if (obj == nullptr) {
162         HILOGE("obj is null, type: %{public}s", type.c_str());
163         return INVALID_PARAMETERS_ERR;
164     }
165     for (auto iterItem = registerOnListener_.begin(); iterItem != registerOnListener_.end();) {
166         for (auto iter = iterItem->second.begin(); iter != iterItem->second.end();) {
167             if (*iter == obj) {
168                 std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
169                 iter = iterItem->second.erase(iter);
170                 obj->RemoveDeathRecipient(missionDiedListener_);
171                 break;
172             } else {
173                 iter++;
174             }
175         }
176         if (iterItem->second.empty()) {
177             std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
178             iterItem = registerOnListener_.erase(iterItem);
179         } else {
180             iterItem++;
181         }
182     }
183     HILOGI("RegisterOffListener end");
184     return ERR_OK;
185 }
186 
StartEvent()187 void DMSContinueRecvMgr::StartEvent()
188 {
189     HILOGI("StartEvent start");
190     prctl(PR_SET_NAME, CONTINUE_RECV_MANAGER.c_str());
191     auto runner = AppExecFwk::EventRunner::Create(false);
192     {
193         std::lock_guard<std::mutex> lock(eventMutex_);
194         eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
195     }
196     eventCon_.notify_one();
197     if (runner != nullptr) {
198         runner->Run();
199     } else {
200         HILOGE("runner is null");
201     }
202     HILOGI("StartEvent end");
203 }
204 
VerifyBroadcastSource(const std::string & senderNetworkId,const std::string & srcBundleName,const std::string & sinkBundleName,const std::string & continueType,const int32_t state)205 int32_t DMSContinueRecvMgr::VerifyBroadcastSource(const std::string& senderNetworkId, const std::string& srcBundleName,
206     const std::string& sinkBundleName, const std::string& continueType, const int32_t state)
207 {
208     std::lock_guard<std::mutex> currentIconLock(iconMutex_);
209     if (state == ACTIVE) {
210         iconInfo_.senderNetworkId = senderNetworkId;
211         iconInfo_.bundleName = sinkBundleName;
212         iconInfo_.sourceBundleName = srcBundleName;
213         iconInfo_.continueType = continueType;
214     } else {
215         if (senderNetworkId != iconInfo_.senderNetworkId) {
216             HILOGW("Sender not match, task abort. senderNetworkId: %{public}s, saved NetworkId: %{public}s.",
217                 GetAnonymStr(senderNetworkId).c_str(), GetAnonymStr(iconInfo_.senderNetworkId).c_str());
218             return INVALID_PARAMETERS_ERR;
219         }
220 
221         if (sinkBundleName != iconInfo_.bundleName) {
222             HILOGW("BundleName not match, task abort. bundleName: %{public}s, saved bundleName: %{public}s",
223                 sinkBundleName.c_str(), iconInfo_.bundleName.c_str());
224             return INVALID_PARAMETERS_ERR;
225         }
226 
227         iconInfo_.senderNetworkId = "";
228         iconInfo_.bundleName = "";
229         iconInfo_.continueType = "";
230     }
231     return ERR_OK;
232 }
233 
PostOnBroadcastBusiness(const std::string & senderNetworkId,uint16_t bundleNameId,uint8_t continueTypeId,const int32_t state,const int32_t delay,const int32_t retry)234 void DMSContinueRecvMgr::PostOnBroadcastBusiness(const std::string& senderNetworkId,
235     uint16_t bundleNameId, uint8_t continueTypeId, const int32_t state, const int32_t delay, const int32_t retry)
236 {
237     auto feedfunc = [this, senderNetworkId, bundleNameId, continueTypeId, state, retry]() mutable {
238         DealOnBroadcastBusiness(senderNetworkId, bundleNameId, continueTypeId, state, retry);
239     };
240     if (eventHandler_ != nullptr) {
241         eventHandler_->RemoveTask(DBMS_RETRY_TASK);
242         eventHandler_->PostTask(feedfunc, DBMS_RETRY_TASK, delay);
243     } else {
244         HILOGE("eventHandler_ is nullptr");
245     }
246 }
247 
RetryPostBroadcast(const std::string & senderNetworkId,uint16_t bundleNameId,uint8_t continueTypeId,const int32_t state,const int32_t retry)248 int32_t DMSContinueRecvMgr::RetryPostBroadcast(const std::string& senderNetworkId,
249     uint16_t bundleNameId, uint8_t continueTypeId, const int32_t state, const int32_t retry)
250 {
251     HILOGI("Retry post broadcast, current retry times %{public}d", retry);
252     if (retry == DBMS_RETRY_MAX_TIME) {
253         HILOGE("meet max retry time!");
254         return INVALID_PARAMETERS_ERR;
255     }
256     PostOnBroadcastBusiness(senderNetworkId, bundleNameId, continueTypeId, state, DBMS_RETRY_DELAY, retry + 1);
257     return ERR_OK;
258 }
259 
GetFinalBundleName(DmsBundleInfo & distributedBundleInfo,std::string & finalBundleName,AppExecFwk::BundleInfo & localBundleInfo,std::string & continueType)260 bool DMSContinueRecvMgr::GetFinalBundleName(DmsBundleInfo &distributedBundleInfo, std::string &finalBundleName,
261     AppExecFwk::BundleInfo &localBundleInfo, std::string &continueType)
262 {
263     std::string bundleName = distributedBundleInfo.bundleName;
264     if (BundleManagerInternal::GetLocalBundleInfo(bundleName, localBundleInfo) == ERR_OK) {
265         finalBundleName = bundleName;
266         return true;
267     }
268     std::vector<std::string> bundleNameList;
269     bool continueBundleGot = BundleManagerInternal::GetContinueBundle4Src(bundleName, bundleNameList);
270     if (!continueBundleGot) {
271         HILOGE("can not get local bundle info or continue bundle for bundle name: %{public}s", bundleName.c_str());
272         return false;
273     }
274 
275     for (std::string &bundleNameItem: bundleNameList) {
276         HILOGI("find dst bundle name for diff bundle continue. src developer id: %{public}s; ",
277             GetAnonymStr(distributedBundleInfo.developerId).c_str());
278         AppExecFwk::AppProvisionInfo appProvisionInfo;
279         if (BundleManagerInternal::GetAppProvisionInfo4CurrentUser(bundleNameItem, appProvisionInfo)
280             && appProvisionInfo.developerId == distributedBundleInfo.developerId
281             && BundleManagerInternal::GetLocalBundleInfo(bundleNameItem, localBundleInfo) == ERR_OK) {
282             finalBundleName = bundleNameItem;
283             return true;
284         }
285     }
286     HILOGE("can not get local bundle info and continue nundle for "
287         "bundle name: %{public}s", bundleName.c_str());
288     return false;
289 }
290 
FindContinueType(const DmsBundleInfo & distributedBundleInfo,uint8_t & continueTypeId,std::string & continueType)291 void DMSContinueRecvMgr::FindContinueType(const DmsBundleInfo &distributedBundleInfo,
292     uint8_t &continueTypeId, std::string &continueType)
293 {
294     uint32_t pos = 0;
295     for (auto dmsAbilityInfo: distributedBundleInfo.dmsAbilityInfos) {
296         for (auto continueTypeElement: dmsAbilityInfo.continueType) {
297             if (pos == continueTypeId) {
298                 continueType = continueTypeElement;
299                 return;
300             }
301             ++pos;
302         }
303     }
304     continueType = "";
305 }
306 
DealOnBroadcastBusiness(const std::string & senderNetworkId,uint16_t bundleNameId,uint8_t continueTypeId,const int32_t state,const int32_t retry)307 int32_t DMSContinueRecvMgr::DealOnBroadcastBusiness(const std::string& senderNetworkId,
308     uint16_t bundleNameId, uint8_t continueTypeId, const int32_t state, const int32_t retry)
309 {
310     HILOGI("DealOnBroadcastBusiness start, senderNetworkId: %{public}s, bundleNameId: %{public}u, state: %{public}d.",
311         GetAnonymStr(senderNetworkId).c_str(), bundleNameId, state);
312     DmsBundleInfo distributedBundleInfo;
313     if (!DmsBmStorage::GetInstance()->GetDistributedBundleInfo(senderNetworkId, bundleNameId,
314         distributedBundleInfo)) {
315         HILOGW("get distributedBundleInfo failed, try = %{public}d", retry);
316         DmsKvSyncE2E::GetInstance()->PushAndPullData(senderNetworkId);
317         return RetryPostBroadcast(senderNetworkId, bundleNameId, continueTypeId, state, retry);
318     }
319 
320     std::string bundleName = distributedBundleInfo.bundleName;
321 
322     HILOGI("get distributedBundleInfo success, bundleName: %{public}s", bundleName.c_str());
323     std::string finalBundleName;
324     if (!CheckBundleContinueConfig(bundleName)) {
325         HILOGI("App does not allow continue in config file, bundle name %{public}s", bundleName.c_str());
326         return REMOTE_DEVICE_BIND_ABILITY_ERR;
327     }
328 
329     AppExecFwk::BundleInfo localBundleInfo;
330     std::string continueType;
331     FindContinueType(distributedBundleInfo, continueTypeId, continueType);
332     if (!GetFinalBundleName(distributedBundleInfo, finalBundleName, localBundleInfo, continueType)) {
333         HILOGE("The app is not installed on the local device.");
334         return INVALID_PARAMETERS_ERR;
335     }
336     HILOGI("got finalBundleName: %{public}s", finalBundleName.c_str());
337 
338     if (localBundleInfo.applicationInfo.bundleType != AppExecFwk::BundleType::APP) {
339         HILOGE("The bundleType must be app, but it is %{public}d", localBundleInfo.applicationInfo.bundleType);
340         return INVALID_PARAMETERS_ERR;
341     }
342     if (!IsBundleContinuable(localBundleInfo)) {
343         HILOGE("Bundle %{public}s is not continuable", finalBundleName.c_str());
344         return BUNDLE_NOT_CONTINUABLE;
345     }
346 
347     int32_t ret = VerifyBroadcastSource(senderNetworkId, bundleName, finalBundleName, continueType, state);
348     if (ret != ERR_OK) {
349         return ret;
350     }
351     std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
352     auto iterItem = registerOnListener_.find(onType_);
353     if (iterItem == registerOnListener_.end()) {
354         HILOGE("get iterItem failed from registerOnListener_, bundleNameId: %{public}u", bundleNameId);
355         return INVALID_PARAMETERS_ERR;
356     }
357     std::vector<sptr<IRemoteObject>> objs = iterItem->second;
358     for (auto iter : objs) {
359         NotifyRecvBroadcast(iter, currentIconInfo(senderNetworkId, bundleName, finalBundleName, continueType), state);
360     }
361     HILOGI("DealOnBroadcastBusiness end");
362     return ERR_OK;
363 }
364 
IsBundleContinuable(const AppExecFwk::BundleInfo & bundleInfo)365 bool DMSContinueRecvMgr::IsBundleContinuable(const AppExecFwk::BundleInfo& bundleInfo)
366 {
367     for (auto abilityInfo : bundleInfo.abilityInfos) {
368         if (abilityInfo.continuable) {
369             return true;
370         }
371     }
372     return false;
373 }
374 
NotifyRecvBroadcast(const sptr<IRemoteObject> & obj,const currentIconInfo & continueInfo,const int32_t state)375 void DMSContinueRecvMgr::NotifyRecvBroadcast(const sptr<IRemoteObject>& obj,
376     const currentIconInfo& continueInfo, const int32_t state)
377 {
378     std::string networkId = continueInfo.senderNetworkId;
379     std::string srcBundleName = continueInfo.sourceBundleName;
380     std::string sinkBundleName = continueInfo.bundleName;
381     std::string continueType = continueInfo.continueType.empty() ? "" : continueInfo.continueType;
382 
383     HILOGI("NotifyRecvBroadcast start");
384     if (obj == nullptr) {
385         HILOGE("obj is null");
386         return;
387     }
388     MessageParcel data;
389     MessageParcel reply;
390     MessageOption option(MessageOption::TF_ASYNC);
391     if (!data.WriteInterfaceToken(DESCRIPTOR)) {
392         HILOGE("NotifyRecvBroadcast write interface token failed");
393         return;
394     }
395     PARCEL_WRITE_HELPER_NORET(data, Int32, state);
396     PARCEL_WRITE_HELPER_NORET(data, String, networkId);
397     PARCEL_WRITE_HELPER_NORET(data, String, sinkBundleName);
398     PARCEL_WRITE_HELPER_NORET(data, String, continueType);
399     PARCEL_WRITE_HELPER_NORET(data, String, srcBundleName);
400     HILOGI("[PerformanceTest] NotifyRecvBroadcast called, IPC begin = %{public}" PRId64, GetTickCount());
401     int32_t error = obj->SendRequest(ON_CALLBACK, data, reply, option);
402     if (state != INACTIVE) {
403         std::string bName = sinkBundleName;
404         std::string cType = continueType;
405         std::string abilityName = BundleManagerInternal::GetInstance().GetAbilityName(networkId,
406             bName, cType);
407         DmsUE::GetInstance().NotifyDockShowIcon(sinkBundleName, abilityName, networkId, error);
408     }
409     if (error != ERR_NONE) {
410         HILOGE("NotifyRecvBroadcast fail, error: %{public}d", error);
411         return;
412     }
413     HILOGI("NotifyRecvBroadcast end");
414 }
415 
NotifyDied(const sptr<IRemoteObject> & obj)416 void DMSContinueRecvMgr::NotifyDied(const sptr<IRemoteObject>& obj)
417 {
418     HILOGI("NotifyDied start");
419     if (obj == nullptr) {
420         HILOGE("obj is null");
421         return;
422     }
423     for (auto iterItem = registerOnListener_.begin(); iterItem != registerOnListener_.end();) {
424         for (auto iter = iterItem->second.begin(); iter != iterItem->second.end();) {
425             if (*iter == obj) {
426                 obj->RemoveDeathRecipient(missionDiedListener_);
427                 iter = iterItem->second.erase(iter);
428             } else {
429                 iter++;
430             }
431         }
432         if (iterItem->second.empty()) {
433             std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
434             iterItem = registerOnListener_.erase(iterItem);
435         } else {
436             iterItem++;
437         }
438     }
439     HILOGI("NotifyDied end");
440 }
441 
442 #ifdef SUPPORT_COMMON_EVENT_SERVICE
OnDeviceScreenOff()443 void DMSContinueRecvMgr::OnDeviceScreenOff()
444 {
445     HILOGI("OnDeviceScreenOff called");
446     auto func = [this]() {
447         std::string senderNetworkId;
448         std::string bundleName;
449         std::string continueType;
450         {
451             std::lock_guard<std::mutex> currentIconLock(iconMutex_);
452             if (iconInfo_.isEmpty()) {
453                 HILOGW("Saved iconInfo has already been cleared, task abort.");
454                 return;
455             }
456             senderNetworkId = iconInfo_.senderNetworkId;
457             bundleName = iconInfo_.bundleName;
458             continueType = iconInfo_.continueType;
459             iconInfo_.senderNetworkId = "";
460             iconInfo_.bundleName = "";
461             iconInfo_.continueType = "";
462         }
463         HILOGI("Saved iconInfo cleared, networkId: %{public}s, bundleName: %{public}s.",
464             GetAnonymStr(senderNetworkId).c_str(), bundleName.c_str());
465         {
466             std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
467             auto iterItem = registerOnListener_.find(onType_);
468             if (iterItem == registerOnListener_.end()) {
469                 HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
470                 return;
471             }
472             std::vector<sptr<IRemoteObject>> objs = iterItem->second;
473             for (auto iter : objs) {
474                 NotifyRecvBroadcast(iter,
475                     currentIconInfo(senderNetworkId, iconInfo_.sourceBundleName, bundleName, continueType),
476                     INACTIVE);
477             }
478         }
479     };
480     if (eventHandler_ == nullptr) {
481         HILOGE("eventHandler_ is nullptr");
482         return;
483     }
484     eventHandler_->PostTask(func);
485 }
486 #endif
487 
OnContinueSwitchOff()488 void DMSContinueRecvMgr::OnContinueSwitchOff()
489 {
490     auto func = [this]() {
491         std::string senderNetworkId;
492         std::string bundleName;
493         std::string continueType;
494         {
495             std::lock_guard<std::mutex> currentIconLock(iconMutex_);
496             if (iconInfo_.isEmpty()) {
497                 HILOGW("Saved iconInfo has already been cleared, task abort.");
498                 return;
499             }
500             senderNetworkId = iconInfo_.senderNetworkId;
501             bundleName = iconInfo_.bundleName;
502             continueType = iconInfo_.continueType;
503             iconInfo_.senderNetworkId = "";
504             iconInfo_.bundleName = "";
505             iconInfo_.continueType = "";
506         }
507         HILOGI("Saved iconInfo cleared, networkId: %{public}s, bundleName: %{public}s.",
508             GetAnonymStr(senderNetworkId).c_str(), bundleName.c_str());
509         {
510             std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
511             auto iterItem = registerOnListener_.find(onType_);
512             if (iterItem == registerOnListener_.end()) {
513                 HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
514                 return;
515             }
516             std::vector<sptr<IRemoteObject>> objs = iterItem->second;
517             for (auto iter : objs) {
518                 NotifyRecvBroadcast(iter,
519                     currentIconInfo(senderNetworkId, iconInfo_.sourceBundleName, bundleName, continueType),
520                     INACTIVE);
521             }
522         }
523     };
524     if (eventHandler_ == nullptr) {
525         HILOGE("eventHandler_ is nullptr");
526         return;
527     }
528     eventHandler_->PostTask(func);
529 }
530 
NotifyDeviceOffline(const std::string & networkId)531 void DMSContinueRecvMgr::NotifyDeviceOffline(const std::string& networkId)
532 {
533     if (networkId.empty()) {
534         HILOGE("NotifyDeviceOffline networkId empty");
535         return;
536     }
537     HILOGI("NotifyDeviceOffline begin. networkId: %{public}s.", GetAnonymStr(networkId).c_str());
538     std::string localNetworkId;
539     if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localNetworkId)) {
540         HILOGE("Get local networkId failed");
541         return;
542     }
543     std::string senderNetworkId;
544     std::string bundleName;
545     std::string continueType;
546     {
547         std::lock_guard<std::mutex> currentIconLock(iconMutex_);
548         if (networkId != iconInfo_.senderNetworkId && networkId != localNetworkId) {
549             HILOGI("NotifyDeviceOffline irrelevant device offline, ignore");
550             return;
551         }
552         senderNetworkId = iconInfo_.senderNetworkId;
553         bundleName = iconInfo_.bundleName;
554         continueType = iconInfo_.continueType;
555         iconInfo_.senderNetworkId = "";
556         iconInfo_.bundleName = "";
557         iconInfo_.continueType = "";
558     }
559     HILOGI("Saved iconInfo cleared, networkId: %{public}s, bundleName: %{public}s.",
560         GetAnonymStr(senderNetworkId).c_str(), bundleName.c_str());
561     {
562         std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
563         auto iterItem = registerOnListener_.find(onType_);
564         if (iterItem == registerOnListener_.end()) {
565             HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
566             return;
567         }
568         std::vector<sptr<IRemoteObject>> objs = iterItem->second;
569         for (auto iter : objs) {
570             NotifyRecvBroadcast(iter,
571                 currentIconInfo(senderNetworkId, iconInfo_.sourceBundleName, bundleName, continueType),
572                 INACTIVE);
573         }
574     }
575     HILOGI("NotifyDeviceOffline end");
576 }
577 
NotifyPackageRemoved(const std::string & sinkBundleName)578 void DMSContinueRecvMgr::NotifyPackageRemoved(const std::string& sinkBundleName)
579 {
580     if (sinkBundleName.empty()) {
581         HILOGE("NotifyPackageRemoved sinkBundleName empty");
582         return;
583     }
584     if (iconInfo_.bundleName != sinkBundleName) {
585         HILOGI("NotifyPackageRemoved current sinkBundleName: %{public}s; removed package: %{public}s.",
586             iconInfo_.bundleName.c_str(), sinkBundleName.c_str());
587         return;
588     }
589     HILOGI("NotifyPackageRemoved begin. sinkBundleName: %{public}s.", sinkBundleName.c_str());
590     std::string senderNetworkId;
591     std::string bundleName;
592     std::string continueType;
593     {
594         std::lock_guard<std::mutex> currentIconLock(iconMutex_);
595         senderNetworkId = iconInfo_.senderNetworkId;
596         bundleName = iconInfo_.bundleName;
597         continueType = iconInfo_.continueType;
598         iconInfo_.senderNetworkId = "";
599         iconInfo_.bundleName = "";
600         iconInfo_.continueType = "";
601     }
602     HILOGI("Saved iconInfo cleared, sinkBundleName: %{public}s.",  bundleName.c_str());
603     {
604         std::lock_guard<std::mutex> registerOnListenerMapLock(eventMutex_);
605         auto iterItem = registerOnListener_.find(onType_);
606         if (iterItem == registerOnListener_.end()) {
607             HILOGI("Get iterItem failed from registerOnListener_, nobody registed");
608             return;
609         }
610         std::vector<sptr<IRemoteObject>> objs = iterItem->second;
611         for (auto iter : objs) {
612             NotifyRecvBroadcast(iter,
613                 currentIconInfo(senderNetworkId, iconInfo_.sourceBundleName, bundleName, continueType),
614                 INACTIVE);
615         }
616     }
617     HILOGI("NotifyPackageRemoved end");
618 }
619 
GetContinueType(const std::string & bundleName)620 std::string DMSContinueRecvMgr::GetContinueType(const std::string& bundleName)
621 {
622     std::lock_guard<std::mutex> currentIconLock(iconMutex_);
623     if (iconInfo_.isEmpty()) {
624         HILOGW("get continueType failed, Saved iconInfo has already been cleared.");
625         return "";
626     }
627     if (iconInfo_.bundleName != bundleName) {
628         HILOGW("BundleName not match, task abort. bundleName: %{public}s, saved bundleName: %{public}s",
629             bundleName.c_str(), iconInfo_.bundleName.c_str());
630         return "";
631     }
632 
633     return iconInfo_.continueType;
634 }
635 
CheckRegSoftbusListener()636 bool DMSContinueRecvMgr::CheckRegSoftbusListener()
637 {
638     return hasRegSoftbusEventListener_;
639 }
640 } // namespace DistributedSchedule
641 } // namespace OHOS
642