• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
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 
16 #include "audio_bluetooth_manager.h"
17 
18 #include "audio_info.h"
19 #include "audio_errors.h"
20 #include "audio_log.h"
21 #include "bluetooth_def.h"
22 #include "hdf_remote_service.h"
23 #include "servmgr_hdi.h"
24 
25 namespace OHOS {
26 namespace Bluetooth {
27 using namespace AudioStandard;
28 
29 IDeviceStatusObserver *g_deviceObserver = nullptr;
30 A2dpSource *AudioA2dpManager::a2dpInstance_ = nullptr;
31 AudioA2dpListener AudioA2dpManager::a2dpListener_;
32 HandsFreeAudioGateway *AudioHfpManager::hfpInstance_ = nullptr;
33 AudioHfpListener AudioHfpManager::hfpListener_;
34 int AudioA2dpManager::connectionState_ = static_cast<int>(BTConnectState::DISCONNECTED);
35 bool AudioA2dpManager::bluetoothSinkLoaded_ = false;
36 BluetoothRemoteDevice AudioA2dpManager::bluetoothRemoteDevice_;
37 HdfRemoteService *g_hdiService = nullptr;
38 HdfRemoteService *g_audioSessionService = nullptr;
39 constexpr const char *AUDIO_BLUETOOTH_SERVICE_NAME = "audio_bluetooth_hdi_service";
40 
41 std::mutex g_deviceLock;
42 std::mutex g_a2dpInstanceLock;
43 
GetAudioStreamInfo(A2dpCodecInfo codecInfo,AudioStreamInfo & audioStreamInfo)44 static bool GetAudioStreamInfo(A2dpCodecInfo codecInfo, AudioStreamInfo &audioStreamInfo)
45 {
46     switch (codecInfo.sampleRate) {
47         case A2DP_SBC_SAMPLE_RATE_48000_USER:
48             audioStreamInfo.samplingRate = SAMPLE_RATE_48000;
49             break;
50         case A2DP_SBC_SAMPLE_RATE_44100_USER:
51             audioStreamInfo.samplingRate = SAMPLE_RATE_44100;
52             break;
53         case A2DP_SBC_SAMPLE_RATE_32000_USER:
54             audioStreamInfo.samplingRate = SAMPLE_RATE_32000;
55             break;
56         case A2DP_SBC_SAMPLE_RATE_16000_USER:
57             audioStreamInfo.samplingRate = SAMPLE_RATE_16000;
58             break;
59         default:
60             return false;
61     }
62 
63     switch (codecInfo.bitsPerSample) {
64         case A2DP_SAMPLE_BITS_16_USER:
65             audioStreamInfo.format = SAMPLE_S16LE;
66             break;
67         case A2DP_SAMPLE_BITS_24_USER:
68             audioStreamInfo.format = SAMPLE_S24LE;
69             break;
70         case A2DP_SAMPLE_BITS_32_USER:
71             audioStreamInfo.format = SAMPLE_S32LE;
72             break;
73         default:
74             return false;
75     }
76 
77     switch (codecInfo.channelMode) {
78         case A2DP_SBC_CHANNEL_MODE_STEREO_USER:
79             audioStreamInfo.channels = STEREO;
80             break;
81         case A2DP_SBC_CHANNEL_MODE_MONO_USER:
82             audioStreamInfo.channels = MONO;
83             break;
84         default:
85             return false;
86     }
87 
88     audioStreamInfo.encoding = ENCODING_PCM;
89 
90     return true;
91 }
92 
RegisterDeviceObserver(IDeviceStatusObserver & observer)93 int32_t RegisterDeviceObserver(IDeviceStatusObserver &observer)
94 {
95     std::lock_guard<std::mutex> deviceLock(g_deviceLock);
96     g_deviceObserver = &observer;
97     return SUCCESS;
98 }
99 
UnregisterDeviceObserver()100 void UnregisterDeviceObserver()
101 {
102     std::lock_guard<std::mutex> deviceLock(g_deviceLock);
103     g_deviceObserver = nullptr;
104 }
105 
RegisterBluetoothA2dpListener()106 void AudioA2dpManager::RegisterBluetoothA2dpListener()
107 {
108     AUDIO_INFO_LOG("Entered %{public}s", __func__);
109 
110     std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
111 
112     a2dpInstance_ = A2dpSource::GetProfile();
113     CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "Failed to obtain A2DP profile instance");
114 
115     a2dpInstance_->RegisterObserver(&a2dpListener_);
116 }
117 
UnregisterBluetoothA2dpListener()118 void AudioA2dpManager::UnregisterBluetoothA2dpListener()
119 {
120     AUDIO_INFO_LOG("Entered %{public}s", __func__);
121 
122     std::lock_guard<std::mutex> a2dpLock(g_a2dpInstanceLock);
123 
124     CHECK_AND_RETURN_LOG(a2dpInstance_ != nullptr, "A2DP profile instance unavailable");
125 
126     a2dpInstance_->DeregisterObserver(&a2dpListener_);
127     a2dpInstance_ = nullptr;
128 }
129 
ConnectBluetoothA2dpSink()130 void AudioA2dpManager::ConnectBluetoothA2dpSink()
131 {
132     // Update device when hdi service is available
133     if (connectionState_ != static_cast<int>(BTConnectState::CONNECTED)) {
134         AUDIO_ERR_LOG("bluetooth state is not on");
135         return;
136     }
137 
138     std::lock_guard<std::mutex> deviceLock(g_deviceLock);
139 
140     if (g_deviceObserver == nullptr) {
141         AUDIO_INFO_LOG("device observer is null");
142         return;
143     }
144 
145     AudioStreamInfo streamInfo = {};
146     A2dpCodecStatus codecStatus = A2dpSource::GetProfile()->GetCodecStatus(bluetoothRemoteDevice_);
147     if (!GetAudioStreamInfo(codecStatus.codecInfo, streamInfo)) {
148         AUDIO_ERR_LOG("OnConnectionStateChanged: Unsupported a2dp codec info");
149         return;
150     }
151 
152     g_deviceObserver->OnDeviceStatusUpdated(DEVICE_TYPE_BLUETOOTH_A2DP, true,
153         bluetoothRemoteDevice_.GetDeviceAddr(), bluetoothRemoteDevice_.GetDeviceName(), streamInfo);
154     bluetoothSinkLoaded_ = true;
155 }
156 
DisconnectBluetoothA2dpSink()157 void AudioA2dpManager::DisconnectBluetoothA2dpSink()
158 {
159     if (!bluetoothSinkLoaded_) {
160         AUDIO_INFO_LOG("DisconnectBluetoothA2dpSink: bluetooth is disconnected");
161         return;
162     }
163 
164     int connectionState = static_cast<int>(BTConnectState::DISCONNECTED);
165     a2dpListener_.OnConnectionStateChanged(bluetoothRemoteDevice_, connectionState);
166 }
167 
OnConnectionStateChanged(const BluetoothRemoteDevice & device,int state)168 void AudioA2dpListener::OnConnectionStateChanged(const BluetoothRemoteDevice &device, int state)
169 {
170     AUDIO_INFO_LOG("OnConnectionStateChanged: state: %{public}d", state);
171 
172     // Record connection state and device for hdi start time to check
173     AudioA2dpManager::SetConnectionState(state);
174     if (state == static_cast<int>(BTConnectState::CONNECTED)) {
175         AudioA2dpManager::SetBluetoothRemoteDevice(device);
176 
177         struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();
178         if (serviceMgr == nullptr) {
179             AUDIO_ERR_LOG("HDIServiceManagerGet failed!");
180             return;
181         }
182         g_hdiService = serviceMgr->GetService(serviceMgr, AUDIO_BLUETOOTH_SERVICE_NAME);
183         HDIServiceManagerRelease(serviceMgr);
184 
185         if (g_hdiService != nullptr) {
186             AUDIO_INFO_LOG("Remote GetService [g_hdiService] SUCCESS!");
187             AudioA2dpManager::ConnectBluetoothA2dpSink();
188         }
189     }
190 
191     // Currently disconnect need to be done in OnConnectionStateChanged instead of hdi service stopped
192     if (state == static_cast<int>(BTConnectState::DISCONNECTED)) {
193         std::lock_guard<std::mutex> deviceLock(g_deviceLock);
194 
195         if (g_deviceObserver == nullptr) {
196             AUDIO_INFO_LOG("device observer is null");
197             return;
198         }
199 
200         AudioStreamInfo streamInfo = {};
201         g_deviceObserver->OnDeviceStatusUpdated(DEVICE_TYPE_BLUETOOTH_A2DP, false,
202             device.GetDeviceAddr(), device.GetDeviceName(), streamInfo);
203         AudioA2dpManager::SetBluetoothSinkLoaded(false);
204     }
205 }
206 
OnConfigurationChanged(const BluetoothRemoteDevice & device,const A2dpCodecInfo & codecInfo,int error)207 void AudioA2dpListener::OnConfigurationChanged(const BluetoothRemoteDevice &device, const A2dpCodecInfo &codecInfo,
208     int error)
209 {
210     AUDIO_INFO_LOG("OnConfigurationChanged: sampleRate: %{public}d, channels: %{public}d, format: %{public}d",
211         codecInfo.sampleRate, codecInfo.channelMode, codecInfo.bitsPerSample);
212 
213     std::lock_guard<std::mutex> deviceLock(g_deviceLock);
214 
215     if (g_deviceObserver == nullptr) {
216         AUDIO_INFO_LOG("device observer is null");
217         return;
218     }
219 
220     AudioStreamInfo streamInfo = {};
221     if (!GetAudioStreamInfo(codecInfo, streamInfo)) {
222         AUDIO_ERR_LOG("OnConfigurationChanged: Unsupported a2dp codec info");
223         return;
224     }
225 
226     g_deviceObserver->OnDeviceConfigurationChanged(DEVICE_TYPE_BLUETOOTH_A2DP, device.GetDeviceAddr(),
227         device.GetDeviceName(), streamInfo);
228 }
229 
OnPlayingStatusChanged(const BluetoothRemoteDevice & device,int playingState,int error)230 void AudioA2dpListener::OnPlayingStatusChanged(const BluetoothRemoteDevice &device, int playingState, int error)
231 {
232     AUDIO_INFO_LOG("OnPlayingStatusChanged, state: %{public}d, error: %{public}d", playingState, error);
233 }
234 
RegisterBluetoothScoListener()235 void AudioHfpManager::RegisterBluetoothScoListener()
236 {
237     AUDIO_INFO_LOG("Entered %{public}s", __func__);
238     hfpInstance_ = HandsFreeAudioGateway::GetProfile();
239     CHECK_AND_RETURN_LOG(hfpInstance_ != nullptr, "Failed to obtain HFP AG profile instance");
240 
241     hfpInstance_->RegisterObserver(&hfpListener_);
242 }
243 
UnregisterBluetoothScoListener()244 void AudioHfpManager::UnregisterBluetoothScoListener()
245 {
246     AUDIO_INFO_LOG("Entered %{public}s", __func__);
247     CHECK_AND_RETURN_LOG(hfpInstance_ != nullptr, "HFP AG profile instance unavailable");
248 
249     hfpInstance_->DeregisterObserver(&hfpListener_);
250     hfpInstance_ = nullptr;
251 }
252 
OnScoStateChanged(const BluetoothRemoteDevice & device,int state)253 void AudioHfpListener::OnScoStateChanged(const BluetoothRemoteDevice &device, int state)
254 {
255     AUDIO_INFO_LOG("Entered %{public}s [%{public}d]", __func__, state);
256 
257     std::lock_guard<std::mutex> deviceLock(g_deviceLock);
258 
259     if (g_deviceObserver == nullptr) {
260         AUDIO_INFO_LOG("device observer is null");
261         return;
262     }
263 
264     HfpScoConnectState scoState = static_cast<HfpScoConnectState>(state);
265     if (scoState == HfpScoConnectState::SCO_CONNECTED || scoState == HfpScoConnectState::SCO_DISCONNECTED) {
266         AudioStreamInfo streamInfo = {};
267         bool isConnected = (scoState == HfpScoConnectState::SCO_CONNECTED) ? true : false;
268         g_deviceObserver->OnDeviceStatusUpdated(DEVICE_TYPE_BLUETOOTH_SCO, isConnected, device.GetDeviceAddr(),
269             device.GetDeviceName(), streamInfo);
270     }
271 }
272 
273 } // namespace Bluetooth
274 } // namespace OHOS
275