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