• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <time.h>
20 #include <mutex>
21 
22 #include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioProvider.h>
23 #include <android/hardware/bluetooth/audio/2.0/types.h>
24 #include <fmq/MessageQueue.h>
25 #include <hardware/audio.h>
26 
27 #include "common/message_loop_thread.h"
28 
29 #define BLUETOOTH_AUDIO_HAL_PROP_DISABLED "persist.bluetooth.bluetooth_audio_hal.disabled"
30 
31 namespace bluetooth {
32 namespace audio {
33 
34 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
35 using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
36 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
37 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
38 using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
39 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
40 using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
41 using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
42 using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
43 using ::android::hardware::bluetooth::audio::V2_0::SessionType;
44 using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
45 using BluetoothAudioStatus =
46     ::android::hardware::bluetooth::audio::V2_0::Status;
47 
48 enum class BluetoothAudioCtrlAck : uint8_t {
49   SUCCESS_FINISHED = 0,
50   PENDING,
51   FAILURE_UNSUPPORTED,
52   FAILURE_BUSY,
53   FAILURE_DISCONNECTING,
54   FAILURE
55 };
56 
57 std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
58 
BluetoothAudioCtrlAckToHalStatus(const BluetoothAudioCtrlAck & ack)59 inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
60     const BluetoothAudioCtrlAck& ack) {
61   switch (ack) {
62     case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
63       return BluetoothAudioStatus::SUCCESS;
64     case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
65       return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
66     case BluetoothAudioCtrlAck::PENDING:
67       return BluetoothAudioStatus::FAILURE;
68     case BluetoothAudioCtrlAck::FAILURE_BUSY:
69       return BluetoothAudioStatus::FAILURE;
70     case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
71       return BluetoothAudioStatus::FAILURE;
72     default:
73       return BluetoothAudioStatus::FAILURE;
74   }
75 }
76 
77 // An IBluetoothTransportInstance needs to be implemented by a Bluetooth audio
78 // transport, such as A2DP or Hearing Aid, to handle callbacks from Audio HAL.
79 class IBluetoothTransportInstance {
80  public:
IBluetoothTransportInstance(SessionType sessionType,AudioConfiguration audioConfig)81   IBluetoothTransportInstance(SessionType sessionType,
82                               AudioConfiguration audioConfig)
83       : session_type_(sessionType), audio_config_(std::move(audioConfig)){};
84   virtual ~IBluetoothTransportInstance() = default;
85 
GetSessionType()86   SessionType GetSessionType() const { return session_type_; }
87 
GetAudioConfiguration()88   AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
89 
UpdateAudioConfiguration(const AudioConfiguration & audio_config)90   void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
91     audio_config_ = audio_config;
92   }
93 
94   virtual BluetoothAudioCtrlAck StartRequest() = 0;
95 
96   virtual BluetoothAudioCtrlAck SuspendRequest() = 0;
97 
98   virtual void StopRequest() = 0;
99 
100   virtual bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
101                                        uint64_t* total_bytes_readed,
102                                        timespec* data_position) = 0;
103 
104   virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
105 
106   // Invoked when the transport is requested to reset presentation position
107   virtual void ResetPresentationPosition() = 0;
108 
109   // Invoked when the transport is requested to log bytes read
110   virtual void LogBytesRead(size_t bytes_readed) = 0;
111 
112  private:
113   const SessionType session_type_;
114   AudioConfiguration audio_config_;
115 };
116 
117 // common object is shared between different kind of SessionType
118 class BluetoothAudioDeathRecipient;
119 
120 // The client interface connects an IBluetoothTransportInstance to
121 // IBluetoothAudioProvider and helps to route callbacks to
122 // IBluetoothTransportInstance
123 class BluetoothAudioClientInterface {
124  public:
125   // Constructs an BluetoothAudioClientInterface to communicate to
126   // BluetoothAudio HAL. |sink| is the implementation for the transport, and
127   // |message_loop| is the thread where callbacks are invoked.
128   BluetoothAudioClientInterface(
129       IBluetoothTransportInstance* sink,
130       bluetooth::common::MessageLoopThread* message_loop);
131 
132   ~BluetoothAudioClientInterface();
133 
IsValid()134   bool IsValid() const {
135     return provider_ != nullptr;
136   }
137 
138   std::vector<AudioCapabilities> GetAudioCapabilities() const;
139 
140   bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
141 
142   int StartSession();
143 
144   void StreamStarted(const BluetoothAudioCtrlAck& ack);
145 
146   void StreamSuspended(const BluetoothAudioCtrlAck& ack);
147 
148   int EndSession();
149 
150   // Read data from audio  HAL through fmq
151   size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
152 
153   // Write data to audio HAL through fmq
154   size_t WriteAudioData(uint8_t* p_buf, uint32_t len);
155 
156   // Renew the connection and usually is used when HIDL restarted
157   void RenewAudioProviderAndSession();
158 
159   static constexpr PcmParameters kInvalidPcmConfiguration = {
160       .sampleRate = SampleRate::RATE_UNKNOWN,
161       .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
162       .channelMode = ChannelMode::UNKNOWN};
163 
164  private:
165   // Helper function to connect to an IBluetoothAudioProvider
166   void fetch_audio_provider();
167 
168   mutable std::mutex internal_mutex_;
169   IBluetoothTransportInstance* sink_;
170   android::sp<IBluetoothAudioProvider> provider_;
171   std::vector<AudioCapabilities> capabilities_;
172   bool session_started_;
173   std::unique_ptr<::android::hardware::MessageQueue<
174       uint8_t, ::android::hardware::kSynchronizedReadWrite>>
175       mDataMQ;
176   android::sp<BluetoothAudioDeathRecipient> death_recipient_;
177 };
178 
179 }  // namespace audio
180 }  // namespace bluetooth
181