180922886Sopenharmony_ci/*
280922886Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
380922886Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
480922886Sopenharmony_ci * you may not use this file except in compliance with the License.
580922886Sopenharmony_ci * You may obtain a copy of the License at
680922886Sopenharmony_ci *
780922886Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
880922886Sopenharmony_ci *
980922886Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1080922886Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1180922886Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1280922886Sopenharmony_ci * See the License for the specific language governing permissions and
1380922886Sopenharmony_ci * limitations under the License.
1480922886Sopenharmony_ci */
1580922886Sopenharmony_ci
1680922886Sopenharmony_ci#include "background_audio_controller.h"
1780922886Sopenharmony_ci#include "avsession_log.h"
1880922886Sopenharmony_ci#include "avsession_service.h"
1980922886Sopenharmony_ci#include "avsession_item.h"
2080922886Sopenharmony_ci#include "permission_checker.h"
2180922886Sopenharmony_ci
2280922886Sopenharmony_cinamespace OHOS::AVSession {
2380922886Sopenharmony_ciusing AudioStandard::RendererState;
2480922886Sopenharmony_ci
2580922886Sopenharmony_ciBackgroundAudioController::BackgroundAudioController() : ptr_(nullptr)
2680922886Sopenharmony_ci{
2780922886Sopenharmony_ci    SLOGI("construct");
2880922886Sopenharmony_ci}
2980922886Sopenharmony_ci
3080922886Sopenharmony_ciBackgroundAudioController::~BackgroundAudioController()
3180922886Sopenharmony_ci{
3280922886Sopenharmony_ci    SLOGI("destroy");
3380922886Sopenharmony_ci}
3480922886Sopenharmony_ci
3580922886Sopenharmony_civoid BackgroundAudioController::Init(AVSessionService *ptr)
3680922886Sopenharmony_ci{
3780922886Sopenharmony_ci    ptr_ = ptr;
3880922886Sopenharmony_ci    AudioAdapter::GetInstance().AddStreamRendererStateListener([this](const auto& infos) {
3980922886Sopenharmony_ci        HandleAudioStreamRendererStateChange(infos);
4080922886Sopenharmony_ci    });
4180922886Sopenharmony_ci    AppManagerAdapter::GetInstance().SetAppStateChangeObserver([this](int32_t uid, int32_t pid, bool isBackground) {
4280922886Sopenharmony_ci        SLOGI("set background observe for uid=%{public}d, pid=%{public}d, isBackground=%{public}d",
4380922886Sopenharmony_ci            uid, pid, isBackground);
4480922886Sopenharmony_ci        HandleAppMuteState(uid, pid, isBackground);
4580922886Sopenharmony_ci    });
4680922886Sopenharmony_ci}
4780922886Sopenharmony_ci
4880922886Sopenharmony_civoid BackgroundAudioController::OnSessionCreate(const AVSessionDescriptor& descriptor)
4980922886Sopenharmony_ci{
5080922886Sopenharmony_ci    std::lock_guard lockGuard(lock_);
5180922886Sopenharmony_ci    sessionUIDs_.insert(descriptor.uid_);
5280922886Sopenharmony_ci    SLOGI("OnSessionCreate remove observe for uid %{public}d", descriptor.uid_);
5380922886Sopenharmony_ci    AppManagerAdapter::GetInstance().RemoveObservedApp(descriptor.uid_);
5480922886Sopenharmony_ci}
5580922886Sopenharmony_ci
5680922886Sopenharmony_civoid BackgroundAudioController::OnSessionRelease(const AVSessionDescriptor& descriptor)
5780922886Sopenharmony_ci{
5880922886Sopenharmony_ci    {
5980922886Sopenharmony_ci        std::lock_guard lockGuard(lock_);
6080922886Sopenharmony_ci        sessionUIDs_.erase(descriptor.uid_);
6180922886Sopenharmony_ci    }
6280922886Sopenharmony_ci
6380922886Sopenharmony_ci    if (descriptor.isThirdPartyApp_) {
6480922886Sopenharmony_ci        SLOGI("OnSessionRelease add observe for uid %{public}d", descriptor.uid_);
6580922886Sopenharmony_ci        AppManagerAdapter::GetInstance().AddObservedApp(descriptor.uid_);
6680922886Sopenharmony_ci        int32_t uid = descriptor.uid_;
6780922886Sopenharmony_ci        bool isRunning = AudioAdapter::GetInstance().GetRendererRunning(uid);
6880922886Sopenharmony_ci        if (!isRunning) {
6980922886Sopenharmony_ci            SLOGI("renderer state is not running when session release");
7080922886Sopenharmony_ci            return;
7180922886Sopenharmony_ci        }
7280922886Sopenharmony_ci        if (AppManagerAdapter::GetInstance().IsAppBackground(descriptor.uid_, descriptor.pid_)) {
7380922886Sopenharmony_ci            AudioAdapter::GetInstance().MuteAudioStream(descriptor.uid_);
7480922886Sopenharmony_ci            if (ptr_ != nullptr) {
7580922886Sopenharmony_ci                ptr_->NotifyAudioSessionCheckTrigger(descriptor.uid_);
7680922886Sopenharmony_ci            }
7780922886Sopenharmony_ci        }
7880922886Sopenharmony_ci    }
7980922886Sopenharmony_ci}
8080922886Sopenharmony_ci
8180922886Sopenharmony_ci// LCOV_EXCL_START
8280922886Sopenharmony_civoid BackgroundAudioController::HandleAudioStreamRendererStateChange(const AudioRendererChangeInfos& infos)
8380922886Sopenharmony_ci{
8480922886Sopenharmony_ci    for (const auto& info : infos) {
8580922886Sopenharmony_ci        if (info->rendererState != AudioStandard::RENDERER_RUNNING) {
8680922886Sopenharmony_ci            continue;
8780922886Sopenharmony_ci        }
8880922886Sopenharmony_ci        if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(info->clientUID)) {
8980922886Sopenharmony_ci            SLOGD("uid=%{public}d is system app", info->clientUID);
9080922886Sopenharmony_ci            continue;
9180922886Sopenharmony_ci        }
9280922886Sopenharmony_ci        SLOGI("AudioStreamRendererStateChange add observe for uid %{public}d", info->clientUID);
9380922886Sopenharmony_ci        AppManagerAdapter::GetInstance().AddObservedApp(info->clientUID);
9480922886Sopenharmony_ci
9580922886Sopenharmony_ci        if (HasAVSession(info->clientUID)) {
9680922886Sopenharmony_ci            continue;
9780922886Sopenharmony_ci        }
9880922886Sopenharmony_ci
9980922886Sopenharmony_ci        if (AppManagerAdapter::GetInstance().IsAppBackground(info->clientUID, info->clientPid)) {
10080922886Sopenharmony_ci            AudioAdapter::GetInstance().MuteAudioStream(info->clientUID);
10180922886Sopenharmony_ci            if (ptr_ != nullptr) {
10280922886Sopenharmony_ci                ptr_->NotifyAudioSessionCheckTrigger(info->clientUID);
10380922886Sopenharmony_ci            }
10480922886Sopenharmony_ci        } else {
10580922886Sopenharmony_ci            AudioAdapter::GetInstance().UnMuteAudioStream(info->clientUID);
10680922886Sopenharmony_ci        }
10780922886Sopenharmony_ci    }
10880922886Sopenharmony_ci}
10980922886Sopenharmony_ci
11080922886Sopenharmony_civoid BackgroundAudioController::HandleAppMuteState(int32_t uid, int32_t pid, bool isBackground)
11180922886Sopenharmony_ci{
11280922886Sopenharmony_ci    if (PermissionChecker::GetInstance().CheckSystemPermissionByUid(uid)) {
11380922886Sopenharmony_ci        SLOGD("uid=%{public}d is system app", uid);
11480922886Sopenharmony_ci        return;
11580922886Sopenharmony_ci    }
11680922886Sopenharmony_ci    if (HasAVSession(uid)) {
11780922886Sopenharmony_ci        return;
11880922886Sopenharmony_ci    }
11980922886Sopenharmony_ci
12080922886Sopenharmony_ci    if (isBackground) {
12180922886Sopenharmony_ci        std::vector<std::shared_ptr<AudioStandard::AudioRendererChangeInfo>> infos;
12280922886Sopenharmony_ci        auto ret = AudioStandard::AudioStreamManager::GetInstance()->GetCurrentRendererChangeInfos(infos);
12380922886Sopenharmony_ci        if (ret != 0) {
12480922886Sopenharmony_ci            SLOGE("get renderer state failed");
12580922886Sopenharmony_ci            return;
12680922886Sopenharmony_ci        }
12780922886Sopenharmony_ci        bool isRunning = false;
12880922886Sopenharmony_ci        for (const auto& info : infos) {
12980922886Sopenharmony_ci            if (info->rendererState == AudioStandard::RENDERER_RUNNING &&
13080922886Sopenharmony_ci                (info->clientUID == uid and info->clientPid == pid)) {
13180922886Sopenharmony_ci                isRunning = true;
13280922886Sopenharmony_ci                break;
13380922886Sopenharmony_ci            }
13480922886Sopenharmony_ci        }
13580922886Sopenharmony_ci        if (!isRunning) {
13680922886Sopenharmony_ci            SLOGI("find uid=%{public}d pid=%{public}d isn't running, return", uid, pid);
13780922886Sopenharmony_ci            return;
13880922886Sopenharmony_ci        }
13980922886Sopenharmony_ci        SLOGI("mute uid=%{public}d", uid);
14080922886Sopenharmony_ci        AudioAdapter::GetInstance().MuteAudioStream(uid);
14180922886Sopenharmony_ci        if (ptr_ != nullptr) {
14280922886Sopenharmony_ci            ptr_->NotifyAudioSessionCheckTrigger(uid);
14380922886Sopenharmony_ci        }
14480922886Sopenharmony_ci    } else {
14580922886Sopenharmony_ci        SLOGI("unmute uid=%{public}d", uid);
14680922886Sopenharmony_ci        AudioAdapter::GetInstance().UnMuteAudioStream(uid);
14780922886Sopenharmony_ci    }
14880922886Sopenharmony_ci}
14980922886Sopenharmony_ci// LCOV_EXCL_STOP
15080922886Sopenharmony_ci
15180922886Sopenharmony_cibool BackgroundAudioController::IsBackgroundMode(int32_t creatorUid, BackgroundMode backgroundMode) const
15280922886Sopenharmony_ci{
15380922886Sopenharmony_ci    // LCOV_EXCL_START
15480922886Sopenharmony_ci    std::vector<std::shared_ptr<ContinuousTaskCallbackInfo>> continuousTaskList;
15580922886Sopenharmony_ci    ErrCode code = BackgroundTaskMgr::BackgroundTaskMgrHelper::GetContinuousTaskApps(continuousTaskList);
15680922886Sopenharmony_ci    if (code != OHOS::ERR_OK) {
15780922886Sopenharmony_ci        SLOGE("uid=%{public}d no continuous task list, code=%{public}d", creatorUid, code);
15880922886Sopenharmony_ci        return false;
15980922886Sopenharmony_ci    }
16080922886Sopenharmony_ci    // LCOV_EXCL_STOP
16180922886Sopenharmony_ci
16280922886Sopenharmony_ci    for (const auto &task : continuousTaskList) {
16380922886Sopenharmony_ci        SLOGD("uid=%{public}d taskCreatorUid=%{public}d", creatorUid, task->GetCreatorUid());
16480922886Sopenharmony_ci        if (task->GetCreatorUid() != creatorUid) {
16580922886Sopenharmony_ci            continue;
16680922886Sopenharmony_ci        }
16780922886Sopenharmony_ci
16880922886Sopenharmony_ci        std::vector<uint32_t> bgModeIds = task->GetTypeIds();
16980922886Sopenharmony_ci        auto it = std::find_if(bgModeIds.begin(), bgModeIds.end(), [ = ](auto mode) {
17080922886Sopenharmony_ci            uint32_t uMode = static_cast<uint32_t>(backgroundMode);
17180922886Sopenharmony_ci            return (mode == uMode);
17280922886Sopenharmony_ci        });
17380922886Sopenharmony_ci        if (it != bgModeIds.end()) {
17480922886Sopenharmony_ci            SLOGD("uid=%{public}d is audio playback", creatorUid);
17580922886Sopenharmony_ci            return true;
17680922886Sopenharmony_ci        }
17780922886Sopenharmony_ci    }
17880922886Sopenharmony_ci    SLOGD("uid=%{public}d isn't audio playback", creatorUid);
17980922886Sopenharmony_ci    return false;
18080922886Sopenharmony_ci}
18180922886Sopenharmony_ci
18280922886Sopenharmony_cibool BackgroundAudioController::HasAVSession(int32_t uid)
18380922886Sopenharmony_ci{
18480922886Sopenharmony_ci    std::lock_guard lockGuard(lock_);
18580922886Sopenharmony_ci    bool hasSession = false;
18680922886Sopenharmony_ci    auto it = sessionUIDs_.find(uid);
18780922886Sopenharmony_ci    if (it != sessionUIDs_.end()) {
18880922886Sopenharmony_ci        SLOGD("uid=%{public}d has av_session, no need to handle mute or unmute strategy.", uid);
18980922886Sopenharmony_ci        hasSession = true;
19080922886Sopenharmony_ci    }
19180922886Sopenharmony_ci    return hasSession;
19280922886Sopenharmony_ci}
19380922886Sopenharmony_ci}
194