• 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 
SetAudioPlayingUids(std::vector<int> audioPlayingUids)51 void FocusSessionStrategy::SetAudioPlayingUids(std::vector<int> audioPlayingUids)
52 {
53     std::lock_guard lockGuard(audioPlayingLock_);
54     audioPlayingUids_ = audioPlayingUids;
55 }
56 
GetAudioPlayingUids()57 std::vector<int> FocusSessionStrategy::GetAudioPlayingUids()
58 {
59     std::lock_guard lockGuard(audioPlayingLock_);
60     return audioPlayingUids_;
61 }
62 
ProcAudioRenderChange(const AudioRendererChangeInfos & infos)63 void FocusSessionStrategy::ProcAudioRenderChange(const AudioRendererChangeInfos& infos)
64 {
65     SLOGD("AudioRenderStateChange start");
66     std::lock_guard lockGuard(audioPlayingLock_);
67     audioPlayingUids_.clear();
68     std::pair<int32_t, int32_t> playingKey = std::make_pair(-1, -1);
69     for (const auto& info : infos) {
70         SLOGD("AudioRenderStateChange uid=%{public}d pid=%{public}d audioSessionId=%{public}d state=%{public}d",
71             info->clientUID, info->clientPid, info->sessionId, info->rendererState);
72         if (std::find(audioPlayingUids_.begin(), audioPlayingUids_.end(), info->clientUID) == audioPlayingUids_.end() &&
73             (std::count(AUDIO_PLAYING_STREAM_USAGE.begin(), AUDIO_PLAYING_STREAM_USAGE.end(),
74             info->rendererInfo.streamUsage) != 0) && (std::count(AUDIO_PLAYING_STREAM_STATE.begin(),
75             AUDIO_PLAYING_STREAM_STATE.end(), info->rendererState) != 0)) {
76             audioPlayingUids_.push_back(info->clientUID);
77         }
78         if (info->clientUID == ancoUid && (std::count(ALLOWED_ANCO_STREAM_USAGE.begin(),
79             ALLOWED_ANCO_STREAM_USAGE.end(), info->rendererInfo.streamUsage) == 0)) {
80             SLOGI("Anco invalid uid=%{public}d usage=%{public}d", info->clientUID, info->rendererInfo.streamUsage);
81             continue;
82         }
83         if ((std::count(ALLOWED_MEDIA_STREAM_USAGE.begin(),
84             ALLOWED_MEDIA_STREAM_USAGE.end(), info->rendererInfo.streamUsage) == 0)) {
85             SLOGI("Media invalid uid=%{public}d usage=%{public}d", info->clientUID, info->rendererInfo.streamUsage);
86             continue;
87         }
88         bool isPidValid = info->clientPid != 0;
89         CHECK_AND_CONTINUE(isPidValid);
90         {
91             std::lock_guard lockGuard(stateLock_);
92             std::pair<int32_t, int32_t> key = std::make_pair(info->clientUID, info->clientPid);
93             auto it = currentStates_.find(key);
94             if (it == currentStates_.end()) {
95                 currentStates_[key] = stopState;
96             }
97 
98             if (info->rendererState == AudioStandard::RendererState::RENDERER_RUNNING) {
99                 currentStates_[key] = runningState;
100                 playingKey = key;
101             }
102             if (playingKey != key) {
103                 currentStates_[key] = info->rendererState == AudioStandard::RendererState::RENDERER_RELEASED ?
104                     releaseState : stopState;
105             }
106         }
107     }
108     SLOGD("AudioRenderStateChange end");
109 }
110 
HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos & infos)111 void FocusSessionStrategy::HandleAudioRenderStateChangeEvent(const AudioRendererChangeInfos& infos)
112 {
113     ProcAudioRenderChange(infos);
114     std::pair<int32_t, int32_t> focusSessionKey = std::make_pair(-1, -1);
115     std::pair<int32_t, int32_t> stopSessionKey = std::make_pair(-1, -1);
116     {
117         std::lock_guard lockGuard(stateLock_);
118         for (auto it = currentStates_.begin(); it != currentStates_.end();) {
119             if (it->second == runningState) {
120                 if (IsFocusSession(it->first)) {
121                     focusSessionKey = it->first;
122                     it++;
123                     continue;
124                 }
125             } else {
126                 if (CheckFocusSessionStop(it->first)) {
127                     stopSessionKey = it->first;
128                 }
129             }
130             if (it->second == releaseState) {
131                 lastStates_.erase(it->first);
132                 it = currentStates_.erase(it);
133             } else {
134                 it++;
135             }
136         }
137     }
138     if (focusSessionKey.first != -1 && focusSessionKey.second != -1) {
139         UpdateFocusSession(focusSessionKey);
140     }
141     if (stopSessionKey.first != -1 && stopSessionKey.second != -1) {
142         DelayStopFocusSession(stopSessionKey);
143     }
144 }
145 
IsFocusSession(const std::pair<int32_t,int32_t> key)146 bool FocusSessionStrategy::IsFocusSession(const std::pair<int32_t, int32_t> key)
147 {
148     bool isFocus = false;
149     auto it = lastStates_.find(key);
150     if (it == lastStates_.end()) {
151         isFocus = true;
152     } else {
153         isFocus = it->second != runningState;
154     }
155 
156     lastStates_[key] = currentStates_[key];
157     if (isFocus) {
158         AVSessionEventHandler::GetInstance().AVSessionRemoveTask("CheckFocusStop" + std::to_string(key.second));
159         HISYSEVENT_BEHAVIOR("FOCUS_CHANGE", "FOCUS_SESSION_UID", key.second,
160             "AUDIO_INFO_RENDERER_STATE", AudioStandard::RendererState::RENDERER_RUNNING,
161             "DETAILED_MSG", "focussessionstrategy selectfocussession, current focus session info");
162         SLOGI("IsFocusSession uid=%{public}d isFocusTRUE", key.second);
163     }
164     return isFocus;
165 }
166 
UpdateFocusSession(const std::pair<int32_t,int32_t> key)167 void FocusSessionStrategy::UpdateFocusSession(const std::pair<int32_t, int32_t> key)
168 {
169     FocusSessionChangeInfo sessionInfo;
170     sessionInfo.uid = key.first;
171     sessionInfo.pid = key.second;
172     if (selector_) {
173         selector_(sessionInfo);
174     }
175     if (callback_) {
176         callback_(sessionInfo, true);
177     }
178 }
179 
CheckFocusSessionStop(const std::pair<int32_t,int32_t> key)180 bool FocusSessionStrategy::CheckFocusSessionStop(const std::pair<int32_t, int32_t> key)
181 {
182     bool isFocusStop = false;
183     auto it = lastStates_.find(key);
184     if (it == lastStates_.end()) {
185         isFocusStop = false;
186     } else {
187         isFocusStop = it->second == runningState;
188     }
189 
190     lastStates_[key] = currentStates_[key];
191     if (isFocusStop) {
192         SLOGI("CheckFocusSessionStop uid=%{public}d pid=%{public}d isFocusStopTRUE", key.first, key.second);
193     }
194     return isFocusStop;
195 }
196 
DelayStopFocusSession(const std::pair<int32_t,int32_t> key)197 void FocusSessionStrategy::DelayStopFocusSession(const std::pair<int32_t, int32_t> key)
198 {
199     AVSessionEventHandler::GetInstance().AVSessionPostTask(
200         [this, key]() {
201             {
202                 std::lock_guard lockGuard(stateLock_);
203                 auto it = lastStates_.find(key);
204                 CHECK_AND_RETURN_LOG(!(it != lastStates_.end() &&
205                     it->second == AudioStandard::RendererState::RENDERER_RUNNING),
206                     "DelayStopFocus uid=%{public}d pid=%{public}d not found or not running", key.first, key.second);
207                 SLOGE("DelayStopFocus uid=%{public}d lastState=%{public}d", it->first.first, it->second);
208             }
209             FocusSessionChangeInfo changeInfo;
210             changeInfo.uid = key.first;
211             changeInfo.pid = key.second;
212             if (callback_) {
213                 callback_(changeInfo, false);
214             }
215         }, "CheckFocusStop" + std::to_string(key.second), cancelTimeout);
216 }
217 }
218