2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 namespace Tizen.Network.Bluetooth
21 internal class BluetoothAudioImpl : IDisposable
23 private event EventHandler<AudioConnectionStateChangedEventArgs> _audioConnectionChanged;
24 private Interop.Bluetooth.AudioConnectionStateChangedCallback _audioConnectionChangedCallback;
26 private event EventHandler<AgScoStateChangedEventArgs> _agScoStateChanged;
27 private Interop.Bluetooth.AgScoStateChangedCallback _agScoStateChangedCallback;
29 private static readonly Lazy<BluetoothAudioImpl> _instance = new Lazy<BluetoothAudioImpl>(() =>
31 return new BluetoothAudioImpl();
33 private bool disposed = false;
35 internal event EventHandler<AudioConnectionStateChangedEventArgs> AudioConnectionStateChanged
39 if (_audioConnectionChanged == null)
41 RegisterAudioConnectionChangedEvent();
43 _audioConnectionChanged += value;
47 _audioConnectionChanged -= value;
48 if (_audioConnectionChanged == null)
50 UnregisterAudioConnectionChangedEvent();
55 private void RegisterAudioConnectionChangedEvent()
57 _audioConnectionChangedCallback = (int result, bool connected, string deviceAddress, int profileType, IntPtr userData) =>
59 _audioConnectionChanged?.Invoke(this, new AudioConnectionStateChangedEventArgs(result, connected, deviceAddress, (BluetoothAudioProfileType)profileType));
61 int ret = Interop.Bluetooth.SetAudioConnectionStateChangedCallback(_audioConnectionChangedCallback, IntPtr.Zero);
62 if (ret != (int)BluetoothError.None)
64 Log.Error(Globals.LogTag, "Failed to set audio connection changed callback, Error - " + (BluetoothError)ret);
68 private void UnregisterAudioConnectionChangedEvent()
70 int ret = Interop.Bluetooth.UnsetAudioConnectionStateChangedCallback();
71 if (ret != (int)BluetoothError.None)
73 Log.Error(Globals.LogTag, "Failed to unset audio connection changed callback, Error - " + (BluetoothError)ret);
77 internal int Connect(string deviceAddress, BluetoothAudioProfileType type)
79 int ret = Interop.Bluetooth.Connect(deviceAddress, (int)type);
80 if (ret != (int)BluetoothError.None)
82 Log.Error(Globals.LogTag, "Failed to connect device with the given profile type, Error - " + (BluetoothError)ret);
87 internal int Disconnect(string deviceAddress, BluetoothAudioProfileType type)
89 int ret = Interop.Bluetooth.Disconnect(deviceAddress, (int)type);
90 if (ret != (int)BluetoothError.None)
92 Log.Error(Globals.LogTag, "Failed to disconnect device with the given profile type, Error - " + (BluetoothError)ret);
97 internal void OpenAgSco()
99 if (Globals.IsAudioInitialize)
101 int ret = Interop.Bluetooth.OpenAgSco();
102 if (ret != (int)BluetoothError.None)
104 Log.Error(Globals.LogTag, "Failed to open ag sco to remote device, Error - " + (BluetoothError)ret);
105 BluetoothErrorFactory.ThrowBluetoothException(ret);
110 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
114 internal void CloseAgSco()
116 if (Globals.IsAudioInitialize)
118 int ret = Interop.Bluetooth.CloseAgSco();
119 if (ret != (int)BluetoothError.None)
121 Log.Error(Globals.LogTag, "Failed to close ag sco to remote device, Error - " + (BluetoothError)ret);
122 BluetoothErrorFactory.ThrowBluetoothException(ret);
127 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
131 internal bool IsAgScoOpened
136 int ret = Interop.Bluetooth.IsAgScoOpened(out isOpened);
137 if (ret != (int)BluetoothError.None)
139 Log.Error(Globals.LogTag, "Failed to check whether an opened SCO exists or not., Error - " + (BluetoothError)ret);
145 internal event EventHandler<AgScoStateChangedEventArgs> AgScoStateChanged
149 if (_agScoStateChanged == null)
151 RegisterAgScoStateChangedEvent();
153 _agScoStateChanged += value;
157 _agScoStateChanged -= value;
158 if (_agScoStateChanged == null)
160 UnregisterAgScoStateChangedEvent();
165 private void RegisterAgScoStateChangedEvent()
167 _agScoStateChangedCallback = (int result, bool opened, IntPtr userData) =>
169 _agScoStateChanged?.Invoke(null, new AgScoStateChangedEventArgs(opened));
172 int ret = Interop.Bluetooth.SetAgScoStateChangedCallback(_agScoStateChangedCallback, IntPtr.Zero);
173 if (ret != (int)BluetoothError.None)
175 Log.Error(Globals.LogTag, "Failed to set ag sco state changed callback, Error - " + (BluetoothError)ret);
179 private void UnregisterAgScoStateChangedEvent()
181 int ret = Interop.Bluetooth.UnsetAgScoStateChangedCallback();
182 if (ret != (int)BluetoothError.None)
184 Log.Error(Globals.LogTag, "Failed to unset ag sco state changed callback, Error - " + (BluetoothError)ret);
188 internal void NotifyAgVoiceRecognitionState(bool enable)
190 if (Globals.IsAudioInitialize)
192 int ret = Interop.Bluetooth.NotifyAgVoiceRecognitionState(enable);
193 if (ret != (int)BluetoothError.None)
195 Log.Error(Globals.LogTag, "Failed to notify sco voice recognition state, Error - " + (BluetoothError)ret);
196 BluetoothErrorFactory.ThrowBluetoothException(ret);
201 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
205 internal static BluetoothAudioImpl Instance
209 return _instance.Value;
213 private BluetoothAudioImpl ()
215 Log.Info(Globals.LogTag, "Initializing audio");
219 ~BluetoothAudioImpl()
224 public void Dispose()
227 GC.SuppressFinalize(this);
230 private void Dispose(bool disposing)
237 // Free managed objects.
239 //Free unmanaged objects
241 RemoveAllRegisteredEvent();
245 private void initialize()
247 if (Globals.IsInitialize)
249 int ret = Interop.Bluetooth.InitializeAudio ();
250 if (ret != (int)BluetoothError.None)
252 Log.Error(Globals.LogTag, "Failed to initialize bluetoothaudio, Error - " + (BluetoothError)ret);
253 Globals.IsAudioInitialize = false;
254 BluetoothErrorFactory.ThrowBluetoothException (ret);
258 Globals.IsAudioInitialize = true;
263 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
267 private void deinitialize()
269 if (Globals.IsAudioInitialize) {
270 int ret = Interop.Bluetooth.DeinitializeAudio ();
271 if (ret != (int)BluetoothError.None) {
272 Log.Error (Globals.LogTag, "Failed to deinitialize bluetoothaudio, Error - " + (BluetoothError)ret);
277 private void RemoveAllRegisteredEvent()
279 if (_audioConnectionChanged != null)
281 UnregisterAudioConnectionChangedEvent();