• 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 <android/hardware/bluetooth/audio/2.0/types.h>
20 #include <hardware/audio.h>
21 #include <condition_variable>
22 #include <mutex>
23 #include <unordered_map>
24 
25 enum class BluetoothStreamState : uint8_t;
26 
27 namespace android {
28 namespace bluetooth {
29 namespace audio {
30 
31 // Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
32 // Session Control. All methods are not thread safe, so users must acquire a
33 // lock. Note: currently, in stream_apis.cc, if GetState() is only used for
34 // verbose logging, it is not locked, so the state may not be synchronized.
35 class BluetoothAudioPortOut {
36  public:
37   BluetoothAudioPortOut();
38   ~BluetoothAudioPortOut() = default;
39 
40   // Fetch output control / data path of BluetoothAudioPortOut and setup
41   // callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio
42   // HAL must delete this BluetoothAudioPortOut and return EINVAL to caller
43   bool SetUp(audio_devices_t devices);
44 
45   // Unregister this BluetoothAudioPortOut from BluetoothAudioSessionControl.
46   // Audio HAL must delete this BluetoothAudioPortOut after calling this.
47   void TearDown();
48 
49   // When the Audio framework / HAL tries to query audio config about format,
50   // channel mask and sample rate, it uses this function to fetch from the
51   // Bluetooth stack
52   bool LoadAudioConfig(audio_config_t* audio_cfg) const;
53 
54   // WAR to support Mono mode / 16 bits per sample
ForcePcmStereoToMono(bool force)55   void ForcePcmStereoToMono(bool force) {
56     is_stereo_to_mono_ = force;
57   }
58 
59   // When the Audio framework / HAL wants to change the stream state, it invokes
60   // these 3 functions to control the Bluetooth stack (Audio Control Path).
61   // Note: Both Start() and Suspend() will return ture when there are no errors.
62   // Called by Audio framework / HAL to start the stream
63   bool Start();
64   // Called by Audio framework / HAL to suspend the stream
65   bool Suspend();
66   // Called by Audio framework / HAL to stop the stream
67   void Stop();
68 
69   // The audio data path to the Bluetooth stack (Software encoding)
70   size_t WriteData(const void* buffer, size_t bytes) const;
71 
72   // Called by the Audio framework / HAL to fetch informaiton about audio frames
73   // presented to an external sink.
74   bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
75                                timespec* timestamp) const;
76 
77   // Called by the Audio framework / HAL when the metadata of the stream's
78   // source has been changed.
79   void UpdateMetadata(const source_metadata* source_metadata) const;
80 
81   // Return the current BluetoothStreamState
82   BluetoothStreamState GetState() const;
83 
84   // Set the current BluetoothStreamState
85   void SetState(BluetoothStreamState state);
86 
87  private:
88   BluetoothStreamState state_;
89   ::android::hardware::bluetooth::audio::V2_0::SessionType session_type_;
90   uint16_t cookie_;
91   mutable std::mutex cv_mutex_;
92   std::condition_variable internal_cv_;
93   // WR to support Mono: True if fetching Stereo and mixing into Mono
94   bool is_stereo_to_mono_ = false;
95 
96   // Check and initialize session type for |devices| If failed, this
97   // BluetoothAudioPortOut is not initialized and must be deleted.
98   bool init_session_type(audio_devices_t device);
99 
100   bool in_use() const;
101 
102   bool CondwaitState(BluetoothStreamState state);
103 
104   void ControlResultHandler(
105       const ::android::hardware::bluetooth::audio::V2_0::Status& status);
106   void SessionChangedHandler();
107 };
108 
109 }  // namespace audio
110 }  // namespace bluetooth
111 }  // namespace android
112