1 /*
2  * Copyright (c) 2022 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 "focus_session_strategy.h"
17 #include "avsession_log.h"
18 #include "audio_adapter.h"
19 #include "avsession_sysevent.h"
20 
21 namespace OHOS::AVSession {
FocusSessionStrategy()22 FocusSessionStrategy::FocusSessionStrategy()
23 {
24     SLOGI("construct");
25 }
26 
~FocusSessionStrategy()27 FocusSessionStrategy::~FocusSessionStrategy()
28 {
29     SLOGI("destroy");
30     AudioStandard::AudioStreamManager::GetInstance()->UnregisterAudioRendererEventListener(getpid());
31 }
32 
Init()33 void FocusSessionStrategy::Init()
34 {
35     AudioAdapter::GetInstance().AddStreamRendererStateListener([this](const auto& infos) {
36         HandleAudioRenderStateChangeEvent(infos);
37     });
38 }
39 
RegisterFocusSessionChangeCallback(const FocusSessionChangeCallback & callback)40 void FocusSessionStrategy::RegisterFocusSessionChangeCallback(const FocusSessionChangeCallback& callback)
41 {
42     callback_ = callback;
43 }
44 
RegisterFocusSessionSelector(const FocusSessionSelector & selector)45 void FocusSessionStrategy::RegisterFocusSessionSelector(const FocusSessionSelector& selector)
46 {
47     selector_ = selector;
48 }
49 
HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos & infos)50 void FocusSessionStrategy::HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos& infos)
51 {
52     FocusSessionChangeInfo focusSessionChangeInfo;
53     if (SelectFocusSession(infos, focusSessionChangeInfo)) {
54         if (callback_) {
55             callback_(focusSessionChangeInfo);
56         }
57     }
58 }
59 
IsFocusSession(const AudioStandard::AudioRendererChangeInfo & info)60 bool FocusSessionStrategy::IsFocusSession(const AudioStandard::AudioRendererChangeInfo& info)
61 {
62     if (info.rendererState == AudioStandard::RendererState::RENDERER_RUNNING) {
63         std::lock_guard lockGuard(stateLock_);
64         auto it = lastStates_.find(info.clientUID);
65         if (it == lastStates_.end()) {
66             return true;
67         }
68         if (it->second != AudioStandard::RendererState::RENDERER_RUNNING) {
69             HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", info.clientUID,
70                 "AUDIO_INFO_CONTENT_TYPE", info.rendererInfo.contentType,
71                 "AUDIO_INFO_RENDERER_STATE", info.rendererState,
72                 "DETAILED_MSG", "focussessionstrategy selectfocussession, last focus session info");
73             return true;
74         }
75     }
76     return false;
77 }
78 
SelectFocusSession(const AudioRendererChangeInfos & infos,FocusSessionChangeInfo & sessionInfo)79 bool FocusSessionStrategy::SelectFocusSession(const AudioRendererChangeInfos& infos,
80                                               FocusSessionChangeInfo& sessionInfo)
81 {
82     for (const auto& info : infos) {
83         if (!IsFocusSession(*info)) {
84             std::lock_guard lockGuard(stateLock_);
85             lastStates_[info->clientUID] = info->rendererState;
86             HISYSEVENT_SET_AUDIO_STATUS(info->clientUID, info->rendererState);
87             continue;
88         }
89         {
90             std::lock_guard lockGuard(stateLock_);
91             HISYSEVENT_SET_AUDIO_STATUS(info->clientUID, info->rendererState);
92             lastStates_[info->clientUID] = info->rendererState;
93         }
94         SLOGD("SelectFocusSession check uid=%{public}d state=%{public}d", info->clientUID, info->rendererState);
95         sessionInfo.uid = info->clientUID;
96         sessionInfo.streamUsage = info->rendererInfo.streamUsage;
97         if (selector_ != nullptr && !selector_(sessionInfo)) {
98             continue;
99         }
100         SLOGI("uid=%{public}d is focus session", sessionInfo.uid);
101         HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", sessionInfo.uid, "AUDIO_INFO_CONTENT_TYPE",
102             info->rendererInfo.contentType, "AUDIO_INFO_RENDERER_STATE", info->rendererState,
103             "DETAILED_MSG", "focussessionstrategy selectfocussession, current focus session info");
104         return true;
105     }
106     return false;
107 }
108 }
109