• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "avsession_event_handler.h"
21 
22 namespace OHOS::AVSession {
FocusSessionStrategy()23 FocusSessionStrategy::FocusSessionStrategy()
24 {
25     SLOGI("construct");
26 }
27 
~FocusSessionStrategy()28 FocusSessionStrategy::~FocusSessionStrategy()
29 {
30     SLOGI("destroy");
31     AudioStandard::AudioStreamManager::GetInstance()->UnregisterAudioRendererEventListener(getpid());
32 }
33 
Init()34 void FocusSessionStrategy::Init()
35 {
36     AudioAdapter::GetInstance().AddStreamRendererStateListener([this](const auto& infos) {
37         HandleAudioRenderStateChangeEvent(infos);
38     });
39 }
40 
RegisterFocusSessionChangeCallback(const FocusSessionChangeCallback & callback)41 void FocusSessionStrategy::RegisterFocusSessionChangeCallback(const FocusSessionChangeCallback& callback)
42 {
43     callback_ = callback;
44 }
45 
RegisterFocusSessionSelector(const FocusSessionSelector & selector)46 void FocusSessionStrategy::RegisterFocusSessionSelector(const FocusSessionSelector& selector)
47 {
48     selector_ = selector;
49 }
50 
ProcAudioRenderChange(const AudioRendererChangeInfos & infos)51 void FocusSessionStrategy::ProcAudioRenderChange(const AudioRendererChangeInfos& infos)
52 {
53     SLOGD("AudioRenderStateChange start");
54     int32_t playingUid = -1;
55     for (const auto& info : infos) {
56         SLOGD("AudioRenderStateChange uid=%{public}d sessionId=%{public}d state=%{public}d",
57             info->clientUID, info->sessionId, info->rendererState);
58         if (info->clientUID == ancoUid && (std::count(ALLOWED_ANCO_STREAM_USAGE.begin(),
59             ALLOWED_ANCO_STREAM_USAGE.end(), info->rendererInfo.streamUsage) == 0)) {
60             SLOGI("Anco invalid uid=%{public}d usage=%{public}d", info->clientUID, info->rendererInfo.streamUsage);
61             continue;
62         }
63         {
64             std::lock_guard lockGuard(stateLock_);
65             auto it = currentStates_.find(info->clientUID);
66             if (it == currentStates_.end()) {
67                 currentStates_[info->clientUID] = stopState;
68             } else if (info->rendererState == AudioStandard::RendererState::RENDERER_RELEASED) {
69                 currentStates_.erase(it);
70                 continue;
71             }
72 
73             if (info->rendererState == AudioStandard::RendererState::RENDERER_RUNNING) {
74                 currentStates_[info->clientUID] = runningState;
75                 playingUid = info->clientUID;
76             }
77             if (playingUid != info->clientUID) {
78                 currentStates_[info->clientUID] = stopState;
79             }
80         }
81     }
82     SLOGD("AudioRenderStateChange end");
83 }
84 
HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos & infos)85 void FocusSessionStrategy::HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos& infos)
86 {
87     ProcAudioRenderChange(infos);
88     int32_t focusSessionUid = -1;
89     int32_t stopSessionUid = -1;
90     {
91         std::lock_guard lockGuard(stateLock_);
92         for (auto it = currentStates_.begin(); it != currentStates_.end(); it++) {
93             if (it->second == runningState) {
94                 if (IsFocusSession(it->first)) {
95                     focusSessionUid = it->first;
96                     continue;
97                 }
98             } else {
99                 if (CheckFocusSessionStop(it->first)) {
100                     stopSessionUid = it->first;
101                 }
102             }
103         }
104     }
105 
106     if (focusSessionUid != -1) {
107         UpdateFocusSession(focusSessionUid);
108     }
109 
110     if (stopSessionUid != -1) {
111         DelayStopFocusSession(stopSessionUid);
112     }
113 }
114 
IsFocusSession(const int32_t uid)115 bool FocusSessionStrategy::IsFocusSession(const int32_t uid)
116 {
117     bool isFocus = false;
118     auto it = lastStates_.find(uid);
119     if (it == lastStates_.end()) {
120         isFocus = true;
121     } else {
122         isFocus = it->second != runningState;
123     }
124 
125     lastStates_[uid] = currentStates_[uid];
126     if (isFocus) {
127         AVSessionEventHandler::GetInstance().AVSessionRemoveTask("CheckFocusStop" + std::to_string(uid));
128         HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", uid,
129             "AUDIO_INFO_RENDERER_STATE", AudioStandard::RendererState::RENDERER_RUNNING,
130             "DETAILED_MSG", "focussessionstrategy selectfocussession, current focus session info");
131         SLOGI("IsFocusSession uid=%{public}d isFocusTRUE", uid);
132     }
133     return isFocus;
134 }
135 
UpdateFocusSession(const int32_t uid)136 void FocusSessionStrategy::UpdateFocusSession(const int32_t uid)
137 {
138     FocusSessionChangeInfo sessionInfo;
139     sessionInfo.uid = uid;
140     if (selector_) {
141         selector_(sessionInfo);
142     }
143     if (callback_) {
144         callback_(sessionInfo, true);
145     }
146 }
147 
CheckFocusSessionStop(const int32_t uid)148 bool FocusSessionStrategy::CheckFocusSessionStop(const int32_t uid)
149 {
150     bool isFocusStop = false;
151     auto it = lastStates_.find(uid);
152     if (it == lastStates_.end()) {
153         isFocusStop = false;
154     } else {
155         isFocusStop = it->second == runningState;
156     }
157 
158     lastStates_[uid] = currentStates_[uid];
159     if (isFocusStop) {
160         SLOGI("CheckFocusSessionStop uid=%{public}d isFocusStopTRUE", uid);
161     }
162     return isFocusStop;
163 }
164 
DelayStopFocusSession(const int32_t uid)165 void FocusSessionStrategy::DelayStopFocusSession(const int32_t uid)
166 {
167     AVSessionEventHandler::GetInstance().AVSessionPostTask(
168         [this, uid]() {
169             {
170                 std::lock_guard lockGuard(stateLock_);
171                 SLOGI("CheckFocusStop uid=%{public}d lastState=%{public}d", uid, lastStates_[uid]);
172                 if (lastStates_[uid] == AudioStandard::RendererState::RENDERER_RUNNING) {
173                     return;
174                 }
175             }
176             FocusSessionChangeInfo changeInfo;
177             changeInfo.uid = uid;
178             if (callback_) {
179                 callback_(changeInfo, false);
180             }
181         }, "CheckFocusStop" + std::to_string(uid), cancelTimeout);
182 }
183 }
184