1 // Copyright (C) 2021 The Android Open Source Project
2 //
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 #include "BusStreamProvider.h"
16
17 #include <android-base/logging.h>
18
19 #include <algorithm>
20
21 #include "DummyBusOutputStream.h"
22 #include "RemoteBusOutputStream.h"
23
24 using aidl::device::google::atv::audio_proxy::IOutputStream;
25
26 namespace audio_proxy::service {
27
setStreamProvider(std::shared_ptr<IStreamProvider> provider)28 void BusStreamProvider::setStreamProvider(
29 std::shared_ptr<IStreamProvider> provider) {
30 std::lock_guard<std::mutex> lock(mLock);
31 cleanStreamOutList_Locked();
32 mStreamProvider = std::move(provider);
33
34 for (auto& weakStream : mStreamOutList) {
35 if (sp<StreamOutImpl> stream = weakStream.promote()) {
36 auto oldOutputStream = stream->getOutputStream();
37 auto outputStream = openOutputStream_Locked(oldOutputStream->getAddress(),
38 oldOutputStream->getConfig(),
39 oldOutputStream->getFlags());
40 stream->updateOutputStream(std::move(outputStream));
41 }
42 }
43 }
44
getStreamProvider()45 std::shared_ptr<IStreamProvider> BusStreamProvider::getStreamProvider() {
46 std::lock_guard<std::mutex> lock(mLock);
47 return mStreamProvider;
48 }
49
openOutputStream(const std::string & address,const AidlAudioConfig & config,int32_t flags)50 std::shared_ptr<BusOutputStream> BusStreamProvider::openOutputStream(
51 const std::string& address, const AidlAudioConfig& config, int32_t flags) {
52 std::lock_guard<std::mutex> lock(mLock);
53 return openOutputStream_Locked(address, config, flags);
54 }
55
onStreamOutCreated(wp<StreamOutImpl> stream)56 void BusStreamProvider::onStreamOutCreated(wp<StreamOutImpl> stream) {
57 std::lock_guard<std::mutex> lock(mLock);
58 cleanStreamOutList_Locked();
59 mStreamOutList.emplace_back(std::move(stream));
60 }
61
openOutputStream_Locked(const std::string & address,const AidlAudioConfig & config,int32_t flags)62 std::shared_ptr<BusOutputStream> BusStreamProvider::openOutputStream_Locked(
63 const std::string& address, const AidlAudioConfig& config, int32_t flags) {
64 if (!mStreamProvider) {
65 return std::make_shared<DummyBusOutputStream>(address, config, flags);
66 }
67
68 std::shared_ptr<IOutputStream> stream;
69 ndk::ScopedAStatus status =
70 mStreamProvider->openOutputStream(address, config, flags, &stream);
71 if (!status.isOk() || !stream) {
72 LOG(ERROR) << "Failed to open output stream, status " << status.getStatus();
73 return std::make_shared<DummyBusOutputStream>(address, config, flags);
74 }
75
76 return std::make_shared<RemoteBusOutputStream>(std::move(stream), address,
77 config, flags);
78 }
79
cleanAndCountStreamOuts()80 size_t BusStreamProvider::cleanAndCountStreamOuts() {
81 std::lock_guard<std::mutex> lock(mLock);
82 cleanStreamOutList_Locked();
83 return mStreamOutList.size();
84 }
85
cleanStreamOutList_Locked()86 void BusStreamProvider::cleanStreamOutList_Locked() {
87 auto it = mStreamOutList.begin();
88 while (it != mStreamOutList.end()) {
89 if (!it->promote()) {
90 it = mStreamOutList.erase(it);
91 } else {
92 ++it;
93 }
94 }
95 }
96
97 } // namespace audio_proxy::service