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