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