• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_condition_manager.h"
17 
18 #include "ability_manager_client.h"
19 #include "datashare_manager.h"
20 #include "dtbschedmgr_log.h"
21 #include "mission_info.h"
22 #include "mission/bluetooth_state_adapter.h"
23 #include "mission/dsched_sync_e2e.h"
24 #include "mission/wifi_state_adapter.h"
25 #include "multi_user_manager.h"
26 
27 
28 namespace OHOS {
29 namespace DistributedSchedule {
30 namespace {
31 const std::string TAG = "DmsContinueConditionMgr";
32 constexpr int32_t GET_MAX_MISSIONS = 50;
33 constexpr int32_t CONDITION_INVALID_MISSION_ID = -1;
34 }
35 
36 IMPLEMENT_SINGLE_INSTANCE(DmsContinueConditionMgr);
37 
Init()38 void DmsContinueConditionMgr::Init()
39 {
40     InitConditionFuncs();
41     InitSystemCondition();
42     InitMissionCondition();
43 }
44 
UnInit()45 void DmsContinueConditionMgr::UnInit()
46 {
47     std::lock_guard<std::mutex> missionlock(missionMutex_);
48     missionMap_.clear();
49 }
50 
InitConditionFuncs()51 void DmsContinueConditionMgr::InitConditionFuncs()
52 {
53     sysFuncMap_[SYS_EVENT_CONTINUE_SWITCH] = &DmsContinueConditionMgr::SetIsContinueSwitchOn;
54     sysFuncMap_[SYS_EVENT_WIFI] = &DmsContinueConditionMgr::SetIsWifiActive;
55     sysFuncMap_[SYS_EVENT_BLUETOOTH] = &DmsContinueConditionMgr::SetIsBtActive;
56     sysFuncMap_[SYS_EVENT_SCREEN_LOCK] = &DmsContinueConditionMgr::SetIsScreenLocked;
57 
58     missionFuncMap_[MISSION_EVENT_FOCUSED] = &DmsContinueConditionMgr::OnMissionFocused;
59     missionFuncMap_[MISSION_EVENT_UNFOCUSED] = &DmsContinueConditionMgr::OnMissionUnfocused;
60     missionFuncMap_[MISSION_EVENT_DESTORYED] = &DmsContinueConditionMgr::OnMissionDestory;
61     missionFuncMap_[MISSION_EVENT_BACKGROUND] = &DmsContinueConditionMgr::OnMissionBackground;
62     missionFuncMap_[MISSION_EVENT_ACTIVE] = &DmsContinueConditionMgr::OnMissionActive;
63     missionFuncMap_[MISSION_EVENT_INACTIVE] = &DmsContinueConditionMgr::OnMissionInactive;
64 
65     conditionFuncMap_[MISSION_EVENT_FOCUSED] = &DmsContinueConditionMgr::CheckSendFocusedCondition;
66     conditionFuncMap_[MISSION_EVENT_UNFOCUSED] = &DmsContinueConditionMgr::CheckSendUnfocusedCondition;
67     conditionFuncMap_[MISSION_EVENT_DESTORYED] = &DmsContinueConditionMgr::CheckSendBackgroundCondition;
68     conditionFuncMap_[MISSION_EVENT_BACKGROUND] = &DmsContinueConditionMgr::CheckSendBackgroundCondition;
69     conditionFuncMap_[MISSION_EVENT_ACTIVE] = &DmsContinueConditionMgr::CheckSendActiveCondition;
70     conditionFuncMap_[MISSION_EVENT_INACTIVE] = &DmsContinueConditionMgr::CheckSendInactiveCondition;
71     conditionFuncMap_[MISSION_EVENT_TIMEOUT] = &DmsContinueConditionMgr::CheckSendBackgroundCondition;
72     conditionFuncMap_[MISSION_EVENT_MMI] = &DmsContinueConditionMgr::CheckSendFocusedCondition;
73     conditionFuncMap_[MISSION_EVENT_CONTINUE_SWITCH_OFF] =
74         &DmsContinueConditionMgr::CheckSendContinueSwitchOffCondition;
75 }
76 
InitSystemCondition()77 void DmsContinueConditionMgr::InitSystemCondition()
78 {
79     isSwitchOn_ = DataShareManager::GetInstance().IsCurrentContinueSwitchOn();
80     isWifiActive_ = WifiStateAdapter::GetInstance().IsWifiActive();
81 #ifdef DMS_CHECK_BLUETOOTH
82     isBtActive_ = BluetoothStateAdapter::GetInstance().IsBluetoothActive();
83 #endif
84 
85     HILOGI("end. switch: %{public}d, wifi: %{public}d, bt: %{public}d",
86         isSwitchOn_.load(), isWifiActive_.load(), isBtActive_.load());
87 }
88 
InitMissionCondition()89 void DmsContinueConditionMgr::InitMissionCondition()
90 {
91     int32_t currentAccountId = MultiUserManager::GetInstance().GetForegroundUser();
92     InitMissionStatus(currentAccountId);
93 }
94 
UpdateSystemStatus(SysEventType type,bool value)95 int32_t DmsContinueConditionMgr::UpdateSystemStatus(SysEventType type, bool value)
96 {
97     auto iterFunc = sysFuncMap_.find(type);
98     if (iterFunc == sysFuncMap_.end()) {
99         HILOGE("invalid system status %{public}d", type);
100         return INVALID_PARAMETERS_ERR;
101     }
102 
103     auto memberFunc = iterFunc->second;
104     int32_t ret = (this->*memberFunc)(value);
105     if (ret != ERR_OK) {
106         HILOGE("update system status %{public}d failed, ret: %{public}d", type, ret);
107     }
108     return ret;
109 }
110 
SetIsContinueSwitchOn(bool isSwitchOn)111 int32_t DmsContinueConditionMgr::SetIsContinueSwitchOn(bool isSwitchOn)
112 {
113     HILOGI("isSwitchOn changed, before: %{public}d, after: %{public}d", isSwitchOn_.load(), isSwitchOn);
114     isSwitchOn_.store(isSwitchOn);
115     return ERR_OK;
116 }
117 
SetIsWifiActive(bool isWifiActive)118 int32_t DmsContinueConditionMgr::SetIsWifiActive(bool isWifiActive)
119 {
120     HILOGI("isWifiActive changed, before: %{public}d, after: %{public}d", isWifiActive_.load(), isWifiActive);
121     isWifiActive_.store(isWifiActive);
122     return ERR_OK;
123 }
124 
SetIsBtActive(bool isBtActive)125 int32_t DmsContinueConditionMgr::SetIsBtActive(bool isBtActive)
126 {
127     HILOGI("isBtActive changed, before: %{public}d, after: %{public}d", isBtActive_.load(), isBtActive);
128     isBtActive_.store(isBtActive);
129     return ERR_OK;
130 }
131 
SetIsScreenLocked(bool isScreenLocked)132 int32_t DmsContinueConditionMgr::SetIsScreenLocked(bool isScreenLocked)
133 {
134     HILOGI("isScreenLocked changed, before: %{public}d, after: %{public}d", isScreenLocked_.load(), isScreenLocked);
135     isScreenLocked_.store(isScreenLocked);
136     return ERR_OK;
137 }
138 
OnUserSwitched(int32_t accountId)139 void DmsContinueConditionMgr::OnUserSwitched(int32_t accountId)
140 {
141     HILOGI("OnUserSwitched init mission status for new user: %{public}d", accountId);
142     InitMissionStatus(accountId);
143     return;
144 }
145 
OnUserRemoved(int32_t accountId)146 void DmsContinueConditionMgr::OnUserRemoved(int32_t accountId)
147 {
148     HILOGI("OnUserRemoved delete mission status for user: %{public}d", accountId);
149     std::lock_guard<std::mutex> missionlock(missionMutex_);
150     if (missionMap_.empty()) {
151         return;
152     }
153     auto it = missionMap_.find(accountId);
154     if (it != missionMap_.end()) {
155         missionMap_.erase(it);
156     }
157     lastContinuableMissionId_ = 0;
158     return;
159 }
160 
UpdateMissionStatus(int32_t accountId,int32_t missionId,MissionEventType type)161 int32_t DmsContinueConditionMgr::UpdateMissionStatus(int32_t accountId, int32_t missionId, MissionEventType type)
162 {
163     HILOGI("user %{public}d, missionId %{public}d, type %{public}s", accountId, missionId,
164         TypeEnumToString(type).c_str());
165     {
166         std::lock_guard<std::mutex> missionlock(missionMutex_);
167         auto missionList = missionMap_.find(accountId);
168         if (missionList == missionMap_.end()) {
169             HILOGW("no mission status records for user %{public}d", accountId);
170             return INVALID_PARAMETERS_ERR;
171         }
172     }
173 
174     auto iterFunc = missionFuncMap_.find(type);
175     if (iterFunc == missionFuncMap_.end()) {
176         HILOGE("invalid mission status %{public}d", type);
177         return INVALID_PARAMETERS_ERR;
178     }
179 
180     auto memberFunc = iterFunc->second;
181     int32_t ret = (this->*memberFunc)(accountId, missionId);
182     if (ret != ERR_OK) {
183         HILOGE("update mission status %{public}s failed, accountId %{public}d, missionId %{public}d, ret: %{public}d",
184             TypeEnumToString(type).c_str(), accountId, missionId, ret);
185     }
186     return ret;
187 }
188 
InitMissionStatus(int32_t accountId)189 void DmsContinueConditionMgr::InitMissionStatus(int32_t accountId)
190 {
191     HILOGI("InitMissionStatus for user %{public}d start", accountId);
192     std::vector<AAFwk::MissionInfo> missions;
193     int32_t ret = GetMissionInfos(missions);
194     if (ret != ERR_OK) {
195         HILOGE("GetMissionInfos failed, ret %{public}d", ret);
196     }
197 
198     if (missions.empty()) {
199         HILOGW("no running mission under current user");
200     }
201     HILOGI("GetMissionInfos ret size %{public}zu", missions.size());
202 
203     int32_t focusedMissionId = GetCurrentMissionId();
204     {
205         std::lock_guard<std::mutex> missionlock(missionMutex_);
206         if (!missionMap_.empty() && missionMap_.find(accountId) != missionMap_.end()) {
207             HILOGI("mission list for user %{public}d has already been inited", accountId);
208             return;
209         }
210 
211         std::map<int32_t, MissionStatus> missionList;
212         for (auto mission : missions) {
213             MissionStatus status;
214             ConvertToMissionStatus(mission, accountId, status);
215             HILOGD("mission %{public}d status: %{public}s", mission.id, status.ToString().c_str());
216             missionList[mission.id] = status;
217         }
218 
219         if (focusedMissionId > 0 && missionList.count(focusedMissionId) != 0) {
220             missionList[focusedMissionId].isFocused = true;
221         }
222         missionMap_[accountId] = missionList;
223     }
224 
225     lastContinuableMissionId_ = 0;
226     HILOGI("InitMissionStatus for user %{public}d end", accountId);
227     return;
228 }
229 
GetMissionInfos(std::vector<AAFwk::MissionInfo> & missions)230 int32_t DmsContinueConditionMgr::GetMissionInfos(std::vector<AAFwk::MissionInfo>& missions)
231 {
232     auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance();
233     if (abilityMgr == nullptr) {
234         HILOGE("abilityMgr is null");
235         return INVALID_PARAMETERS_ERR;
236     }
237     int32_t ret = abilityMgr->Connect();
238     if (ret != ERR_OK) {
239         HILOGE("get ability server failed, ret = %{public}d", ret);
240         return ret;
241     }
242     return abilityMgr->GetMissionInfos("", GET_MAX_MISSIONS, missions);
243 }
244 
OnMissionFocused(int32_t accountId,int32_t missionId)245 int32_t DmsContinueConditionMgr::OnMissionFocused(int32_t accountId, int32_t missionId)
246 {
247     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
248 
249     AAFwk::MissionInfo info;
250     int32_t ret = GetMissionInfo(missionId, info);
251     if (ret != ERR_OK) {
252         HILOGE("GetMissionInfo failed, missionId %{public}d, ret %{public}d", missionId, ret);
253         return ret;
254     }
255 
256     {
257         HILOGI("new mission %{public}d focused, add record", missionId);
258         std::lock_guard<std::mutex> missionlock(missionMutex_);
259         MissionStatus status;
260         ConvertToMissionStatus(info, accountId, status);
261         CleanLastFocusedFlagLocked(accountId, missionId);
262         status.isFocused = true;
263         HILOGD("mission %{public}d status: %{public}s", missionId, status.ToString().c_str());
264         missionMap_[accountId][missionId] = status;
265     }
266     return ERR_OK;
267 }
268 
GetMissionInfo(int32_t missionId,AAFwk::MissionInfo & info)269 int32_t DmsContinueConditionMgr::GetMissionInfo(int32_t missionId, AAFwk::MissionInfo& info)
270 {
271     auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance();
272     if (abilityMgr == nullptr) {
273         HILOGE("abilityMgr is null");
274         return INVALID_PARAMETERS_ERR;
275     }
276     int32_t ret = abilityMgr->Connect();
277     if (ret != ERR_OK) {
278         HILOGE("get ability server failed, ret = %{public}d", ret);
279         return ret;
280     }
281     return abilityMgr->GetMissionInfo("", missionId, info);
282 }
283 
ConvertToMissionStatus(const AAFwk::MissionInfo & missionInfo,int32_t accountId,MissionStatus & status)284 void DmsContinueConditionMgr::ConvertToMissionStatus(const AAFwk::MissionInfo& missionInfo,
285     int32_t accountId, MissionStatus& status)
286 {
287     status.accountId = accountId;
288     status.missionId = missionInfo.id;
289     status.bundleName = missionInfo.want.GetElement().GetBundleName();
290     status.moduleName = missionInfo.want.GetElement().GetModuleName();
291     status.abilityName = missionInfo.want.GetElement().GetAbilityName();
292     status.isContinuable = missionInfo.continuable;
293     status.launchFlag = missionInfo.want.GetFlags();
294     status.continueState = missionInfo.continueState;
295     return;
296 }
297 
CleanLastFocusedFlagLocked(int32_t accountId,int32_t missionId)298 void DmsContinueConditionMgr::CleanLastFocusedFlagLocked(int32_t accountId, int32_t missionId)
299 {
300     for (auto& record : missionMap_[accountId]) {
301         if (record.first != missionId && record.second.isFocused) {
302             HILOGI("new mission %{public}d focused, mission %{public}d lose focus", missionId, record.first);
303             record.second.isFocused = false;
304         }
305     }
306     return;
307 }
308 
OnMissionUnfocused(int32_t accountId,int32_t missionId)309 int32_t DmsContinueConditionMgr::OnMissionUnfocused(int32_t accountId, int32_t missionId)
310 {
311     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
312 
313     std::lock_guard<std::mutex> missionlock(missionMutex_);
314     if (!IsMissionStatusExistLocked(accountId, missionId)) {
315         HILOGW("mission %{public}d under user %{public}d not exist", missionId, accountId);
316         return CONDITION_INVALID_MISSION_ID;
317     }
318     missionMap_[accountId][missionId].isFocused = false;
319     HILOGI("missionMap update finished! status: %{public}s", missionMap_[accountId][missionId].ToString().c_str());
320     return ERR_OK;
321 }
322 
OnMissionBackground(int32_t accountId,int32_t missionId)323 int32_t DmsContinueConditionMgr::OnMissionBackground(int32_t accountId, int32_t missionId)
324 {
325     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
326 
327     std::lock_guard<std::mutex> missionlock(missionMutex_);
328     if (!IsMissionStatusExistLocked(accountId, missionId)) {
329         HILOGW("mission %{public}d under user %{public}d not exist", missionId, accountId);
330         return CONDITION_INVALID_MISSION_ID;
331     }
332     missionMap_[accountId][missionId].isFocused = false;
333     HILOGI("missionMap update finished! status: %{public}s", missionMap_[accountId][missionId].ToString().c_str());
334     return ERR_OK;
335 }
336 
OnMissionDestory(int32_t accountId,int32_t missionId)337 int32_t DmsContinueConditionMgr::OnMissionDestory(int32_t accountId, int32_t missionId)
338 {
339     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
340 
341     std::lock_guard<std::mutex> missionlock(missionMutex_);
342     if (!IsMissionStatusExistLocked(accountId, missionId)) {
343         HILOGW("mission %{public}d under user %{public}d not exist", missionId, accountId);
344         return ERR_OK;
345     }
346     missionMap_[accountId].erase(missionId);
347     HILOGI("missionMap update finished!");
348     return ERR_OK;
349 }
350 
OnMissionActive(int32_t accountId,int32_t missionId)351 int32_t DmsContinueConditionMgr::OnMissionActive(int32_t accountId, int32_t missionId)
352 {
353     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
354 
355     std::lock_guard<std::mutex> missionlock(missionMutex_);
356     if (!IsMissionStatusExistLocked(accountId, missionId)) {
357         HILOGW("mission %{public}d under user %{public}d not exist", missionId, accountId);
358         return ERR_OK;
359     }
360     missionMap_[accountId][missionId].continueState = AAFwk::ContinueState::CONTINUESTATE_ACTIVE;
361     HILOGI("missionMap update finished! status: %{public}s", missionMap_[accountId][missionId].ToString().c_str());
362     return ERR_OK;
363 }
364 
OnMissionInactive(int32_t accountId,int32_t missionId)365 int32_t DmsContinueConditionMgr::OnMissionInactive(int32_t accountId, int32_t missionId)
366 {
367     HILOGI("accountId %{public}d, missionId %{public}d", accountId, missionId);
368 
369     std::lock_guard<std::mutex> missionlock(missionMutex_);
370     if (!IsMissionStatusExistLocked(accountId, missionId)) {
371         HILOGW("mission %{public}d under user %{public}d not exist", missionId, accountId);
372         return ERR_OK;
373     }
374     missionMap_[accountId][missionId].continueState = AAFwk::ContinueState::CONTINUESTATE_INACTIVE;
375     HILOGI("missionMap update finished! status: %{public}s", missionMap_[accountId][missionId].ToString().c_str());
376     return ERR_OK;
377 }
378 
CheckSystemSendCondition()379 bool DmsContinueConditionMgr::CheckSystemSendCondition()
380 {
381     HILOGI("switch: %{public}d, wifi: %{public}d, bt: %{public}d",
382         isSwitchOn_.load(), isWifiActive_.load(), isBtActive_.load());
383 
384     std::string reason = "";
385     do {
386         if (!isSwitchOn_) {
387             reason = "CONTINUE_SWITCH_OFF";
388             break;
389         }
390 #ifdef DMS_CHECK_WIFI
391         if (!isWifiActive_) {
392             reason = "WIFI_INACTIVE";
393             break;
394         }
395 #endif
396 #ifdef DMS_CHECK_BLUETOOTH
397         if (!isBtActive_) {
398             reason = "BLUETOOTH_INACTIVE";
399             break;
400         }
401 #endif
402         HILOGI("PASS");
403         return true;
404     } while (0);
405 
406     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
407     return false;
408 }
409 
CheckMissionSendCondition(const MissionStatus & status,MissionEventType type)410 bool DmsContinueConditionMgr::CheckMissionSendCondition(const MissionStatus& status, MissionEventType type)
411 {
412     HILOGI("missionId %{public}d, type %{public}s", status.missionId, TypeEnumToString(type).c_str());
413     auto iterFunc = conditionFuncMap_.find(type);
414     if (iterFunc == conditionFuncMap_.end()) {
415         HILOGE("invalid system status");
416         return false;
417     }
418 
419     auto memberFunc = iterFunc->second;
420     return (this->*memberFunc)(status);
421 }
422 
CheckSendFocusedCondition(const MissionStatus & status)423 bool DmsContinueConditionMgr::CheckSendFocusedCondition(const MissionStatus& status)
424 {
425     HILOGI("missionId %{public}d", status.missionId);
426 
427     std::string reason = "";
428     do {
429         if (!status.isContinuable) {
430             reason = "NOT_CONTINUABLE";
431             break;
432         }
433         if (status.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
434             reason = "CONTINUE_STATE_INACTIVE";
435             break;
436         }
437         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
438             reason = "MDM_CONTROL";
439             break;
440         }
441         lastContinuableMissionId_ = status.missionId;
442         HILOGI("PASS");
443         return true;
444     } while (0);
445 
446     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
447     return false;
448 }
449 
CheckSendUnfocusedCondition(const MissionStatus & status)450 bool DmsContinueConditionMgr::CheckSendUnfocusedCondition(const MissionStatus& status)
451 {
452     HILOGI("missionId %{public}d", status.missionId);
453 
454     std::string reason = "";
455     do {
456         if (!status.isFocused) {
457             reason = "NOT_FOCUSED";
458             break;
459         }
460         if (!status.isContinuable) {
461             reason = "NOT_CONTINUABLE";
462             break;
463         }
464         if (status.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
465             reason = "CONTINUE_STATE_INACTIVE";
466             break;
467         }
468         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
469             reason = "MDM_CONTROL";
470             break;
471         }
472         HILOGI("PASS");
473         return true;
474     } while (0);
475 
476     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
477     return false;
478 }
479 
CheckSendBackgroundCondition(const MissionStatus & status)480 bool DmsContinueConditionMgr::CheckSendBackgroundCondition(const MissionStatus& status)
481 {
482     HILOGI("missionId %{public}d", status.missionId);
483 
484     std::string reason = "";
485     do {
486         if (!status.isContinuable) {
487             reason = "NOT_CONTINUABLE";
488             break;
489         }
490         if (status.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
491             reason = "CONTINUE_STATE_INACTIVE";
492             break;
493         }
494         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
495             reason = "MDM_CONTROL";
496             break;
497         }
498         HILOGI("PASS");
499         return true;
500     } while (0);
501 
502     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
503     return false;
504 }
505 
CheckSendActiveCondition(const MissionStatus & status)506 bool DmsContinueConditionMgr::CheckSendActiveCondition(const MissionStatus& status)
507 {
508     HILOGI("missionId %{public}d", status.missionId);
509 
510     std::string reason = "";
511     do {
512         if (!status.isFocused) {
513             reason = "NOT_FOCUSED";
514             break;
515         }
516         if (!status.isContinuable) {
517             reason = "NOT_CONTINUABLE";
518             break;
519         }
520         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
521             reason = "MDM_CONTROL";
522             break;
523         }
524         lastContinuableMissionId_ = status.missionId;
525         HILOGI("PASS");
526         return true;
527     } while (0);
528 
529     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
530     return false;
531 }
532 
CheckSendInactiveCondition(const MissionStatus & status)533 bool DmsContinueConditionMgr::CheckSendInactiveCondition(const MissionStatus& status)
534 {
535     HILOGI("missionId %{public}d", status.missionId);
536 
537     std::string reason = "";
538     do {
539         MissionStatus currenFocusedMission;
540         GetCurrentFocusedMission(status.accountId, currenFocusedMission);
541         if (currenFocusedMission.missionId != CONDITION_INVALID_MISSION_ID && currenFocusedMission.isContinuable
542             && currenFocusedMission.missionId != status.missionId) {
543             HILOGE("Current focused mission id: %{public}d", currenFocusedMission.missionId);
544             reason = "OTHER_MISSION_FOCUSED";
545             break;
546         }
547         if (!status.isContinuable) {
548             reason = "NOT_CONTINUABLE";
549             break;
550         }
551         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
552             reason = "MDM_CONTROL";
553             break;
554         }
555         HILOGI("PASS");
556         return true;
557     } while (0);
558 
559     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
560     return false;
561 }
562 
CheckSendContinueSwitchOffCondition(const MissionStatus & status)563 bool DmsContinueConditionMgr::CheckSendContinueSwitchOffCondition(const MissionStatus& status)
564 {
565     HILOGI("missionId %{public}d", status.missionId);
566 
567     std::string reason = "";
568     do {
569         if (!status.isContinuable) {
570             reason = "NOT_CONTINUABLE";
571             break;
572         }
573         if (status.continueState != AAFwk::ContinueState::CONTINUESTATE_ACTIVE) {
574             reason = "CONTINUE_STATE_INACTIVE";
575             break;
576         }
577         if (DmsKvSyncE2E::GetInstance()->CheckMDMCtrlRule(status.bundleName)) {
578             reason = "MDM_CONTROL";
579             break;
580         }
581         HILOGI("PASS");
582         return true;
583     } while (0);
584 
585     HILOGE("FAILED, Reason: %{public}s", reason.c_str());
586     return false;
587 }
588 
GetMissionStatus(int32_t accountId,int32_t missionId,MissionStatus & status)589 int32_t DmsContinueConditionMgr::GetMissionStatus(int32_t accountId, int32_t missionId, MissionStatus& status)
590 {
591     std::lock_guard<std::mutex> missionlock(missionMutex_);
592     if (!IsMissionStatusExistLocked(accountId, missionId)) {
593         HILOGE("mission %{public}d under user %{public}d not exist", missionId, accountId);
594         return INVALID_PARAMETERS_ERR;
595     }
596 
597     status = missionMap_[accountId][missionId];
598     return ERR_OK;
599 }
600 
IsMissionStatusExistLocked(int32_t accountId,int32_t missionId)601 bool DmsContinueConditionMgr::IsMissionStatusExistLocked(int32_t accountId, int32_t missionId)
602 {
603     if (missionMap_.count(accountId) == 0 || missionMap_[accountId].count(missionId) == 0) {
604         return false;
605     }
606     return true;
607 }
608 
IsScreenLocked()609 bool DmsContinueConditionMgr::IsScreenLocked()
610 {
611     return isScreenLocked_.load();
612 }
613 
GetMissionIdByBundleName(int32_t accountId,const std::string & bundleName,int32_t & missionId)614 int32_t DmsContinueConditionMgr::GetMissionIdByBundleName(
615     int32_t accountId, const std::string& bundleName, int32_t& missionId)
616 {
617     std::lock_guard<std::mutex> missionlock(missionMutex_);
618     if (missionMap_.count(accountId) == 0) {
619         HILOGE("user %{public}d not exist!", accountId);
620         return MISSION_NOT_FOCUSED;
621     }
622 
623     for (const auto& record : missionMap_[accountId]) {
624         if (record.second.isFocused) {
625             missionId = record.first;
626             break;
627         }
628     }
629     HILOGI("GetMissionIdByBundleName current focused missionId: %{public}d", missionId);
630     MissionStatus missionStatus = missionMap_[accountId][missionId];
631     if (missionStatus.bundleName == bundleName && missionStatus.isContinuable) {
632         HILOGI("GetMissionIdByBundleName got missionId: %{public}d", missionId);
633         return ERR_OK;
634     }
635     HILOGW("GetMissionIdByBundleName current focused missionId(%{public}d) "
636            "is not belong to bundle: %{public}s; or it's isContinuable is %{public}s. "
637            "try to get last focused mission id",
638         missionId, bundleName.c_str(), missionStatus.isContinuable ? "true" : "false");
639     auto iter = missionMap_[accountId].find(lastContinuableMissionId_);
640     if (iter != missionMap_[accountId].end()) {
641         if (lastContinuableMissionId_ != 0 &&
642             missionMap_[accountId][lastContinuableMissionId_].bundleName == bundleName) {
643             missionId = lastContinuableMissionId_;
644             HILOGI("GetMissionIdByBundleName got lastContinuableMissionId: %{public}d, "
645                    "lastContinuableBundleName: %{public}s",
646                 missionId, missionMap_[accountId][lastContinuableMissionId_].bundleName.c_str());
647             return ERR_OK;
648         }
649     }
650 
651     HILOGE("GetMissionIdByBundleName lastContinuableMissionId(%{public}d) "
652            "is not belong to bundle: %{public}s.",
653            missionId, bundleName.c_str());
654     return MISSION_NOT_FOCUSED;
655 }
656 
GetCurrentFocusedMission(int32_t accountId)657 int32_t DmsContinueConditionMgr::GetCurrentFocusedMission(int32_t accountId)
658 {
659     int32_t missionId = CONDITION_INVALID_MISSION_ID;
660     {
661         std::lock_guard<std::mutex> missionlock(missionMutex_);
662         if (missionMap_.count(accountId) == 0) {
663             HILOGE("user %{public}d not exist!", accountId);
664             return missionId;
665         }
666         for (const auto& record : missionMap_[accountId]) {
667             if (record.second.isFocused) {
668                 missionId = record.first;
669                 break;
670             }
671         }
672     }
673     return missionId;
674 }
675 
GetCurrentFocusedMission(int32_t accountId,MissionStatus & missionStatus)676 int32_t DmsContinueConditionMgr::GetCurrentFocusedMission(int32_t accountId, MissionStatus &missionStatus)
677 {
678     int32_t missionId = CONDITION_INVALID_MISSION_ID;
679     missionStatus.missionId = CONDITION_INVALID_MISSION_ID;
680     {
681         std::lock_guard<std::mutex> missionlock(missionMutex_);
682         if (missionMap_.count(accountId) == 0) {
683             HILOGE("user %{public}d not exist!", accountId);
684             return missionId;
685         }
686         for (const auto& record : missionMap_[accountId]) {
687             if (record.second.isFocused) {
688                 missionId = record.first;
689                 missionStatus = record.second;
690                 break;
691             }
692         }
693     }
694     return missionId;
695 }
696 
TypeEnumToString(MissionEventType type)697 std::string DmsContinueConditionMgr::TypeEnumToString(MissionEventType type)
698 {
699     switch (type) {
700         case MISSION_EVENT_FOCUSED:
701             return "FOCUSED";
702         case MISSION_EVENT_UNFOCUSED:
703             return "UNFOCUSED";
704         case MISSION_EVENT_DESTORYED:
705             return "DESTORYED";
706         case MISSION_EVENT_ACTIVE:
707             return "ACTIVE";
708         case MISSION_EVENT_INACTIVE:
709             return "INACTIVE";
710         case MISSION_EVENT_TIMEOUT:
711             return "TIMEOUT";
712         case MISSION_EVENT_MMI:
713             return "MMI";
714         case MISSION_EVENT_BACKGROUND:
715             return "BACKGROUND";
716         case MISSION_EVENT_CONTINUE_SWITCH_OFF:
717             return "CONTINUE_SWITCH_OFF";
718         default:
719             return "UNDEFINED";
720     }
721 }
722 
GetLastContinuableMissionId()723 int32_t DmsContinueConditionMgr::GetLastContinuableMissionId()
724 {
725     return lastContinuableMissionId_;
726 }
727 } // namespace DistributedSchedule
728 } // namespace OHOS
729