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