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 "focus_session_strategy.h"
1780922886Sopenharmony_ci#include "avsession_log.h"
1880922886Sopenharmony_ci#include "audio_adapter.h"
1980922886Sopenharmony_ci#include "avsession_sysevent.h"
2080922886Sopenharmony_ci
2180922886Sopenharmony_cinamespace OHOS::AVSession {
2280922886Sopenharmony_ciFocusSessionStrategy::FocusSessionStrategy()
2380922886Sopenharmony_ci{
2480922886Sopenharmony_ci    SLOGI("construct");
2580922886Sopenharmony_ci}
2680922886Sopenharmony_ci
2780922886Sopenharmony_ciFocusSessionStrategy::~FocusSessionStrategy()
2880922886Sopenharmony_ci{
2980922886Sopenharmony_ci    SLOGI("destroy");
3080922886Sopenharmony_ci    AudioStandard::AudioStreamManager::GetInstance()->UnregisterAudioRendererEventListener(getpid());
3180922886Sopenharmony_ci}
3280922886Sopenharmony_ci
3380922886Sopenharmony_civoid FocusSessionStrategy::Init()
3480922886Sopenharmony_ci{
3580922886Sopenharmony_ci    AudioAdapter::GetInstance().AddStreamRendererStateListener([this](const auto& infos) {
3680922886Sopenharmony_ci        HandleAudioRenderStateChangeEvent(infos);
3780922886Sopenharmony_ci    });
3880922886Sopenharmony_ci}
3980922886Sopenharmony_ci
4080922886Sopenharmony_civoid FocusSessionStrategy::RegisterFocusSessionChangeCallback(const FocusSessionChangeCallback& callback)
4180922886Sopenharmony_ci{
4280922886Sopenharmony_ci    callback_ = callback;
4380922886Sopenharmony_ci}
4480922886Sopenharmony_ci
4580922886Sopenharmony_civoid FocusSessionStrategy::RegisterFocusSessionSelector(const FocusSessionSelector& selector)
4680922886Sopenharmony_ci{
4780922886Sopenharmony_ci    selector_ = selector;
4880922886Sopenharmony_ci}
4980922886Sopenharmony_ci
5080922886Sopenharmony_civoid FocusSessionStrategy::HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos& infos)
5180922886Sopenharmony_ci{
5280922886Sopenharmony_ci    FocusSessionChangeInfo focusSessionChangeInfo;
5380922886Sopenharmony_ci    if (SelectFocusSession(infos, focusSessionChangeInfo)) {
5480922886Sopenharmony_ci        if (callback_) {
5580922886Sopenharmony_ci            callback_(focusSessionChangeInfo);
5680922886Sopenharmony_ci        }
5780922886Sopenharmony_ci    }
5880922886Sopenharmony_ci}
5980922886Sopenharmony_ci
6080922886Sopenharmony_cibool FocusSessionStrategy::IsFocusSession(const AudioStandard::AudioRendererChangeInfo& info)
6180922886Sopenharmony_ci{
6280922886Sopenharmony_ci    if (info.rendererState == AudioStandard::RendererState::RENDERER_RUNNING) {
6380922886Sopenharmony_ci        std::lock_guard lockGuard(stateLock_);
6480922886Sopenharmony_ci        auto it = lastStates_.find(info.clientUID);
6580922886Sopenharmony_ci        if (it == lastStates_.end()) {
6680922886Sopenharmony_ci            return true;
6780922886Sopenharmony_ci        }
6880922886Sopenharmony_ci        if (it->second != AudioStandard::RendererState::RENDERER_RUNNING) {
6980922886Sopenharmony_ci            HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", info.clientUID,
7080922886Sopenharmony_ci                "AUDIO_INFO_CONTENT_TYPE", info.rendererInfo.contentType,
7180922886Sopenharmony_ci                "AUDIO_INFO_RENDERER_STATE", info.rendererState,
7280922886Sopenharmony_ci                "DETAILED_MSG", "focussessionstrategy selectfocussession, last focus session info");
7380922886Sopenharmony_ci            return true;
7480922886Sopenharmony_ci        }
7580922886Sopenharmony_ci    }
7680922886Sopenharmony_ci    return false;
7780922886Sopenharmony_ci}
7880922886Sopenharmony_ci
7980922886Sopenharmony_cibool FocusSessionStrategy::SelectFocusSession(const AudioRendererChangeInfos& infos,
8080922886Sopenharmony_ci                                              FocusSessionChangeInfo& sessionInfo)
8180922886Sopenharmony_ci{
8280922886Sopenharmony_ci    for (const auto& info : infos) {
8380922886Sopenharmony_ci        if (!IsFocusSession(*info)) {
8480922886Sopenharmony_ci            std::lock_guard lockGuard(stateLock_);
8580922886Sopenharmony_ci            lastStates_[info->clientUID] = info->rendererState;
8680922886Sopenharmony_ci            HISYSEVENT_SET_AUDIO_STATUS(info->clientUID, info->rendererState);
8780922886Sopenharmony_ci            continue;
8880922886Sopenharmony_ci        }
8980922886Sopenharmony_ci        {
9080922886Sopenharmony_ci            std::lock_guard lockGuard(stateLock_);
9180922886Sopenharmony_ci            HISYSEVENT_SET_AUDIO_STATUS(info->clientUID, info->rendererState);
9280922886Sopenharmony_ci            lastStates_[info->clientUID] = info->rendererState;
9380922886Sopenharmony_ci        }
9480922886Sopenharmony_ci        SLOGD("SelectFocusSession check uid=%{public}d state=%{public}d", info->clientUID, info->rendererState);
9580922886Sopenharmony_ci        sessionInfo.uid = info->clientUID;
9680922886Sopenharmony_ci        sessionInfo.streamUsage = info->rendererInfo.streamUsage;
9780922886Sopenharmony_ci        if (selector_ != nullptr && !selector_(sessionInfo)) {
9880922886Sopenharmony_ci            continue;
9980922886Sopenharmony_ci        }
10080922886Sopenharmony_ci        SLOGI("uid=%{public}d is focus session", sessionInfo.uid);
10180922886Sopenharmony_ci        HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", sessionInfo.uid, "AUDIO_INFO_CONTENT_TYPE",
10280922886Sopenharmony_ci            info->rendererInfo.contentType, "AUDIO_INFO_RENDERER_STATE", info->rendererState,
10380922886Sopenharmony_ci            "DETAILED_MSG", "focussessionstrategy selectfocussession, current focus session info");
10480922886Sopenharmony_ci        return true;
10580922886Sopenharmony_ci    }
10680922886Sopenharmony_ci    return false;
10780922886Sopenharmony_ci}
10880922886Sopenharmony_ci}
109