1 // Copyright (C) 2020 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 "AudioProxyDevice.h"
16
17 #include <android-base/logging.h>
18
19 #include "AudioProxyStreamOut.h"
20
21 using aidl::device::google::atv::audio_proxy::AudioConfig;
22
23 #define CHECK_API(func) \
24 do { \
25 if (!stream->func) { \
26 LOG(ERROR) << "Undefined API " << #func; \
27 return false; \
28 } \
29 } while (0)
30
31 namespace audio_proxy {
32 namespace {
isValidStreamOut(const audio_proxy_stream_out_t * stream)33 bool isValidStreamOut(const audio_proxy_stream_out_t* stream) {
34 CHECK_API(standby);
35 CHECK_API(pause);
36 CHECK_API(resume);
37 CHECK_API(flush);
38 CHECK_API(drain);
39 CHECK_API(write);
40 CHECK_API(get_presentation_position);
41 CHECK_API(set_volume);
42
43 return true;
44 }
45 } // namespace
46
AudioProxyDevice(audio_proxy_device_t * device)47 AudioProxyDevice::AudioProxyDevice(audio_proxy_device_t* device)
48 : mDevice(device) {}
49
50 AudioProxyDevice::~AudioProxyDevice() = default;
51
getServiceName()52 const char* AudioProxyDevice::getServiceName() {
53 return mDevice->v2->get_service_name(mDevice->v2);
54 }
55
openOutputStream(const std::string & address,const AudioConfig & aidlConfig,int32_t flags)56 std::unique_ptr<AudioProxyStreamOut> AudioProxyDevice::openOutputStream(
57 const std::string& address, const AudioConfig& aidlConfig, int32_t flags) {
58 audio_proxy_config_t config = {
59 .format = static_cast<audio_proxy_format_t>(aidlConfig.format),
60 .sample_rate = static_cast<uint32_t>(aidlConfig.sampleRateHz),
61 .channel_mask =
62 static_cast<audio_proxy_channel_mask_t>(aidlConfig.channelMask),
63 .frame_count = 0,
64 .extension = nullptr};
65
66 // TODO(yucliu): Pass address to the app. For now, the only client app
67 // (MediaShell) can use flags to distinguish different streams.
68 audio_proxy_stream_out_t* stream = nullptr;
69 int ret = mDevice->v2->open_output_stream(
70 mDevice->v2, address.c_str(),
71 static_cast<audio_proxy_output_flags_t>(flags), &config, &stream);
72
73 if (ret || !stream) {
74 return nullptr;
75 }
76
77 if (!isValidStreamOut(stream)) {
78 mDevice->close_output_stream(mDevice, stream);
79 return nullptr;
80 }
81
82 return std::make_unique<AudioProxyStreamOut>(stream, mDevice);
83 }
84
85 } // namespace audio_proxy
86