diff --git a/frameworks/include/background_task_manager.h b/frameworks/include/background_task_manager.h index c4b7e1228f7336616dbc1978413a4092d76750ac..67ed519810130e9c24be40694f4a13add86c86b8 100644 --- a/frameworks/include/background_task_manager.h +++ b/frameworks/include/background_task_manager.h @@ -258,6 +258,15 @@ public: */ ErrCode SetBgTaskConfig(const std::string &configData, int32_t sourceType); + /** + * @brief Request suspend continuous audio play back task. + * @param uid app uid. + * @param pid app pid. + * @param reason continuous task suspend reason. + * @return Returns ERR_OK if success, else failure. + */ + ErrCode SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason); + private: bool GetBackgroundTaskManagerProxy(); diff --git a/frameworks/src/background_task_manager.cpp b/frameworks/src/background_task_manager.cpp index c3ea7c8dd8cc242c77b46d292cea225d33421b3a..6492a7a715cda85336a7266fbbe62ba6eeffcebd 100644 --- a/frameworks/src/background_task_manager.cpp +++ b/frameworks/src/background_task_manager.cpp @@ -464,6 +464,14 @@ ErrCode BackgroundTaskManager::SetBgTaskConfig(const std::string &configData, in return proxy_->SetBgTaskConfig(configData, sourceType); } +ErrCode BackgroundTaskManager::SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason) +{ + std::lock_guard lock(mutex_); + GET_BACK_GROUND_TASK_MANAGER_PROXY_RETURN + + return proxy_->SuspendContinuousAudioPlayBackTask(uid, pid, reason); +} + BackgroundTaskManager::BgTaskMgrDeathRecipient::BgTaskMgrDeathRecipient(BackgroundTaskManager &backgroundTaskManager) : backgroundTaskManager_(backgroundTaskManager) {} diff --git a/frameworks/test/unittest/bgtask_framework_abnormal_unit_test.cpp b/frameworks/test/unittest/bgtask_framework_abnormal_unit_test.cpp index 2a46ab3d6c54bfe8857c2ea84c3abb27361b3093..19b964f4f98e4a9defbb65118565188a9223552b 100644 --- a/frameworks/test/unittest/bgtask_framework_abnormal_unit_test.cpp +++ b/frameworks/test/unittest/bgtask_framework_abnormal_unit_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -649,5 +649,26 @@ HWTEST_F(BgTaskFrameworkAbnormalUnitTest, BackgroundTaskMgrProxyAbnormalTest_019 MessageParcelHelper::BgTaskFwkAbnormalSetWriteReadInt32WithParamFlag(false); EXPECT_EQ(backgroundTaskMgrProxy.ActiveContinuousTask(1, 1, ""), ERR_INVALID_DATA); } + +/** + * @tc.name: BackgroundTaskMgrProxyAbnormalTest_020 + * @tc.desc: test BackgroundTaskMgrProxy abnormal. + * @tc.type: FUNC + * @tc.require: issueIC6B53 + */ +HWTEST_F(BgTaskFrameworkAbnormalUnitTest, BackgroundTaskMgrProxyAbnormalTest_020, TestSize.Level2) +{ + BackgroundTaskMgrProxy backgroundTaskMgrProxy = BackgroundTaskMgrProxy(nullptr); + + MessageParcelHelper::BgTaskFwkAbnormalSetWriteInterfaceTokenFlag(false); + EXPECT_EQ(backgroundTaskMgrProxy.SuspendContinuousAudioPlayBackTask(1, 1, 1), ERR_INVALID_VALUE); + + MessageParcelHelper::BgTaskFwkAbnormalSetWriteInterfaceTokenFlag(true); + MessageParcelHelper::BgTaskFwkAbnormalSetWriteInt32WithParamFlag(false); + EXPECT_EQ(backgroundTaskMgrProxy.SuspendContinuousAudioPlayBackTask(1, 1, 1), ERR_INVALID_DATA); + + MessageParcelHelper::BgTaskFwkAbnormalSetWriteInt32WithParamFlag(true); + EXPECT_EQ(backgroundTaskMgrProxy.SuspendContinuousAudioPlayBackTask(1, 1, 1), ERR_INVALID_DATA); +} } } diff --git a/frameworks/test/unittest/bgtask_framework_unit_test.cpp b/frameworks/test/unittest/bgtask_framework_unit_test.cpp index 8fb953e369964febd5bcf2e53c6fb6e96e359131..8bcef6076208a6e3b29bbdda160d6909b8c734ca 100644 --- a/frameworks/test/unittest/bgtask_framework_unit_test.cpp +++ b/frameworks/test/unittest/bgtask_framework_unit_test.cpp @@ -445,6 +445,24 @@ HWTEST_F(BgTaskFrameworkUnitTest, BgTaskFrameworkUnitTest_019, TestSize.Level1) ERR_BGTASK_PERMISSION_DENIED); } +/** + * @tc.name: BgTaskFrameworkUnitTest_020 + * @tc.desc: test SuspendContinuousAudioPlayBackTask. + * @tc.type: FUNC + * @tc.require: issueIC6B53 + */ +HWTEST_F(BgTaskFrameworkUnitTest, BgTaskFrameworkUnitTest_020, TestSize.Level1) +{ + DelayedSingleton::GetInstance()->proxy_ = nullptr; + SystemAbilityManagerClient::GetInstance().action_ = "set_null"; + EXPECT_EQ(DelayedSingleton::GetInstance()->SuspendContinuousAudioPlayBackTask(1, 1, 4), + ERR_BGTASK_SERVICE_NOT_CONNECTED); + + SystemAbilityManagerClient::GetInstance().action_ = ""; + EXPECT_EQ(DelayedSingleton::GetInstance()->SuspendContinuousAudioPlayBackTask(1, 1, 4), + ERR_BGTASK_PERMISSION_DENIED); +} + /** * @tc.name: BackgroundTaskSubscriberProxyTest_001 * @tc.desc: test BackgroundTaskSubscriberProxy. diff --git a/interfaces/innerkits/BUILD.gn b/interfaces/innerkits/BUILD.gn index 5995d31487518f52c6cc31872b005a7fbce09e71..4f864ff140f53fdc6a1e52468c01a3e4e5ae9f0c 100644 --- a/interfaces/innerkits/BUILD.gn +++ b/interfaces/innerkits/BUILD.gn @@ -64,6 +64,7 @@ ohos_shared_library("bgtaskmgr_innerkits") { "src/continuous_task_callback_info.cpp", "src/continuous_task_info.cpp", "src/continuous_task_param.cpp", + "src/continuous_task_suspend_reason.cpp", "src/delay_suspend_info.cpp", "src/efficiency_resource_info.cpp", "src/expired_callback.cpp", diff --git a/interfaces/innerkits/IBackgroundTaskMgr.idl b/interfaces/innerkits/IBackgroundTaskMgr.idl index e5c98131ee80a8b31172b83d455c86324eeb0451..c019361d3f2840c29d0c3284bba3dc19e87c23bd 100644 --- a/interfaces/innerkits/IBackgroundTaskMgr.idl +++ b/interfaces/innerkits/IBackgroundTaskMgr.idl @@ -52,4 +52,5 @@ interface OHOS.BackgroundTaskMgr.IBackgroundTaskMgr { void StartTransientTaskTimeForInner([in] int uid); void AVSessionNotifyUpdateNotification([in] int uid, [in] int pid, [in] boolean isPublish); void SetBgTaskConfig([in] String configData, [in] int sourceType); + void SuspendContinuousAudioPlayBackTask([in] int uid, [in] int pid, [in] int reason); } diff --git a/interfaces/innerkits/include/background_task_mgr_helper.h b/interfaces/innerkits/include/background_task_mgr_helper.h index a5ff46ed95645a04e02e0f2665ef954ba75aea7c..e852a0d6f2c265791dee0632bbfc33ec612e1799 100644 --- a/interfaces/innerkits/include/background_task_mgr_helper.h +++ b/interfaces/innerkits/include/background_task_mgr_helper.h @@ -200,6 +200,15 @@ public: * @return Returns ERR_OK if success, else failure. */ static ErrCode SetBgTaskConfig(const std::string &configData, int32_t sourceType); + + /** + * @brief Request suspend continuous audio play back task. + * @param uid app uid. + * @param pid app pid. + * @param reason continuous task suspend reason. + * @return Returns ERR_OK if success, else failure. + */ + static ErrCode SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason); }; } // namespace BackgroundTaskMgr } // namespace OHOS diff --git a/interfaces/innerkits/include/continuous_task_suspend_reason.h b/interfaces/innerkits/include/continuous_task_suspend_reason.h index daff7a5aa545917b0f3e6a181dc2f672ae41cce3..f93444eae96cec8483e2d686446a7573af56c22d 100644 --- a/interfaces/innerkits/include/continuous_task_suspend_reason.h +++ b/interfaces/innerkits/include/continuous_task_suspend_reason.h @@ -1,4 +1,4 @@ - /* +/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,26 +13,29 @@ * limitations under the License. */ - #ifndef FOUNDATION_RESOURCESCHEDULE_BACKGROUND_TASK_MGR_INTERFACES_INNERKITS_INCLUDE_CONTINUOUS_TASK_SUSPEND_REASON_H - #define FOUNDATION_RESOURCESCHEDULE_BACKGROUND_TASK_MGR_INTERFACES_INNERKITS_INCLUDE_CONTINUOUS_TASK_SUSPEND_REASON_H - - namespace OHOS { - namespace BackgroundTaskMgr { - class ContinuousTaskSuspendReason { - public: - virtual ~ContinuousTaskSuspendReason() = default; - enum Type : uint32_t { - SYSTEM_SUSPEND_DATA_TRANSFER_LOW_SPEED = 4, - SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_USE_AVSESSION, - SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_RUNNING, - SYSTEM_SUSPEND_AUDIO_RECORDING_NOT_RUNNING, - SYSTEM_SUSPEND_LOCATION_NOT_USED, - SYSTEM_SUSPEND_BLUETOOTH_NOT_USED, - SYSTEM_SUSPEND_MULTI_DEVICE_NOT_USED, - SYSTEM_SUSPEND_USED_ILLEGALLY, - SYSTEM_SUSPEND_SYSTEM_LOAD_WARNING, - }; - }; - } // namespace BackgroundTaskMgr - } // namespace OHOS - #endif \ No newline at end of file +#ifndef FOUNDATION_RESOURCESCHEDULE_BACKGROUND_TASK_MGR_INTERFACES_INNERKITS_INCLUDE_CONTINUOUS_TASK_SUSPEND_REASON_H +#define FOUNDATION_RESOURCESCHEDULE_BACKGROUND_TASK_MGR_INTERFACES_INNERKITS_INCLUDE_CONTINUOUS_TASK_SUSPEND_REASON_H + +namespace OHOS { +namespace BackgroundTaskMgr { +class ContinuousTaskSuspendReason { +public: + virtual ~ContinuousTaskSuspendReason() = default; + enum Type : uint32_t { + SYSTEM_SUSPEND_DATA_TRANSFER_LOW_SPEED = 4, + SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_USE_AVSESSION, + SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_RUNNING, + SYSTEM_SUSPEND_AUDIO_RECORDING_NOT_RUNNING, + SYSTEM_SUSPEND_LOCATION_NOT_USED, + SYSTEM_SUSPEND_BLUETOOTH_NOT_USED, + SYSTEM_SUSPEND_MULTI_DEVICE_NOT_USED, + SYSTEM_SUSPEND_USED_ILLEGALLY, + SYSTEM_SUSPEND_SYSTEM_LOAD_WARNING, + ILLEGALLY_MODE = 99, + }; + + static uint32_t GetSuspendReasonValue(const uint32_t mode); +}; +} // namespace BackgroundTaskMgr +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/innerkits/libbgtaskmgr_innerkits.versionscript b/interfaces/innerkits/libbgtaskmgr_innerkits.versionscript index f0372a282168a8db54bb7ec182958636c745637a..f5ae276b0afdcdec5c766b9025f5323d6b60176a 100644 --- a/interfaces/innerkits/libbgtaskmgr_innerkits.versionscript +++ b/interfaces/innerkits/libbgtaskmgr_innerkits.versionscript @@ -20,6 +20,7 @@ *ContinuousTaskCallbackInfo*; *ContinuousTaskInfo*; *ContinuousTaskParam*; + *ContinuousTaskSuspendReason*; *DelaySuspendInfo*; *EfficiencyResourceInfo*; *ExpiredCallback*; diff --git a/interfaces/innerkits/src/background_task_mgr_helper.cpp b/interfaces/innerkits/src/background_task_mgr_helper.cpp index 320092898d0c47bd101b9b54708be00a0a440b41..185a65220252915b7133a1095dc3c3a3ef29020f 100644 --- a/interfaces/innerkits/src/background_task_mgr_helper.cpp +++ b/interfaces/innerkits/src/background_task_mgr_helper.cpp @@ -134,5 +134,10 @@ ErrCode BackgroundTaskMgrHelper::AVSessionNotifyUpdateNotification(int32_t uid, return DelayedSingleton::GetInstance()-> AVSessionNotifyUpdateNotification(uid, pid, isPublish); } + +ErrCode BackgroundTaskMgrHelper::SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason) +{ + return DelayedSingleton::GetInstance()->SuspendContinuousAudioPlayBackTask(uid, pid, reason); +} } // namespace BackgroundTaskMgr } // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/src/continuous_task_suspend_reason.cpp b/interfaces/innerkits/src/continuous_task_suspend_reason.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c31d2937e41ca4da46f8827dd73d2b72fd600e4a --- /dev/null +++ b/interfaces/innerkits/src/continuous_task_suspend_reason.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "background_mode.h" +#include "continuous_task_suspend_reason.h" + +namespace OHOS { +namespace BackgroundTaskMgr { +const std::unordered_map PARAM_SUSPEND_REASON = { + {BackgroundMode::DATA_TRANSFER, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_DATA_TRANSFER_LOW_SPEED}, + {BackgroundMode::AUDIO_PLAYBACK, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_RUNNING}, + {BackgroundMode::AUDIO_RECORDING, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_AUDIO_RECORDING_NOT_RUNNING}, + {BackgroundMode::LOCATION, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_LOCATION_NOT_USED}, + {BackgroundMode::BLUETOOTH_INTERACTION, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_BLUETOOTH_NOT_USED}, + {BackgroundMode::MULTI_DEVICE_CONNECTION, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_MULTI_DEVICE_NOT_USED}, + {BackgroundMode::VOIP, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_AUDIO_PLAYBACK_NOT_RUNNING}, + {ContinuousTaskSuspendReason::ILLEGALLY_MODE, ContinuousTaskSuspendReason::SYSTEM_SUSPEND_USED_ILLEGALLY} +}; + +uint32_t ContinuousTaskSuspendReason::GetSuspendReasonValue(const uint32_t mode) +{ + auto iter = PARAM_SUSPEND_REASON.find(mode); + if (iter != PARAM_SUSPEND_REASON.end()) { + return iter->second; + } + return 0; +} +} // namespace BackgroundTaskMgr +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/src/js_backgroundtask_subscriber.cpp b/interfaces/kits/napi/src/js_backgroundtask_subscriber.cpp index f4194b5fa6b926b956a6ed899a23430063d88d0d..27db21b2f670cf9f5da1709aaeaa7f3af682eb40 100644 --- a/interfaces/kits/napi/src/js_backgroundtask_subscriber.cpp +++ b/interfaces/kits/napi/src/js_backgroundtask_subscriber.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,7 +14,9 @@ */ #include "js_backgroundtask_subscriber.h" +#include "background_mode.h" #include "continuous_task_log.h" +#include "continuous_task_suspend_reason.h" #include "js_runtime_utils.h" #include "iservice_registry.h" #include "system_ability_definition.h" @@ -237,9 +239,13 @@ void JsBackgroundTaskSubscriber::HandleOnContinuousTaskSuspend( napi_set_named_property(env_, jsContinuousTaskSuspendInfo, "suspendState", suspendState); // set suspendReason - napi_value suspendReason = nullptr; - napi_create_int32(env_, continuousTaskCallbackInfo->GetSuspendReason(), &suspendReason); - napi_set_named_property(env_, jsContinuousTaskSuspendInfo, "suspendReason", suspendReason); + uint32_t mode = continuousTaskCallbackInfo->GetSuspendReason(); + if (mode < BackgroundMode::END || mode == ContinuousTaskSuspendReason::ILLEGALLY_MODE) { + uint32_t reason = ContinuousTaskSuspendReason::GetSuspendReasonValue(mode); + napi_value suspendReason = nullptr; + napi_create_int32(env_, reason, &suspendReason); + napi_set_named_property(env_, jsContinuousTaskSuspendInfo, "suspendReason", suspendReason); + } napi_value argv[1] = { jsContinuousTaskSuspendInfo }; napi_value callResult = nullptr; diff --git a/services/continuous_task/include/bg_continuous_task_mgr.h b/services/continuous_task/include/bg_continuous_task_mgr.h index 5de1673004e72885bc61805308378bbddca781db..4f03f91e768e8dc9aacc962807688b8fd628cbdb 100644 --- a/services/continuous_task/include/bg_continuous_task_mgr.h +++ b/services/continuous_task/include/bg_continuous_task_mgr.h @@ -106,6 +106,7 @@ public: void OnConfigurationChanged(const AppExecFwk::Configuration &configuration); void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId); void HandleRemoveTaskByMode(uint32_t mode); + void SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason); private: ErrCode StartBackgroundRunningInner(std::shared_ptr &continuousTaskRecordPtr); @@ -139,8 +140,8 @@ private: bool RegisterConfigurationObserver(); bool GetNotificationPrompt(); bool SetCachedBundleInfo(int32_t uid, int32_t userId, const std::string &bundleName, const std::string &appName); - void HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key); - void HandleSuspendContinuousTask(int32_t uid, int32_t pid, int32_t reason, const std::string &key); + void HandleSuspendContinuousTask(int32_t uid, int32_t reason); + void SuspendOrStopContinuousAudioTask(int32_t uid, int32_t reason); void HandleActiveContinuousTask(int32_t uid, int32_t pid, const std::string &key); void OnRemoteSubscriberDiedInner(const wptr &object); void OnContinuousTaskChanged(const std::shared_ptr continuousTaskInfo, @@ -161,7 +162,6 @@ private: std::shared_ptr GetBundleResMgr(const AppExecFwk::BundleInfo &bundleInfo); std::string GetMainAbilityLabel(const std::string &bundleName, int32_t userId); std::string GetNotificationText(const std::shared_ptr record); - void RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode); void RemoveContinuousTaskRecordByUid(int32_t uid); void ReclaimProcessMemory(int32_t pid); void SetReason(const std::string &mapKey, int32_t reason); diff --git a/services/continuous_task/include/continuous_task_record.h b/services/continuous_task/include/continuous_task_record.h index 70eff936dcf32946529ef10dcfd6d1fc2437fdd4..7466fe790302a2c913ebb3ae520c3da79aafa7ff 100644 --- a/services/continuous_task/include/continuous_task_record.h +++ b/services/continuous_task/include/continuous_task_record.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -61,6 +61,7 @@ public: bool ParseFromJson(const nlohmann::json &value); std::string ToString(std::vector &bgmodes); bool IsSystem() const; + int32_t GetSuspendAudioTaskTime() const; private: std::vector ToVector(std::string &str); @@ -89,6 +90,7 @@ private: int32_t continuousTaskId_ {-1}; bool suspendState_ {false}; int32_t suspendReason_ {0}; + int32_t suspendAudioTaskTime_ {0}; friend class BgContinuousTaskMgr; friend class NotificationTools; diff --git a/services/continuous_task/src/bg_continuous_task_mgr.cpp b/services/continuous_task/src/bg_continuous_task_mgr.cpp index 5350634ca225c3e9e1850be44f6a917b2ec0d65d..20f0509421e40309008ef17de17fea3f7b0bc17b 100644 --- a/services/continuous_task/src/bg_continuous_task_mgr.cpp +++ b/services/continuous_task/src/bg_continuous_task_mgr.cpp @@ -53,6 +53,7 @@ #endif // SUPPORT_GRAPHICS #include "background_mode.h" #include "background_sub_mode.h" +#include "continuous_task_suspend_reason.h" namespace OHOS { namespace BackgroundTaskMgr { @@ -100,7 +101,6 @@ static constexpr uint32_t HEALTHSPORT_SA_UID = 7500; #else static constexpr uint32_t HEALTHSPORT_SA_UID = 7259; #endif -static constexpr uint32_t ALL_MODES = 0xFF; #ifndef HAS_OS_ACCOUNT_PART constexpr int32_t DEFAULT_OS_ACCOUNT_ID = 0; // 0 is the default id when there is no os_account part @@ -1113,57 +1113,79 @@ ErrCode BgContinuousTaskMgr::GetAllContinuousTasksInner(int32_t uid, void BgContinuousTaskMgr::StopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key) { if (!isSysReady_.load()) { - BGTASK_LOGW("manager is not ready"); return; } auto self = shared_from_this(); auto task = [self, uid, pid, taskType, key]() { if (self) { - self->HandleStopContinuousTask(uid, pid, taskType, key); + self->RemoveContinuousTaskRecordByUid(uid); } }; handler_->PostTask(task); } -void BgContinuousTaskMgr::HandleStopContinuousTask(int32_t uid, int32_t pid, uint32_t taskType, const std::string &key) +void BgContinuousTaskMgr::SuspendContinuousTask(int32_t uid, int32_t pid, int32_t reason, const std::string &key) { - BGTASK_LOGI("StopContinuousTask taskType: %{public}d, key %{public}s", taskType, key.c_str()); - if (taskType == BackgroundMode::DATA_TRANSFER) { - RemoveContinuousTaskRecordByUidAndMode(uid, taskType); - return; - } - if (taskType == ALL_MODES) { - RemoveContinuousTaskRecordByUid(uid); - return; - } - if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) { + if (!isSysReady_.load()) { return; } - NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(), - continuousTaskInfosMap_[key]->GetNotificationId()); - SetReason(key, FREEZE_CANCEL); - RemoveContinuousTaskRecord(key); + auto self = shared_from_this(); + auto task = [self, uid, pid, reason, key]() { + if (self) { + if (self->IsExistCallback(uid, CONTINUOUS_TASK_SUSPEND)) { + self->HandleSuspendContinuousTask(uid, reason); + } else { + self->RemoveContinuousTaskRecordByUid(uid); + } + } + }; + handler_->PostTask(task); } -void BgContinuousTaskMgr::SuspendContinuousTask(int32_t uid, int32_t pid, int32_t reason, const std::string &key) +void BgContinuousTaskMgr::SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason) { if (!isSysReady_.load()) { BGTASK_LOGW("manager is not ready"); return; } auto self = shared_from_this(); - auto task = [self, uid, pid, reason, key]() { + auto task = [self, uid, pid, reason]() { if (self) { - if (self->IsExistCallback(uid, CONTINUOUS_TASK_SUSPEND)) { - self->HandleSuspendContinuousTask(uid, pid, reason, key); - } else { - self->HandleStopContinuousTask(uid, pid, 0, key); - } + self->SuspendOrStopContinuousAudioTask(uid, reason); } }; handler_->PostTask(task); } +void BgContinuousTaskMgr::SuspendOrStopContinuousAudioTask(int32_t uid, int32_t reason) +{ + auto iter = continuousTaskInfosMap_.begin(); + while (iter != continuousTaskInfosMap_.end()) { + if (iter->second->GetUid() == uid) { + NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(), + iter->second->GetNotificationId()); + if (IsExistCallback(uid, CONTINUOUS_TASK_SUSPEND) && iter->second->GetSuspendAudioTaskTime() == 0) { + BGTASK_LOGD("continuous audio play task suspend, key %{public}s", iter->first.c_str()); + iter->second->suspendState_ = true; + iter->second->suspendAudioTaskTime_ = 1; + iter->second->suspendReason_ = reason == ContinuousTaskSuspendReason::ILLEGALLY_MODE ? reason : + iter->second->bgModeId_; + OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_SUSPEND); + iter++; + } else if (IsExistCallback(uid, CONTINUOUS_TASK_SUSPEND) && iter->second->GetSuspendAudioTaskTime() == 1) { + BGTASK_LOGD("continuous audio play task remove, key %{public}s", iter->first.c_str()); + OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL); + iter = continuousTaskInfosMap_.erase(iter); + RefreshTaskRecord(); + } else { + iter++; + } + } else { + iter++; + } + } +} + bool BgContinuousTaskMgr::IsExistCallback(int32_t uid, uint32_t type) { for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) { @@ -1175,29 +1197,22 @@ bool BgContinuousTaskMgr::IsExistCallback(int32_t uid, uint32_t type) return false; } -void BgContinuousTaskMgr::HandleSuspendContinuousTask(int32_t uid, int32_t pid, int32_t reason, const std::string &key) +void BgContinuousTaskMgr::HandleSuspendContinuousTask(int32_t uid, int32_t reason) { - if (continuousTaskInfosMap_.find(key) == continuousTaskInfosMap_.end()) { - BGTASK_LOGW("suspend TaskInfo failure, no matched task: %{public}s", key.c_str()); - return; - } auto iter = continuousTaskInfosMap_.begin(); while (iter != continuousTaskInfosMap_.end()) { - if (iter->second->GetUid() != uid) { - ++iter; - continue; + if (iter->second->GetUid() == uid) { + BGTASK_LOGD("continuous task suspend, key %{public}s", iter->first.c_str()); + iter->second->suspendState_ = true; + iter->second->suspendReason_ = reason == ContinuousTaskSuspendReason::ILLEGALLY_MODE ? reason : + iter->second->bgModeId_; + NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(), + iter->second->GetNotificationId()); + OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_SUSPEND); + RefreshTaskRecord(); } - BGTASK_LOGW("SuspendContinuousTask reason: %{public}d, key %{public}s", reason, key.c_str()); - iter->second->suspendState_ = true; - iter->second->suspendReason_ = reason; - OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_SUSPEND); - RefreshTaskRecord(); - break; + iter++; } - // 暂停状态取消长时任务通知 - NotificationTools::GetInstance()->CancelNotification(continuousTaskInfosMap_[key]->GetNotificationLabel(), - continuousTaskInfosMap_[key]->GetNotificationId()); - // 对SA来说,暂停状态等同于取消 HandleAppContinuousTaskStop(uid); } @@ -1220,16 +1235,14 @@ void BgContinuousTaskMgr::HandleActiveContinuousTask(int32_t uid, int32_t pid, c { auto iter = continuousTaskInfosMap_.begin(); while (iter != continuousTaskInfosMap_.end()) { - if (iter->second->GetUid() != uid || !iter->second->suspendState_) { - ++iter; - continue; + if (iter->second->GetUid() == uid && iter->second->suspendState_) { + BGTASK_LOGD("continuous task active, key %{public}s", iter->first.c_str()); + iter->second->suspendState_ = false; + OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_ACTIVE); + SendContinuousTaskNotification(iter->second); + RefreshTaskRecord(); } - BGTASK_LOGI("ActiveContinuousTask uid: %{public}d, pid: %{public}d", uid, pid); - iter->second->suspendState_ = false; - OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_ACTIVE); - SendContinuousTaskNotification(iter->second); - RefreshTaskRecord(); - break; + iter++; } } @@ -1237,40 +1250,17 @@ void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUid(int32_t uid) { auto iter = continuousTaskInfosMap_.begin(); while (iter != continuousTaskInfosMap_.end()) { - if (iter->second->GetUid() != uid) { - ++iter; - continue; - } - BGTASK_LOGW("erase key %{public}s", iter->first.c_str()); - iter->second->reason_ = FREEZE_CANCEL; - OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL); - NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(), - iter->second->GetNotificationId()); - iter = continuousTaskInfosMap_.erase(iter); - RefreshTaskRecord(); - } - HandleAppContinuousTaskStop(uid); -} - -void BgContinuousTaskMgr::RemoveContinuousTaskRecordByUidAndMode(int32_t uid, uint32_t mode) -{ - auto iter = continuousTaskInfosMap_.begin(); - while (iter != continuousTaskInfosMap_.end()) { - if (iter->second->GetUid() != uid) { - ++iter; - continue; - } - auto findModeIter = std::find(iter->second->bgModeIds_.begin(), iter->second->bgModeIds_.end(), mode); - if (findModeIter == iter->second->bgModeIds_.end()) { - ++iter; - continue; + if (iter->second->GetUid() == uid) { + BGTASK_LOGD("continuous task remove, key %{public}s", iter->first.c_str()); + iter->second->reason_ = FREEZE_CANCEL; + NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(), + iter->second->GetNotificationId()); + OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL); + iter = continuousTaskInfosMap_.erase(iter); + RefreshTaskRecord(); + } else { + iter++; } - iter->second->reason_ = FREEZE_CANCEL; - OnContinuousTaskChanged(iter->second, ContinuousTaskEventTriggerType::TASK_CANCEL); - NotificationTools::GetInstance()->CancelNotification(iter->second->GetNotificationLabel(), - iter->second->GetNotificationId()); - iter = continuousTaskInfosMap_.erase(iter); - RefreshTaskRecord(); } HandleAppContinuousTaskStop(uid); } @@ -1831,9 +1821,12 @@ void BgContinuousTaskMgr::NotifySubscribersTaskSuspend( const ContinuousTaskCallbackInfo& taskCallbackInfoRef = *continuousTaskCallbackInfo; for (auto iter = bgTaskSubscribers_.begin(); iter != bgTaskSubscribers_.end(); ++iter) { if (!(*iter)->isHap_ && (*iter)->subscriber_) { - // 对SA来说,长时任务暂停状态等同于取消长时任务,保持原有逻辑 + // 对SA来说,长时任务暂停状态等同于取消长时任务,保持原有逻辑,播音任务不触发回调 BGTASK_LOGD("continuous task suspend callback trigger"); - (*iter)->subscriber_->OnContinuousTaskStop(taskCallbackInfoRef); + if (!CommonUtils::CheckExistMode(continuousTaskCallbackInfo->GetTypeIds(), + BackgroundMode::AUDIO_PLAYBACK)) { + (*iter)->subscriber_->OnContinuousTaskStop(taskCallbackInfoRef); + } } else if ((*iter)->isHap_ && (*iter)->uid_ == continuousTaskCallbackInfo->GetCreatorUid() && (*iter)->subscriber_) { // 回调通知应用长时任务暂停 diff --git a/services/continuous_task/src/continuous_task_record.cpp b/services/continuous_task/src/continuous_task_record.cpp index 23ae0d3d74e7f82e6190ef2f02ef721bbd995e0b..744f5bfb11ca87513c0cc4645968233741690634 100644 --- a/services/continuous_task/src/continuous_task_record.cpp +++ b/services/continuous_task/src/continuous_task_record.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -147,6 +147,11 @@ bool ContinuousTaskRecord::IsSystem() const return isSystem_; } +int32_t ContinuousTaskRecord::GetSuspendAudioTaskTime() const +{ + return suspendAudioTaskTime_; +} + std::string ContinuousTaskRecord::ParseToJsonStr() { nlohmann::json root; diff --git a/services/core/include/background_task_mgr_service.h b/services/core/include/background_task_mgr_service.h index e631ea1c288035fb2eb20c887e4c74d6c4d7516c..472de0f02a8d525e8d12f4fa485c1b15e1d1198c 100644 --- a/services/core/include/background_task_mgr_service.h +++ b/services/core/include/background_task_mgr_service.h @@ -93,6 +93,7 @@ public: ErrCode ActiveContinuousTask(int32_t uid, int32_t pid, const std::string &key) override; ErrCode AVSessionNotifyUpdateNotification(int32_t uid, int32_t pid, bool isPublish = false) override; ErrCode SetBgTaskConfig(const std::string &configData, int32_t sourceType) override; + ErrCode SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason) override; int32_t Dump(int32_t fd, const std::vector &args) override; void ForceCancelSuspendDelay(int32_t requestId); diff --git a/services/core/src/background_task_mgr_service.cpp b/services/core/src/background_task_mgr_service.cpp index 53504310c5de796169a580ea7681794544af982a..d663d9f2d772a98b1af1e5c347a10f27f116b49c 100644 --- a/services/core/src/background_task_mgr_service.cpp +++ b/services/core/src/background_task_mgr_service.cpp @@ -531,6 +531,15 @@ ErrCode BackgroundTaskMgrService::SetBgTaskConfig(const std::string &configData, return DelayedSingleton::GetInstance()->SetBgTaskConfig(configData, sourceType); } +ErrCode BackgroundTaskMgrService::SuspendContinuousAudioPlayBackTask(int32_t uid, int32_t pid, int32_t reason) +{ + if (!CheckCallingToken() || !CheckCallingProcess()) { + return ERR_BGTASK_PERMISSION_DENIED; + } + BgContinuousTaskMgr::GetInstance()->SuspendContinuousAudioPlayBackTask(uid, pid, reason); + return ERR_OK; +} + bool BackgroundTaskMgrService::CheckAtomicService() { uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID(); diff --git a/services/test/unittest/bg_continuous_task_mgr_test.cpp b/services/test/unittest/bg_continuous_task_mgr_test.cpp index b5e599a20f4a39fdc7bb7344c4c28727e5188875..52dbfa1be7de0c1de5bbfa013d23bdff4908e79d 100644 --- a/services/test/unittest/bg_continuous_task_mgr_test.cpp +++ b/services/test/unittest/bg_continuous_task_mgr_test.cpp @@ -801,60 +801,6 @@ HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_033, TestSize.Level1) #endif } -/** - * @tc.name: BgTaskManagerUnitTest_034 - * @tc.desc: test HandleStopContinuousTask. - * @tc.type: FUNC - * @tc.require: issueI5IRJK issueI4QT3W issueI4QU0V - */ -HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_034, TestSize.Level1) -{ - bgContinuousTaskMgr_->continuousTaskInfosMap_.clear(); - std::shared_ptr continuousTaskRecord1 = std::make_shared(); - continuousTaskRecord1->uid_ = TEST_NUM_ONE; - continuousTaskRecord1->bgModeId_ = TEST_NUM_ONE; - std::shared_ptr continuousTaskRecord2 = std::make_shared(); - continuousTaskRecord1->uid_ = TEST_NUM_ONE; - continuousTaskRecord1->bgModeId_ = TEST_NUM_TWO; - - bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; - bgContinuousTaskMgr_->continuousTaskInfosMap_["key2"] = continuousTaskRecord2; - bgContinuousTaskMgr_->HandleStopContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, TEST_NUM_ONE, ""); - EXPECT_NE((int32_t)bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); -} - -/** - * @tc.name: BgTaskManagerUnitTest_035 - * @tc.desc: test HandleStopContinuousTask. - * @tc.type: FUNC - * @tc.require: issueI5IRJK issueI4QT3W issueI4QU0V - */ -HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_035, TestSize.Level1) -{ - bgContinuousTaskMgr_->continuousTaskInfosMap_.clear(); - bgContinuousTaskMgr_->HandleStopContinuousTask(0, 0, 0, ""); - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); - - std::shared_ptr continuousTaskRecord1 = std::make_shared(); - continuousTaskRecord1->uid_ = 1; - continuousTaskRecord1->bgModeIds_ = {1}; - bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 1); - - bgContinuousTaskMgr_->HandleStopContinuousTask(1, 0, 1, ""); - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); - - bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 1); - bgContinuousTaskMgr_->HandleStopContinuousTask(1, 0, 0xFF, ""); - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); - - bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 1); - bgContinuousTaskMgr_->HandleStopContinuousTask(1, 0, 0, "key1"); - EXPECT_EQ(bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); -} - /** * @tc.name: BgTaskManagerUnitTest_036 * @tc.desc: test SubscriberChange. @@ -1132,10 +1078,10 @@ HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_051, TestSize.Level1) bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; bgContinuousTaskMgr_->continuousTaskInfosMap_["key2"] = continuousTaskRecord2; // 查不到对应的key值 - bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4, ""); + bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4); EXPECT_NE((int32_t)bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 0); // 查到对应的key值 - bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4, "key1"); + bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4); EXPECT_EQ((int32_t)bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 2); } @@ -1176,7 +1122,7 @@ HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_053, TestSize.Level1) bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; bgContinuousTaskMgr_->continuousTaskInfosMap_["key2"] = continuousTaskRecord2; // 暂停长时任务 - bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4, "key1"); + bgContinuousTaskMgr_->HandleSuspendContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, 4); EXPECT_EQ((int32_t)bgContinuousTaskMgr_->continuousTaskInfosMap_.size(), 2); // 恢复长时任务 bgContinuousTaskMgr_->HandleActiveContinuousTask(TEST_NUM_ONE, TEST_NUM_ONE, ""); @@ -1327,5 +1273,65 @@ HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_054, TestSize.Level1) bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord; EXPECT_EQ(bgContinuousTaskMgr_->SendContinuousTaskNotification(continuousTaskRecord), ERR_OK); } + +/** + * @tc.name: BgTaskManagerUnitTest_055 + * @tc.desc: test SuspendContinuousAudioPlayBackTask. + * @tc.type: FUNC + * @tc.require: issueIC6B53 + */ +HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_055, TestSize.Level1) +{ + bgContinuousTaskMgr_->continuousTaskInfosMap_.clear(); + bgContinuousTaskMgr_->isSysReady_.store(false); + bgContinuousTaskMgr_->SuspendContinuousAudioPlayBackTask(1, 1, 4); + bgContinuousTaskMgr_->isSysReady_.store(true); + bgContinuousTaskMgr_->SuspendContinuousAudioPlayBackTask(1, 1, 4); + SleepForFC(); + EXPECT_TRUE(bgContinuousTaskMgr_->continuousTaskInfosMap_.empty()); +} + +/** + * @tc.name: BgTaskManagerUnitTest_056 + * @tc.desc: test SuspendOrStopContinuousAudioTask. + * @tc.type: FUNC + * @tc.require: issueIC6B53 + */ +HWTEST_F(BgContinuousTaskMgrTest, BgTaskManagerUnitTest_056, TestSize.Level1) +{ + bgContinuousTaskMgr_->continuousTaskInfosMap_.clear(); + std::shared_ptr continuousTaskRecord1 = std::make_shared(); + continuousTaskRecord1->abilityName_ = "abilityName"; + continuousTaskRecord1->uid_ = 1; + continuousTaskRecord1->bgModeId_ = TEST_NUM_TWO; + continuousTaskRecord1->bgModeIds_.push_back(TEST_NUM_TWO); + continuousTaskRecord1->bgSubModeIds_.push_back(TEST_NUM_TWO); + continuousTaskRecord1->notificationId_ = 1; + continuousTaskRecord1->continuousTaskId_ = 1; + continuousTaskRecord1->abilityId_ = 1; + std::shared_ptr info = std::make_shared(); + info->bundleName_ = "wantAgentBundleName"; + info->abilityName_ = "wantAgentAbilityName"; + continuousTaskRecord1->wantAgentInfo_ = info; + bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"] = continuousTaskRecord1; + + bgContinuousTaskMgr_->SuspendOrStopContinuousAudioTask(2, 4); + EXPECT_FALSE(bgContinuousTaskMgr_->continuousTaskInfosMap_.empty()); + + bgContinuousTaskMgr_->SuspendOrStopContinuousAudioTask(1, 4); + EXPECT_FALSE(bgContinuousTaskMgr_->continuousTaskInfosMap_.empty()); + + auto subscriber = new (std::nothrow) TestBackgroundTaskSubscriber(); + EXPECT_NE(subscriber, nullptr); + auto infoSubscriber = std::make_shared(subscriber->GetImpl(), 1, 1, 1, 2); + EXPECT_EQ((int32_t)bgContinuousTaskMgr_->AddSubscriber(infoSubscriber), (int32_t)ERR_OK); + + bgContinuousTaskMgr_->SuspendOrStopContinuousAudioTask(1, 4); + int32_t suspendTime = bgContinuousTaskMgr_->continuousTaskInfosMap_["key1"]->GetSuspendAudioTaskTime(); + EXPECT_EQ(suspendTime, 1); + + bgContinuousTaskMgr_->SuspendOrStopContinuousAudioTask(1, 4); + EXPECT_TRUE(bgContinuousTaskMgr_->continuousTaskInfosMap_.empty()); +} } // namespace BackgroundTaskMgr } // namespace OHOS \ No newline at end of file