• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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