1 /*
2  * Copyright 2022 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 #pragma once
18 
19 #include <fmq/AidlMessageQueue.h>
20 #include <hardware/audio.h>
21 
22 #include <ctime>
23 #include <mutex>
24 #include <vector>
25 
26 #include "audio_aidl_interfaces.h"
27 #include "bluetooth_audio_port_impl.h"
28 #include "bta/le_audio/broadcaster/broadcaster_types.h"
29 #include "bta/le_audio/le_audio_types.h"
30 #include "transport_instance.h"
31 
32 // Keep after audio_aidl_interfaces.h because of <base/logging.h>
33 // conflicting definitions.
34 #include "a2dp_encoding.h"
35 
36 namespace bluetooth {
37 namespace audio {
38 namespace aidl {
39 namespace a2dp {
40 
41 using ::aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
42 using ::aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
43 using ::aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
44 using ::aidl::android::hardware::bluetooth::audio::A2dpStatus;
45 using ::aidl::android::hardware::bluetooth::audio::AudioCapabilities;
46 using ::aidl::android::hardware::bluetooth::audio::AudioConfiguration;
47 using ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus;
48 using ::aidl::android::hardware::bluetooth::audio::CodecId;
49 using ::aidl::android::hardware::bluetooth::audio::CodecInfo;
50 using ::aidl::android::hardware::bluetooth::audio::CodecParameters;
51 using ::aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv;
52 using ::aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv;
53 using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
54 using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
55 using ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
56 using ::aidl::android::hardware::bluetooth::audio::LatencyMode;
57 using ::aidl::android::hardware::bluetooth::audio::MetadataLtv;
58 using ::aidl::android::hardware::bluetooth::audio::PcmConfiguration;
59 
60 using ::aidl::android::hardware::common::fmq::MQDescriptor;
61 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
62 using ::android::AidlMessageQueue;
63 
64 using MqDataType = int8_t;
65 using MqDataMode = SynchronizedReadWrite;
66 using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
67 using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
68 
StatusToHalStatus(Status ack)69 inline BluetoothAudioStatus StatusToHalStatus(Status ack) {
70   switch (ack) {
71     case Status::SUCCESS:
72       return BluetoothAudioStatus::SUCCESS;
73     case Status::UNSUPPORTED_CODEC_CONFIGURATION:
74       return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
75     case Status::PENDING:
76     case Status::FAILURE:
77     default:
78       return BluetoothAudioStatus::FAILURE;
79   }
80 }
81 
82 /***
83  * The client interface connects an IBluetoothTransportInstance to
84  * IBluetoothAudioProvider and helps to route callbacks to
85  * IBluetoothTransportInstance
86  ***/
87 class BluetoothAudioClientInterface {
88 public:
89   BluetoothAudioClientInterface(IBluetoothTransportInstance* instance);
90   virtual ~BluetoothAudioClientInterface();
91 
92   bool IsValid() const;
GetTransportInstance()93   IBluetoothTransportInstance* GetTransportInstance() const { return transport_; }
94 
95   std::vector<AudioCapabilities> GetAudioCapabilities() const;
96 
97   static std::vector<AudioCapabilities> GetAudioCapabilities(SessionType session_type);
98   static std::optional<IBluetoothAudioProviderFactory::ProviderInfo> GetProviderInfo(
99           SessionType session_type,
100           std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory = nullptr);
101 
102   std::optional<A2dpStatus> ParseA2dpConfiguration(const CodecId& codec_id,
103                                                    const std::vector<uint8_t>& configuration,
104                                                    CodecParameters* codec_parameters) const;
105 
106   std::optional<A2dpConfiguration> GetA2dpConfiguration(
107           std::vector<A2dpRemoteCapabilities> const& remote_capabilities,
108           A2dpConfigurationHint const& hint) const;
109 
110   void StreamStarted(const Status& ack);
111 
112   void StreamSuspended(const Status& ack);
113 
114   int StartSession();
115 
116   /***
117    * Renew the connection and usually is used when aidl restarted
118    ***/
119   void RenewAudioProviderAndSession();
120 
121   int EndSession();
122 
123   bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
124 
125   bool SetAllowedLatencyModes(std::vector<LatencyMode> latency_modes);
126 
127   /***
128    * Read data from audio HAL through fmq
129    ***/
130   size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
131 
132   static constexpr PcmConfiguration kInvalidPcmConfiguration = {};
133 
134   static bool is_aidl_available();
135 
136 protected:
137   mutable std::mutex internal_mutex_;
138   /***
139    * Helper function to connect to an IBluetoothAudioProvider
140    ***/
141   void FetchAudioProvider();
142 
143   /***
144    * Invoked when binder died
145    ***/
146   static void binderDiedCallbackAidl(void* cookie_ptr);
147 
148   std::shared_ptr<IBluetoothAudioProvider> provider_;
149   std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
150 
151   bool session_started_;
152   std::unique_ptr<DataMQ> data_mq_;
153 
154   ::ndk::ScopedAIBinder_DeathRecipient death_recipient_;
155   // static constexpr const char* kDefaultAudioProviderFactoryInterface =
156   //     "android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory/default";
157   static inline const std::string kDefaultAudioProviderFactoryInterface =
158           std::string() + IBluetoothAudioProviderFactory::descriptor + "/default";
159 
160 private:
161   IBluetoothTransportInstance* transport_;
162   std::vector<AudioCapabilities> capabilities_;
163   std::vector<LatencyMode> latency_modes_;
164 
165   static constexpr int kDefaultDataReadTimeoutMs = 10;
166   static constexpr int kDefaultDataReadPollIntervalMs = 1;
167 };
168 
169 }  // namespace a2dp
170 }  // namespace aidl
171 }  // namespace audio
172 }  // namespace bluetooth
173