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 #define LOG_TAG "audio_proxy_client"
16 
17 #include "AudioProxyDevice.h"
18 
19 #include <utils/Log.h>
20 
21 #include "AudioProxyStreamOut.h"
22 #include "HidlTypeUtil.h"
23 
24 #define CHECK_API(func)                 \
25   do {                                  \
26     if (!stream->func) {                \
27       ALOGD("Undefined API %s", #func); \
28       return false;                     \
29     }                                   \
30   } while (0)
31 
32 namespace audio_proxy {
33 namespace CPP_VERSION {
34 namespace {
isValidStreamOut(const audio_proxy_stream_out_t * stream)35 bool isValidStreamOut(const audio_proxy_stream_out_t* stream) {
36   CHECK_API(get_buffer_size);
37   CHECK_API(get_frame_count);
38   CHECK_API(get_supported_sample_rates);
39   CHECK_API(get_sample_rate);
40   CHECK_API(get_supported_channel_masks);
41   CHECK_API(get_channel_mask);
42   CHECK_API(get_supported_formats);
43   CHECK_API(get_format);
44   CHECK_API(get_latency);
45   CHECK_API(standby);
46   CHECK_API(pause);
47   CHECK_API(resume);
48   CHECK_API(flush);
49   CHECK_API(write);
50   CHECK_API(get_presentation_position);
51   CHECK_API(set_parameters);
52   CHECK_API(get_parameters);
53 
54   return true;
55 }
56 }  // namespace
57 
AudioProxyDevice(audio_proxy_device_t * device)58 AudioProxyDevice::AudioProxyDevice(audio_proxy_device_t* device)
59     : mDevice(device) {}
60 
61 AudioProxyDevice::~AudioProxyDevice() = default;
62 
getAddress()63 const char* AudioProxyDevice::getAddress() {
64   return mDevice->get_address(mDevice);
65 }
66 
openOutputStream(hidl_bitfield<AudioOutputFlag> flags,const AudioConfig & hidlConfig,std::unique_ptr<AudioProxyStreamOut> * streamOut,AudioConfig * hidlConfigOut)67 Result AudioProxyDevice::openOutputStream(
68     hidl_bitfield<AudioOutputFlag> flags, const AudioConfig& hidlConfig,
69     std::unique_ptr<AudioProxyStreamOut>* streamOut,
70     AudioConfig* hidlConfigOut) {
71   audio_proxy_config_t config = toAudioProxyConfig(hidlConfig);
72 
73   audio_proxy_stream_out_t* stream = nullptr;
74   int ret = mDevice->open_output_stream(
75       mDevice, static_cast<audio_proxy_output_flags_t>(flags), &config,
76       &stream);
77 
78   if (stream) {
79     if (!isValidStreamOut(stream)) {
80       mDevice->close_output_stream(mDevice, stream);
81       return Result::NOT_SUPPORTED;
82     }
83 
84     *streamOut = std::make_unique<AudioProxyStreamOut>(stream, mDevice);
85   }
86 
87   // Pass the config out even if open_output_stream returns error, as the
88   // suggested config, so that audio service can re-open the stream with
89   // suggested config.
90   *hidlConfigOut = toHidlAudioConfig(config);
91   return toResult(ret);
92 }
93 
94 }  // namespace CPP_VERSION
95 }  // namespace audio_proxy
96