1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "mission/dms_continue_send_manager.h" 17 18 #include <sys/prctl.h> 19 20 #include "adapter/dnetwork_adapter.h" 21 #include "adapter/mmi_adapter.h" 22 #include "datetime_ex.h" 23 #include "datashare_manager.h" 24 #include "dfx/distributed_radar.h" 25 #include "distributed_sched_adapter.h" 26 #include "distributed_sched_utils.h" 27 #include "dsched_data_buffer.h" 28 #include "dtbschedmgr_device_info_storage.h" 29 #include "dtbschedmgr_log.h" 30 #include "mission/dms_continue_recv_manager.h" 31 #include "mission/wifi_state_adapter.h" 32 #include "parcel_helper.h" 33 #include "softbus_adapter/softbus_adapter.h" 34 #include "switch_status_dependency.h" 35 36 namespace OHOS { 37 namespace DistributedSchedule { 38 namespace { 39 constexpr int32_t INDEX_2 = 2; 40 constexpr int32_t INDEX_3 = 3; 41 constexpr int32_t CANCEL_FOCUSED_DELAYED = 60000; 42 constexpr int32_t SCREEN_OFF_DELAY_TIME = 10000; 43 constexpr int64_t TIME_DELAYED = 500; // determines whether normal unfocused or lockoff 44 const std::string TAG = "DMSContinueSendMgr"; 45 const std::string TIMEOUT_UNFOCUSED_TASK = "timeout_unfocused_task"; 46 const std::string SCREEN_OFF_UNFOCUSED_TASK = "screen_off_unfocused_task"; 47 } 48 49 IMPLEMENT_SINGLE_INSTANCE(DMSContinueSendMgr); 50 Init()51 void DMSContinueSendMgr::Init() 52 { 53 HILOGI("Init start"); 54 if (eventHandler_ != nullptr) { 55 HILOGI("Already inited, end."); 56 return; 57 } 58 { 59 MMIAdapter::GetInstance().Init(); 60 SoftbusAdapter::GetInstance().Init(); 61 screenOffHandler_ = std::make_shared<ScreenOffHandler>(); 62 63 eventThread_ = std::thread(&DMSContinueSendMgr::StartEvent, this); 64 std::unique_lock<std::mutex> lock(eventMutex_); 65 eventCon_.wait(lock, [this] { 66 return eventHandler_ != nullptr; 67 }); 68 } 69 70 int32_t missionId = GetCurrentMissionId(); 71 if (missionId <= 0) { 72 HILOGW("GetCurrentMissionId failed, init end. ret: %{public}d", missionId); 73 return; 74 } 75 NotifyMissionFocused(missionId, FocusedReason::INIT); 76 HILOGI("Init end"); 77 } 78 UnInit()79 void DMSContinueSendMgr::UnInit() 80 { 81 HILOGI("UnInit start"); 82 MMIAdapter::GetInstance().UnInit(); 83 SoftbusAdapter::GetInstance().UnInit(); 84 if (eventHandler_ != nullptr && eventHandler_->GetEventRunner() != nullptr) { 85 eventHandler_->GetEventRunner()->Stop(); 86 eventThread_.join(); 87 eventHandler_ = nullptr; 88 } else { 89 HILOGE("eventHandler_ is nullptr"); 90 } 91 HILOGI("UnInit end"); 92 } 93 GetCurrentMissionId()94 int32_t DMSContinueSendMgr::GetCurrentMissionId() 95 { 96 HILOGI("GetCurrentMission begin"); 97 auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance(); 98 if (abilityMgr == nullptr) { 99 HILOGE("abilityMgr is nullptr"); 100 return INVALID_PARAMETERS_ERR; 101 } 102 103 sptr<IRemoteObject> token; 104 int ret = abilityMgr->GetTopAbility(token); 105 if (ret != ERR_OK || token == nullptr) { 106 HILOGE("GetTopAbility failed, ret: %{public}d", ret); 107 return INVALID_MISSION_ID; 108 } 109 int32_t missionId = INVALID_MISSION_ID; 110 abilityMgr->GetMissionIdByToken(token, missionId); 111 return missionId; 112 } 113 PostUnfocusedTaskWithDelay(const int32_t missionId,UnfocusedReason reason)114 void DMSContinueSendMgr::PostUnfocusedTaskWithDelay(const int32_t missionId, UnfocusedReason reason) 115 { 116 HILOGI("called, missionId: %{public}d, reason: %{public}d", missionId, reason); 117 if (eventHandler_ == nullptr) { 118 HILOGE("eventHandler_ is nullptr"); 119 return; 120 } 121 if (reason == UnfocusedReason::TIMEOUT) { 122 auto funcOut = [this, missionId]() { 123 DealUnfocusedBusiness(missionId, UnfocusedReason::TIMEOUT); 124 }; 125 std::string timeoutTaskName = TIMEOUT_UNFOCUSED_TASK + std::to_string(missionId); 126 eventHandler_->RemoveTask(timeoutTaskName); 127 eventHandler_->PostTask(funcOut, timeoutTaskName, CANCEL_FOCUSED_DELAYED); 128 } else if (reason == UnfocusedReason::SCREENOFF) { 129 auto funcOff = [this]() { 130 SendScreenOffEvent(DMS_UNFOCUSED_TYPE); 131 }; 132 std::string scrOffTaskName = SCREEN_OFF_UNFOCUSED_TASK + std::to_string(missionId); 133 eventHandler_->RemoveTask(scrOffTaskName); 134 eventHandler_->PostTask(funcOff, scrOffTaskName, SCREEN_OFF_DELAY_TIME); 135 } 136 } 137 NotifyMissionFocused(const int32_t missionId,FocusedReason reason)138 void DMSContinueSendMgr::NotifyMissionFocused(const int32_t missionId, FocusedReason reason) 139 { 140 HILOGI("NotifyMissionFocused called, missionId: %{public}d, reason: %{public}d", missionId, reason); 141 if (reason <= FocusedReason::MIN || reason >= FocusedReason::MAX) { 142 HILOGI("Unknown focusedReason, no need to deal NotifyMissionFocused"); 143 return; 144 } 145 if (!WifiStateAdapter::GetInstance().IsWifiActive()) { 146 HILOGE("wifi is not activated"); 147 return; 148 } 149 auto feedfunc = [this, missionId, reason]() { 150 int32_t newMissionId = missionId; 151 if (reason == FocusedReason::MMI) { 152 newMissionId = info_.currentMissionId; 153 } 154 if (reason == FocusedReason::NORMAL && screenOffHandler_ != nullptr) { 155 screenOffHandler_->ClearScreenOffInfo(); 156 } 157 DealFocusedBusiness(newMissionId, reason); 158 if (newMissionId == info_.currentMissionId && info_.currentIsContinuable) { 159 PostUnfocusedTaskWithDelay(newMissionId, UnfocusedReason::TIMEOUT); 160 } 161 }; 162 163 if (eventHandler_ == nullptr) { 164 HILOGE("eventHandler_ is nullptr"); 165 return; 166 } 167 eventHandler_->RemoveTask(TIMEOUT_UNFOCUSED_TASK + std::to_string(missionId)); 168 eventHandler_->RemoveTask(SCREEN_OFF_UNFOCUSED_TASK + std::to_string(missionId)); 169 eventHandler_->PostTask(feedfunc); 170 } 171 NotifyMissionUnfocused(const int32_t missionId,UnfocusedReason reason)172 void DMSContinueSendMgr::NotifyMissionUnfocused(const int32_t missionId, UnfocusedReason reason) 173 { 174 HILOGI("NotifyMissionUnfocused start, missionId: %{public}d, reason: %{public}d", missionId, reason); 175 if (reason <= UnfocusedReason::MIN || reason >= UnfocusedReason::MAX) { 176 HILOGE("unknown unfocused reason!"); 177 return; 178 } 179 auto feedfunc = [this, missionId, reason]() { 180 DealUnfocusedBusiness(missionId, reason); 181 }; 182 if (eventHandler_ != nullptr) { 183 eventHandler_->RemoveTask(TIMEOUT_UNFOCUSED_TASK + std::to_string(missionId)); 184 eventHandler_->PostTask(feedfunc); 185 } else { 186 HILOGE("eventHandler_ is nullptr"); 187 } 188 } 189 GetMissionIdByBundleName(const std::string & bundleName,int32_t & missionId)190 int32_t DMSContinueSendMgr::GetMissionIdByBundleName(const std::string& bundleName, int32_t& missionId) 191 { 192 HILOGI("start, bundleName: %{public}s", bundleName.c_str()); 193 std::lock_guard<std::mutex> focusedMissionMapLock(eventMutex_); 194 auto iterItem = focusedMission_.find(bundleName); 195 if (iterItem != focusedMission_.end()) { 196 missionId = iterItem->second; 197 HILOGI("get missionId end, missionId: %{public}d", missionId); 198 return ERR_OK; 199 } 200 HILOGW("get iterItem failed from focusedMission_, try screenOffHandler_"); 201 if (screenOffHandler_ != nullptr && bundleName == screenOffHandler_->GetBundleName()) { 202 missionId = screenOffHandler_->GetMissionId(); 203 HILOGI("get missionId end, missionId: %{public}d", missionId); 204 return ERR_OK; 205 } 206 HILOGW("get bundleName failed from screenOffHandler_"); 207 if (bundleName == lastFocusedMissionInfo_.bundleName) { 208 missionId = lastFocusedMissionInfo_.missionId; 209 HILOGI("get missionId end, missionId: %{public}d", missionId); 210 return ERR_OK; 211 } 212 return MISSION_NOT_FOCUSED; 213 } 214 StartEvent()215 void DMSContinueSendMgr::StartEvent() 216 { 217 HILOGI("StartEvent start"); 218 prctl(PR_SET_NAME, CONTINUE_MANAGER.c_str()); 219 auto runner = AppExecFwk::EventRunner::Create(false); 220 { 221 std::lock_guard<std::mutex> lock(eventMutex_); 222 eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner); 223 } 224 eventCon_.notify_one(); 225 if (runner != nullptr) { 226 runner->Run(); 227 } else { 228 HILOGE("runner is null"); 229 } 230 HILOGI("StartEvent end"); 231 } 232 SendSoftbusEvent(uint16_t bundleNameId,uint8_t continueTypeId,uint8_t type)233 int32_t DMSContinueSendMgr::SendSoftbusEvent(uint16_t bundleNameId, uint8_t continueTypeId, uint8_t type) 234 { 235 HILOGD("SendSoftbusEvent start, bundleNameId: %{public}u, continueTypeId: %{public}u", 236 bundleNameId, continueTypeId); 237 std::shared_ptr<DSchedDataBuffer> buffer = std::make_shared<DSchedDataBuffer>(DMS_SEND_LEN); 238 if (buffer->Data() == nullptr || buffer->Size() < DMS_SEND_LEN) { 239 HILOGE("Failed to initialize DSchedDataBuffer"); 240 return INVALID_PARAMETERS_ERR; 241 } 242 buffer->Data()[0] = (type << CONTINUE_SHIFT_04) | DMS_DATA_LEN; 243 buffer->Data()[1] = (bundleNameId >> CONTINUE_SHIFT_08) & DMS_0XFF; 244 buffer->Data()[INDEX_2] = bundleNameId & DMS_0XFF; 245 buffer->Data()[INDEX_3] = continueTypeId & DMS_0XFF; 246 247 int32_t ret = SoftbusAdapter::GetInstance().SendSoftbusEvent(buffer); 248 HILOGD("SendSoftbusEvent end. Result: %{public}d", ret); 249 return ret; 250 } 251 AddMMIListener()252 void DMSContinueSendMgr::AddMMIListener() 253 { 254 if (mmiMonitorId_ >= 0) { 255 HILOGD("MMI listener already exist, monitor id: %{public}d", mmiMonitorId_); 256 return; 257 } 258 mmiMonitorId_ = MMIAdapter::GetInstance().AddMMIListener(); 259 if (mmiMonitorId_ < 0) { 260 HILOGW("Add MMI listener failed, ret: %{public}d", mmiMonitorId_); 261 return; 262 } 263 HILOGD("MMI listener has been added, monitor id: %{public}d", mmiMonitorId_); 264 } 265 RemoveMMIListener()266 void DMSContinueSendMgr::RemoveMMIListener() 267 { 268 if (mmiMonitorId_ < 0) { 269 HILOGI("No MMI listener to be removed, monitor id: %{public}d", mmiMonitorId_); 270 return; 271 } 272 MMIAdapter::GetInstance().RemoveMMIListener(mmiMonitorId_); 273 HILOGI("MMI listener has been removed, monitor id: %{public}d", mmiMonitorId_); 274 275 mmiMonitorId_ = INVALID_MISSION_ID; 276 return; 277 } 278 DealFocusedBusiness(const int32_t missionId,FocusedReason reason)279 int32_t DMSContinueSendMgr::DealFocusedBusiness(const int32_t missionId, FocusedReason reason) 280 { 281 HILOGI("DealFocusedBusiness start, missionId: %{public}d", missionId); 282 AAFwk::MissionInfo info; 283 auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance(); 284 if (abilityMgr != nullptr) { 285 int32_t ret = abilityMgr->GetMissionInfo("", missionId, info); 286 if (ret != ERR_OK) { 287 HILOGE("get missionInfo failed, missionId: %{public}d, ret: %{public}d", missionId, ret); 288 return ret; 289 } 290 } else { 291 HILOGE("abilityMgr is null"); 292 return INVALID_PARAMETERS_ERR; 293 } 294 bool isMissionContinuable = info.continuable; 295 { 296 std::lock_guard<std::mutex> currentMissionIdLock(eventMutex_); 297 info_.currentMissionId = missionId; 298 info_.currentIsContinuable = isMissionContinuable; 299 } 300 if (!isMissionContinuable) { 301 HILOGI("Mission is not continuable, task abort, missionId: %{public}d", missionId); 302 return REMOTE_DEVICE_BIND_ABILITY_ERR; 303 } 304 std::string bundleName = info.want.GetBundle(); 305 if (!CheckBundleContinueConfig(bundleName)) { 306 HILOGI("App does not allow continue in config file, bundle name %{public}s, missionId: %{public}d", 307 bundleName.c_str(), missionId); 308 return REMOTE_DEVICE_BIND_ABILITY_ERR; 309 } 310 focusedMission_[bundleName] = missionId; 311 312 std::string abilityName = info.want.GetElement().GetAbilityName(); 313 focusedMissionAbility_[missionId] = abilityName; 314 UpdateContinueLaunchMission(info); 315 316 if (info.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) { 317 HILOGE("Mission continue state set to INACTIVE. Broadcast task abort."); 318 return INVALID_PARAMETERS_ERR; 319 } 320 #ifdef SUPPORT_MULTIMODALINPUT_SERVICE 321 if (reason != FocusedReason::MMI) { 322 AddMMIListener(); 323 } 324 #endif 325 if (!SwitchStatusDependency::GetInstance().IsContinueSwitchOn()) { return DMS_PERMISSION_DENIED;} 326 int32_t ret = FocusedBusinessSendEvent(bundleName, abilityName); 327 HILOGI("DealFocusedBusiness end"); 328 return ret; 329 } 330 FocusedBusinessSendEvent(std::string bundleName,const std::string & abilityName)331 int32_t DMSContinueSendMgr::FocusedBusinessSendEvent(std::string bundleName, const std::string& abilityName) 332 { 333 uint16_t bundleNameId = 0; 334 int32_t ret = BundleManagerInternal::GetBundleNameId(bundleName, bundleNameId); 335 if (ret != ERR_OK) { 336 HILOGE("Get focused bundleNameId failed, bundleNameId: %{public}u, ret: %{public}d", bundleNameId, ret); 337 return ret; 338 } 339 340 uint8_t continueTypeId = 0; 341 ret = BundleManagerInternal::GetContinueTypeId(bundleName, abilityName, continueTypeId); 342 if (ret != ERR_OK) { 343 HILOGE("Get focused contineTypeId failed, contineTypeId: %{public}u, ret: %{public}d", continueTypeId, ret); 344 return ret; 345 } 346 347 ret = SendSoftbusEvent(bundleNameId, continueTypeId, DMS_FOCUSED_TYPE); 348 if (ret != ERR_OK) { 349 HILOGE("SendSoftbusEvent focused failed, ret: %{public}d", ret); 350 } 351 return ret; 352 } 353 CheckContinueState(const int32_t missionId)354 int32_t DMSContinueSendMgr::CheckContinueState(const int32_t missionId) 355 { 356 auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance(); 357 if (abilityMgr == nullptr) { 358 HILOGE("abilityMgr is null"); 359 return INVALID_PARAMETERS_ERR; 360 } 361 362 AAFwk::MissionInfo info; 363 int32_t ret = abilityMgr->GetMissionInfo("", missionId, info); 364 if (ret != ERR_OK) { 365 HILOGE("get missionInfo failed, missionId: %{public}d, ret: %{public}d", missionId, ret); 366 return INVALID_PARAMETERS_ERR; 367 } 368 if (info.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) { 369 HILOGE("Mission continue state set to INACTIVE. Broadcast task abort."); 370 return INVALID_PARAMETERS_ERR; 371 } 372 return ERR_OK; 373 } 374 DealUnfocusedBusiness(const int32_t missionId,UnfocusedReason reason)375 int32_t DMSContinueSendMgr::DealUnfocusedBusiness(const int32_t missionId, UnfocusedReason reason) 376 { 377 HILOGI("DealUnfocusedBusiness start, missionId: %{public}d", missionId); 378 std::string bundleName; 379 int32_t ret = GetBundleNameByMissionId(missionId, bundleName); 380 if (ret != ERR_OK) { 381 HILOGI("Get bundleName failed, missionId: %{public}d, ret: %{public}d", missionId, ret); 382 return ret; 383 } 384 HILOGI("Get bundleName success, mission is continuable, missionId: %{public}d, bundleName: %{public}s", 385 missionId, bundleName.c_str()); 386 std::string abilityName; 387 ret = GetAbilityNameByMissionId(missionId, abilityName); 388 if (ret != ERR_OK) { 389 HILOGE("get abilityName failed, missionId: %{public}d, ret: %{public}d", missionId, ret); 390 return ret; 391 } 392 if (reason != UnfocusedReason::TIMEOUT) { 393 if (!IsContinue(missionId, bundleName)) { 394 HILOGE("Not current mission to be continued, missionId: %{public}d", missionId); 395 EraseFocusedMission(bundleName, missionId, reason); 396 return NO_MISSION_INFO_FOR_MISSION_ID; 397 } 398 #ifdef SUPPORT_MULTIMODALINPUT_SERVICE 399 RemoveMMIListener(); 400 #endif 401 } 402 uint16_t bundleNameId = 0; 403 uint8_t continueTypeId = 0; 404 ret = GetAccessTokenIdSendEvent(bundleName, reason, bundleNameId, continueTypeId); 405 if (ret != ERR_OK) { 406 HILOGE("GetAccessTokenIdSendEvent failed"); 407 EraseFocusedMission(bundleName, missionId, reason); 408 return ret; 409 } 410 EraseFocusedMission(bundleName, missionId, reason); 411 if (reason == UnfocusedReason::NORMAL && screenOffHandler_ != nullptr) { 412 screenOffHandler_->SetScreenOffInfo(missionId, bundleName, bundleNameId, abilityName); 413 } 414 HILOGI("DealUnfocusedBusiness end"); 415 return ERR_OK; 416 } 417 EraseFocusedMission(const std::string & bundleName,const int32_t & missionId,const UnfocusedReason & reason)418 void DMSContinueSendMgr::EraseFocusedMission(const std::string& bundleName, const int32_t& missionId, 419 const UnfocusedReason& reason) 420 { 421 if (reason != UnfocusedReason::TIMEOUT) { 422 std::lock_guard<std::mutex> focusedMissionMapLock(eventMutex_); 423 focusedMission_.erase(bundleName); 424 focusedMissionAbility_.erase(missionId); 425 lastFocusedMissionInfo_ = { missionId, bundleName }; 426 } 427 } 428 SendScreenOffEvent(uint8_t type)429 int32_t DMSContinueSendMgr::SendScreenOffEvent(uint8_t type) 430 { 431 if (screenOffHandler_ == nullptr) { 432 HILOGE("screenOffHandler_ is nullptr"); 433 return INVALID_PARAMETERS_ERR; 434 } 435 int32_t missionId = screenOffHandler_->GetMissionId(); 436 std::string bundleName = screenOffHandler_->GetBundleName(); 437 uint16_t bundleNameId = screenOffHandler_->GetAccessTokenId(); 438 std::string abilityName = screenOffHandler_->GetAbilityName(); 439 440 HILOGI("start, type: %{public}d, missionId: %{public}d, bundleName: %{public}s, bundleNameId: %{public}u", 441 type, missionId, bundleName.c_str(), bundleNameId); 442 if (!CheckBundleContinueConfig(bundleName)) { 443 HILOGI("App does not allow continue in config file, bundle name %{public}s, missionId: %{public}d", 444 bundleName.c_str(), missionId); 445 return REMOTE_DEVICE_BIND_ABILITY_ERR; 446 } 447 448 if (!DataShareManager::GetInstance().IsCurrentContinueSwitchOn()) { 449 HILOGE("ContinueSwitch status is off"); 450 return DMS_PERMISSION_DENIED; 451 } 452 453 uint8_t continueTypeId = 0; 454 int32_t ret = BundleManagerInternal::GetContinueTypeId(bundleName, abilityName, continueTypeId); 455 if (ret != ERR_OK) { 456 HILOGE("Get focused contineTypeId failed, abilityName: %{public}s, ret: %{public}d", abilityName.c_str(), ret); 457 return ret; 458 } 459 460 ret = SendSoftbusEvent(bundleNameId, continueTypeId, type); 461 if (ret != ERR_OK) { 462 HILOGE("SendSoftbusEvent unfocused failed, ret: %{public}d", ret); 463 } 464 HILOGI("end"); 465 return ERR_OK; 466 } 467 GetBundleNameByMissionId(const int32_t missionId,std::string & bundleName)468 int32_t DMSContinueSendMgr::GetBundleNameByMissionId(const int32_t missionId, std::string& bundleName) 469 { 470 for (auto iterItem = focusedMission_.begin(); iterItem != focusedMission_.end(); iterItem++) { 471 if (iterItem->second == missionId) { 472 bundleName = iterItem->first; 473 return ERR_OK; 474 } 475 } 476 return INVALID_PARAMETERS_ERR; 477 } 478 GetBundleNameByScreenOffInfo(const int32_t missionId,std::string & bundleName)479 int32_t DMSContinueSendMgr::GetBundleNameByScreenOffInfo(const int32_t missionId, std::string& bundleName) 480 { 481 if (screenOffHandler_ != nullptr && missionId == screenOffHandler_->GetMissionId()) { 482 bundleName = screenOffHandler_->GetBundleName(); 483 if (bundleName.empty()) { 484 HILOGE("get bundleName failed from screenOffHandler"); 485 return INVALID_PARAMETERS_ERR; 486 } 487 HILOGI("get missionId end, bundleName: %{public}s", bundleName.c_str()); 488 return ERR_OK; 489 } 490 HILOGE("get bundleName failed from screenOffHandler"); 491 return INVALID_PARAMETERS_ERR; 492 } 493 GetAbilityNameByMissionId(const int32_t missionId,std::string & abilityName)494 int32_t DMSContinueSendMgr::GetAbilityNameByMissionId(const int32_t missionId, std::string& abilityName) 495 { 496 HILOGI("start, missionId: %{public}d", missionId); 497 std::lock_guard<std::mutex> focusedMissionAbilityMapLock(eventMutex_); 498 auto iterItem = focusedMissionAbility_.find(missionId); 499 if (iterItem != focusedMissionAbility_.end()) { 500 abilityName = iterItem->second; 501 HILOGI("get missionId end, missionId: %{public}d", missionId); 502 return ERR_OK; 503 } 504 HILOGW("get iterItem failed from focusedMissionAbility_, try screenOffHandler_"); 505 if (screenOffHandler_ != nullptr && missionId == screenOffHandler_->GetMissionId()) { 506 abilityName = screenOffHandler_->GetAbilityName(); 507 HILOGI("get missionId end, abilityName: %{public}s", abilityName.c_str()); 508 return ERR_OK; 509 } 510 HILOGE("get abilityName failed from screenOffHandler_"); 511 return INVALID_PARAMETERS_ERR; 512 } 513 IsContinue(const int32_t & missionId,const std::string & bundleName)514 bool DMSContinueSendMgr::IsContinue(const int32_t& missionId, const std::string& bundleName) 515 { 516 if (missionId != info_.currentMissionId && info_.currentIsContinuable) { 517 /*missionId and currentMissionId are not equal but currentMission can change, 518 continue to not send unfocus broadcast*/ 519 HILOGI("mission is not continue, missionId: %{public}d, currentMissionId: %{public}d", 520 missionId, info_.currentMissionId); 521 return false; 522 } 523 /*missionId and currentMissionId are equal, or missionId and currentMissionId are not equal 524 and currentIsContinuable not change, continue to send unfocus broadcast*/ 525 HILOGI("mission is continue, missionId: %{public}d, currentMissionId: %{public}d", 526 missionId, info_.currentMissionId); 527 return true; 528 } 529 SetMissionContinueState(const int32_t missionId,const AAFwk::ContinueState & state)530 int32_t DMSContinueSendMgr::SetMissionContinueState(const int32_t missionId, 531 const AAFwk::ContinueState &state) 532 { 533 HILOGI("SetMissionContinueState start, missionId: %{public}d, state: %{public}d", missionId, state); 534 auto feedfunc = [this, missionId, state]() { 535 DealSetMissionContinueStateBusiness(missionId, state); 536 if (state == AAFwk::ContinueState::CONTINUESTATE_ACTIVE && missionId == info_.currentMissionId && 537 info_.currentIsContinuable) { 538 PostUnfocusedTaskWithDelay(missionId, UnfocusedReason::TIMEOUT); 539 } 540 }; 541 if (eventHandler_ != nullptr) { 542 eventHandler_->RemoveTask(TIMEOUT_UNFOCUSED_TASK + std::to_string(missionId)); 543 eventHandler_->PostTask(feedfunc); 544 } else { 545 HILOGE("eventHandler_ is nullptr"); 546 return ERR_NULL_OBJECT; 547 } 548 HILOGI("SetMissionContinueState end"); 549 return ERR_OK; 550 } 551 DealSetMissionContinueStateBusiness(const int32_t missionId,const AAFwk::ContinueState & state)552 int32_t DMSContinueSendMgr::DealSetMissionContinueStateBusiness(const int32_t missionId, 553 const AAFwk::ContinueState &state) 554 { 555 HILOGI("DealSetMissionContinueStateBusiness start, missionId: %{public}d, state: %{public}d", missionId, state); 556 if (info_.currentMissionId != missionId) { 557 HILOGE("mission is not focused, broadcast task abort, missionId: %{public}d", missionId); 558 return INVALID_PARAMETERS_ERR; 559 } 560 std::string bundleName; 561 if (state == AAFwk::ContinueState::CONTINUESTATE_ACTIVE && 562 GetBundleNameByMissionId(missionId, bundleName) != ERR_OK) { 563 HILOGE("mission is not focused, broadcast task abort, missionId: %{public}d", missionId); 564 return INVALID_PARAMETERS_ERR; 565 } 566 if (!info_.currentIsContinuable) { 567 HILOGI("mission is not continuable, broadcast task abort, missionId: %{public}d", missionId); 568 return INVALID_PARAMETERS_ERR; 569 } 570 571 uint16_t bundleNameId = 0; 572 uint8_t continueTypeId = 0; 573 int32_t ret = GetBundleNameIdAndContinueTypeId(missionId, state, bundleNameId, continueTypeId); 574 if (ret != ERR_OK) { 575 HILOGE("Get focused contineTypeId failed, contineTypeId: %{public}u, ret: %{public}d", continueTypeId, ret); 576 return ret; 577 } 578 579 ret = SetStateSendEvent(bundleNameId, continueTypeId, state); 580 if (ret != ERR_OK) { 581 HILOGE("SetStateSendEvent failed"); 582 return ret; 583 } 584 HILOGI("DealSetMissionContinueStateBusiness end. ContinueState set to: %{public}d", state); 585 return ERR_OK; 586 } 587 GetBundleNameIdAndContinueTypeId(const int32_t missionId,const AAFwk::ContinueState & state,uint16_t & bundleNameId,uint8_t & continueTypeId)588 int32_t DMSContinueSendMgr::GetBundleNameIdAndContinueTypeId(const int32_t missionId, const AAFwk::ContinueState& state, 589 uint16_t& bundleNameId, uint8_t& continueTypeId) 590 { 591 std::string bundleName; 592 int32_t ret = GetBundleNameByMissionId(missionId, bundleName); 593 if (ret != ERR_OK) { 594 HILOGW("get iterItem failed from focusedMission, try screenOffHandler"); 595 if (GetBundleNameByScreenOffInfo(missionId, bundleName) != ERR_OK) { 596 HILOGE("get bundleName failed, missionId: %{public}d, ret: %{public}d", missionId, ret); 597 return ret; 598 } 599 } 600 HILOGI("get bundleName success, missionId: %{public}d, bundleName: %{public}s", missionId, bundleName.c_str()); 601 if (!CheckBundleContinueConfig(bundleName)) { 602 HILOGI("App does not allow continue in config file, bundle name %{public}s, missionId: %{public}d", 603 bundleName.c_str(), missionId); 604 return REMOTE_DEVICE_BIND_ABILITY_ERR; 605 } 606 607 ret = BundleManagerInternal::GetBundleNameId(bundleName, bundleNameId); 608 if (ret != ERR_OK) { 609 HILOGE("get bundleNameId failed, bundleNameId: %{public}u, ret: %{public}d", bundleNameId, ret); 610 return ret; 611 } 612 613 std::string abilityName; 614 ret = GetAbilityNameByMissionId(missionId, abilityName); 615 if (ret != ERR_OK) { 616 HILOGE("get abilityName failed, broadcast task abort, missionId: %{public}d, ret: %{public}d", 617 missionId, ret); 618 return ret; 619 } 620 621 return BundleManagerInternal::GetContinueTypeId(bundleName, abilityName, continueTypeId); 622 } 623 OnMMIEvent()624 void DMSContinueSendMgr::OnMMIEvent() 625 { 626 DMSContinueSendMgr::GetInstance().NotifyMissionFocused(INVALID_MISSION_ID, FocusedReason::MMI); 627 } 628 NotifyDeviceOnline()629 int32_t DMSContinueSendMgr::NotifyDeviceOnline() 630 { 631 HILOGD("NotifyDeviceOnline called"); 632 if (GetCurrentMissionId() <= 0) { 633 return INVALID_MISSION_ID; 634 } 635 NotifyMissionFocused(info_.currentMissionId, FocusedReason::ONLINE); 636 return ERR_OK; 637 } 638 OnDeviceScreenOff()639 void DMSContinueSendMgr::OnDeviceScreenOff() 640 { 641 HILOGI("OnDeviceScreenOff called"); 642 int32_t missionId = info_.currentMissionId; 643 if (!info_.currentIsContinuable || CheckContinueState(missionId) != ERR_OK) { 644 HILOGW("current mission is not continuable, ignore"); 645 return; 646 } 647 auto feedfunc = [this, missionId]() { 648 if (screenOffHandler_ != nullptr) { 649 screenOffHandler_->OnDeviceScreenOff(missionId); 650 } 651 }; 652 if (eventHandler_ == nullptr) { 653 HILOGE("eventHandler_ is nullptr"); 654 return; 655 } 656 eventHandler_->PostTask(feedfunc); 657 } 658 OnDeviceScreenOn()659 void DMSContinueSendMgr::OnDeviceScreenOn() 660 { 661 HILOGI("OnDeviceScreenOn called"); 662 auto feedfunc = [this]() { 663 if (screenOffHandler_ != nullptr) { 664 screenOffHandler_->OnDeviceScreenOn(); 665 } 666 }; 667 if (eventHandler_ == nullptr) { 668 HILOGE("eventHandler_ is nullptr"); 669 return; 670 } 671 eventHandler_->PostTask(feedfunc); 672 } 673 GetMissionId()674 int32_t DMSContinueSendMgr::ScreenOffHandler::GetMissionId() 675 { 676 return unfoInfo_.missionId; 677 } 678 GetBundleName()679 std::string DMSContinueSendMgr::ScreenOffHandler::GetBundleName() 680 { 681 return unfoInfo_.bundleName; 682 } 683 GetAbilityName()684 std::string DMSContinueSendMgr::ScreenOffHandler::GetAbilityName() 685 { 686 return unfoInfo_.abilityName; 687 } 688 GetAccessTokenId()689 uint32_t DMSContinueSendMgr::ScreenOffHandler::GetAccessTokenId() 690 { 691 return unfoInfo_.accessToken; 692 } 693 IsDeviceScreenOn()694 bool DMSContinueSendMgr::ScreenOffHandler::IsDeviceScreenOn() 695 { 696 return isScreenOn_; 697 } 698 699 OnDeviceScreenOff(int32_t missionId)700 void DMSContinueSendMgr::ScreenOffHandler::OnDeviceScreenOff(int32_t missionId) 701 { 702 HILOGI("ScreenOffHandler::OnDeviceScreenOff called"); 703 isScreenOn_ = false; 704 if (unfoInfo_.missionId != INVALID_MISSION_ID && (GetTickCount()- unfoInfo_.unfoTime) < TIME_DELAYED) { 705 // handle unfocus before screen off 706 DMSContinueSendMgr::GetInstance().SendScreenOffEvent(DMS_FOCUSED_TYPE); 707 } 708 DMSContinueSendMgr::GetInstance().PostUnfocusedTaskWithDelay(missionId, UnfocusedReason::SCREENOFF); 709 } 710 OnDeviceScreenOn()711 void DMSContinueSendMgr::ScreenOffHandler::OnDeviceScreenOn() 712 { 713 HILOGI("ScreenOffHandler::OnDeviceScreenOn called"); 714 isScreenOn_ = true; 715 } 716 ClearScreenOffInfo()717 void DMSContinueSendMgr::ScreenOffHandler::ClearScreenOffInfo() 718 { 719 HILOGI("clear last unfocused info"); 720 unfoInfo_.missionId = INVALID_MISSION_ID; 721 unfoInfo_.unfoTime = 0; 722 unfoInfo_.bundleName = ""; 723 unfoInfo_.accessToken = 0; 724 unfoInfo_.abilityName = ""; 725 } 726 SetScreenOffInfo(int32_t missionId,std::string bundleName,uint16_t bundleNameId,std::string abilityName)727 void DMSContinueSendMgr::ScreenOffHandler::SetScreenOffInfo(int32_t missionId, std::string bundleName, 728 uint16_t bundleNameId, std::string abilityName) 729 { 730 HILOGI("set last unfocused info, missionId: %{public}d, bundleName: %{public}s, bundleNameId: %{public}u", 731 missionId, bundleName.c_str(), bundleNameId); 732 unfoInfo_.missionId = missionId; 733 unfoInfo_.unfoTime = GetTickCount(); 734 unfoInfo_.bundleName = bundleName; 735 unfoInfo_.accessToken = bundleNameId; 736 unfoInfo_.abilityName = abilityName; 737 } 738 GetAccessTokenIdSendEvent(std::string bundleName,UnfocusedReason reason,uint16_t & bundleNameId,uint8_t & continueTypeId)739 int32_t DMSContinueSendMgr::GetAccessTokenIdSendEvent(std::string bundleName, 740 UnfocusedReason reason, uint16_t& bundleNameId, uint8_t& continueTypeId) 741 { 742 int32_t ret = BundleManagerInternal::GetBundleNameId(bundleName, bundleNameId); 743 if (ret != ERR_OK) { 744 HILOGE("Get unfocused bundleNameId failed, bundleNameId: %{public}u, ret: %{public}d", bundleNameId, ret); 745 return ret; 746 } 747 748 if (screenOffHandler_ != nullptr && screenOffHandler_->IsDeviceScreenOn()) { 749 ret = SendSoftbusEvent(bundleNameId, continueTypeId, DMS_UNFOCUSED_TYPE); 750 if (ret != ERR_OK) { 751 HILOGE("SendSoftbusEvent unfocused failed, ret: %{public}d", ret); 752 return ret; 753 } 754 } 755 return ret; 756 } 757 SetStateSendEvent(const uint16_t bundleNameId,const uint8_t & continueTypeId,const AAFwk::ContinueState & state)758 int32_t DMSContinueSendMgr::SetStateSendEvent(const uint16_t bundleNameId, const uint8_t& continueTypeId, 759 const AAFwk::ContinueState &state) 760 { 761 if (state == AAFwk::ContinueState::CONTINUESTATE_INACTIVE) { 762 RemoveMMIListener(); 763 } else { 764 AddMMIListener(); 765 } 766 767 if (!DataShareManager::GetInstance().IsCurrentContinueSwitchOn()) { 768 HILOGE("ContinueSwitch status is off"); 769 return DMS_PERMISSION_DENIED; 770 } 771 772 uint8_t type = state == AAFwk::ContinueState::CONTINUESTATE_INACTIVE ? DMS_UNFOCUSED_TYPE : DMS_FOCUSED_TYPE; 773 int32_t ret = SendSoftbusEvent(bundleNameId, continueTypeId, type); 774 if (ret != ERR_OK) { 775 HILOGE("SendSoftbusEvent setContinueState failed, ret: %{public}d", ret); 776 return ret; 777 } 778 return ret; 779 } 780 DeleteContinueLaunchMissionInfo(const int32_t missionId)781 void DMSContinueSendMgr::DeleteContinueLaunchMissionInfo(const int32_t missionId) 782 { 783 HILOGD("called"); 784 std::lock_guard<std::mutex> continueLaunchMissionMapLock(eventMutex_); 785 if (continueLaunchMission_.empty()) { 786 return; 787 } 788 for (auto iter = continueLaunchMission_.begin(); iter != continueLaunchMission_.end(); iter++) { 789 if (iter->second == missionId) { 790 continueLaunchMission_.erase(iter); 791 return; 792 } 793 } 794 } 795 GetContinueLaunchMissionInfo(const int32_t missionId,ContinueLaunchMissionInfo & missionInfo)796 int32_t DMSContinueSendMgr::GetContinueLaunchMissionInfo(const int32_t missionId, 797 ContinueLaunchMissionInfo& missionInfo) 798 { 799 HILOGD("start, missionId: %{public}d", missionId); 800 std::lock_guard<std::mutex> continueLaunchMissionMapLock(eventMutex_); 801 for (auto iter = continueLaunchMission_.begin(); iter != continueLaunchMission_.end(); iter++) { 802 if (iter->second == missionId) { 803 missionInfo = iter->first; 804 HILOGI("get missionInfo end, missionId: %{public}d", missionId); 805 return ERR_OK; 806 } 807 } 808 HILOGW("get missionInfo failed from continueLaunchMission"); 809 return INVALID_PARAMETERS_ERR; 810 } 811 UpdateContinueLaunchMission(const AAFwk::MissionInfo & info)812 bool DMSContinueSendMgr::UpdateContinueLaunchMission(const AAFwk::MissionInfo& info) 813 { 814 auto flag = info.want.GetFlags(); 815 if ((flag & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != AAFwk::Want::FLAG_ABILITY_CONTINUATION && 816 (flag & AAFwk::Want::FLAG_ABILITY_PREPARE_CONTINUATION) != AAFwk::Want::FLAG_ABILITY_PREPARE_CONTINUATION) { 817 return false; 818 } 819 820 std::string bundleName = info.want.GetBundle(); 821 std::string abilityName = info.want.GetElement().GetAbilityName(); 822 ContinueLaunchMissionInfo continueLaunchMissionInfo = { bundleName, abilityName }; 823 824 std::lock_guard<std::mutex> continueLaunchMissionMapLock(eventMutex_); 825 auto iterItem = continueLaunchMission_.find(continueLaunchMissionInfo); 826 if (iterItem == continueLaunchMission_.end()) { 827 HILOGI("not find continueLaunchMissionInfo"); 828 continueLaunchMission_[continueLaunchMissionInfo] = info.id; 829 return true; 830 } 831 if (iterItem->second < info.id) { 832 HILOGI("old missionId: %{public}d, new missionId: %{public}d", iterItem->second, info.id); 833 continueLaunchMission_[continueLaunchMissionInfo] = info.id; 834 return true; 835 } 836 return false; 837 } 838 } // namespace DistributedSchedule 839 } // namespace OHOS 840