1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "BTAudioHw"
18 
19 #include <android-base/logging.h>
20 #include <errno.h>
21 #include <hardware/hardware.h>
22 #include <log/log.h>
23 #include <malloc.h>
24 #include <string.h>
25 #include <system/audio.h>
26 
27 #include "stream_apis.h"
28 #include "utils.h"
29 
30 using ::android::bluetooth::audio::utils::GetAudioParamString;
31 using ::android::bluetooth::audio::utils::ParseAudioParams;
32 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)33 static int adev_set_parameters(struct audio_hw_device* dev,
34                                const char* kvpairs) {
35   LOG(VERBOSE) << __func__ << ": kevpairs=[" << kvpairs << "]";
36   std::unordered_map<std::string, std::string> params =
37       ParseAudioParams(kvpairs);
38   if (params.empty()) return 0;
39 
40   LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
41                << "]";
42   if (params.find("A2dpSuspended") == params.end()) {
43     return -ENOSYS;
44   }
45 
46   auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
47   std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
48   for (auto sout : bluetooth_device->opened_stream_outs_) {
49     if (sout->stream_out_.common.set_parameters != nullptr) {
50       sout->stream_out_.common.set_parameters(&sout->stream_out_.common,
51                                               kvpairs);
52     }
53   }
54   return 0;
55 }
56 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)57 static char* adev_get_parameters(const struct audio_hw_device* dev,
58                                  const char* keys) {
59   LOG(VERBOSE) << __func__ << ": keys=[" << keys << "]";
60   return strdup("");
61 }
62 
adev_init_check(const struct audio_hw_device * dev)63 static int adev_init_check(const struct audio_hw_device* dev) { return 0; }
64 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)65 static int adev_set_voice_volume(struct audio_hw_device* dev, float volume) {
66   LOG(VERBOSE) << __func__ << ": volume=" << volume;
67   return -ENOSYS;
68 }
69 
adev_set_master_volume(struct audio_hw_device * dev,float volume)70 static int adev_set_master_volume(struct audio_hw_device* dev, float volume) {
71   LOG(VERBOSE) << __func__ << ": volume=" << volume;
72   return -ENOSYS;
73 }
74 
adev_get_master_volume(struct audio_hw_device * dev,float * volume)75 static int adev_get_master_volume(struct audio_hw_device* dev, float* volume) {
76   return -ENOSYS;
77 }
78 
adev_set_master_mute(struct audio_hw_device * dev,bool muted)79 static int adev_set_master_mute(struct audio_hw_device* dev, bool muted) {
80   LOG(VERBOSE) << __func__ << ": mute=" << muted;
81   return -ENOSYS;
82 }
83 
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)84 static int adev_get_master_mute(struct audio_hw_device* dev, bool* muted) {
85   return -ENOSYS;
86 }
87 
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)88 static int adev_set_mode(struct audio_hw_device* dev, audio_mode_t mode) {
89   LOG(VERBOSE) << __func__ << ": mode=" << mode;
90   return 0;
91 }
92 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)93 static int adev_set_mic_mute(struct audio_hw_device* dev, bool state) {
94   LOG(VERBOSE) << __func__ << ": state=" << state;
95   return -ENOSYS;
96 }
97 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)98 static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state) {
99   return -ENOSYS;
100 }
101 
adev_dump(const audio_hw_device_t * device,int fd)102 static int adev_dump(const audio_hw_device_t* device, int fd) { return 0; }
103 
adev_close(hw_device_t * device)104 static int adev_close(hw_device_t* device) {
105   auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(device);
106   delete bluetooth_device;
107   return 0;
108 }
109 
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)110 static int adev_open(const hw_module_t* module, const char* name,
111                      hw_device_t** device) {
112   LOG(VERBOSE) << __func__ << ": name=[" << name << "]";
113   if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
114 
115   auto bluetooth_audio_device = new BluetoothAudioDevice{};
116   struct audio_hw_device* adev = &bluetooth_audio_device->audio_device_;
117   if (!adev) return -ENOMEM;
118 
119   adev->common.tag = HARDWARE_DEVICE_TAG;
120   adev->common.version = AUDIO_DEVICE_API_VERSION_2_0;
121   adev->common.module = (struct hw_module_t*)module;
122   adev->common.close = adev_close;
123 
124   adev->init_check = adev_init_check;
125   adev->set_voice_volume = adev_set_voice_volume;
126   adev->set_master_volume = adev_set_master_volume;
127   adev->get_master_volume = adev_get_master_volume;
128   adev->set_mode = adev_set_mode;
129   adev->set_mic_mute = adev_set_mic_mute;
130   adev->get_mic_mute = adev_get_mic_mute;
131   adev->set_parameters = adev_set_parameters;
132   adev->get_parameters = adev_get_parameters;
133   adev->get_input_buffer_size = adev_get_input_buffer_size;
134   adev->open_output_stream = adev_open_output_stream;
135   adev->close_output_stream = adev_close_output_stream;
136   adev->open_input_stream = adev_open_input_stream;
137   adev->close_input_stream = adev_close_input_stream;
138   adev->dump = adev_dump;
139   adev->set_master_mute = adev_set_master_mute;
140   adev->get_master_mute = adev_get_master_mute;
141 
142   *device = &adev->common;
143   return 0;
144 }
145 
146 static struct hw_module_methods_t hal_module_methods = {
147     .open = adev_open,
148 };
149 
150 struct audio_module HAL_MODULE_INFO_SYM = {
151     .common =
152         {
153             .tag = HARDWARE_MODULE_TAG,
154             .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
155             .hal_api_version = HARDWARE_HAL_API_VERSION,
156             .id = AUDIO_HARDWARE_MODULE_ID,
157             .name = "Bluetooth Audio HW HAL",
158             .author = "The Android Open Source Project",
159             .methods = &hal_module_methods,
160         },
161 };
162