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