Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Bluetooth / Tizen.Network.Bluetooth / BluetoothAvrcpImpl.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 using System;
18
19 namespace Tizen.Network.Bluetooth
20 {
21     internal class BluetoothAvrcpImpl : IDisposable
22     {
23         private event EventHandler<TargetConnectionStateChangedEventArgs> _targetConnectionChanged;
24         private event EventHandler<EqualizerStateChangedEventArgs> _equalizerStateChanged;
25         private event EventHandler<RepeatModeChangedEventArgs> _repeatModeChanged;
26         private event EventHandler<ScanModeChangedEventArgs> _scanModeChanged;
27         private event EventHandler<ShuffleModeChangedeventArgs> _shuffleModeChanged;
28
29         private Interop.Bluetooth.TargetConnectionStateChangedCallback _targetConnectionChangedCallback;
30         private Interop.Bluetooth.EqualizerStateChangedCallback _equalizerStateChangedCallback;
31         private Interop.Bluetooth.RepeatModeChangedCallback _repeatModeChangedCallback;
32         private Interop.Bluetooth.ShuffleModeChangedCallback _shuffleModeChangedCallback;
33         private Interop.Bluetooth.ScanModeChangedCallback _scanModeChangedCallback;
34
35         private static BluetoothAvrcpImpl _instance = new BluetoothAvrcpImpl();
36         private bool disposed = false;
37
38         internal event EventHandler<TargetConnectionStateChangedEventArgs> TargetConnectionStateChanged
39         {
40             add
41             {
42                 _targetConnectionChanged += value;
43             }
44             remove
45             {
46                 _targetConnectionChanged -= value;
47             }
48         }
49
50         internal event EventHandler<EqualizerStateChangedEventArgs> EqualizerStateChanged
51         {
52             add
53             {
54                 if (_equalizerStateChanged == null)
55                 {
56                     RegisterEqualizerStateChangedEvent();
57                 }
58                 _equalizerStateChanged += value;
59             }
60             remove
61             {
62                 _equalizerStateChanged -= value;
63                 if (_equalizerStateChanged == null)
64                 {
65                     UnregisterEqualizerStateChangedEvent();
66                 }
67             }
68         }
69
70         internal event EventHandler<RepeatModeChangedEventArgs> RepeatModeChanged
71         {
72             add
73             {
74                 if (_repeatModeChanged == null)
75                 {
76                     RegisterRepeatModeChangedEvent();
77                 }
78                 _repeatModeChanged += value;
79             }
80             remove
81             {
82                 _repeatModeChanged -= value;
83                 if (_repeatModeChanged == null)
84                 {
85                     UnregisterRepeatModeChangedEvent();
86                 }
87             }
88         }
89
90         internal event EventHandler<ShuffleModeChangedeventArgs> ShuffleModeChanged
91         {
92             add
93             {
94                 if (_shuffleModeChanged == null)
95                 {
96                     RegisterShuffleModeChangedEvent();
97                 }
98                 _shuffleModeChanged += value;
99             }
100             remove
101             {
102                 _shuffleModeChanged -= value;
103                 if (_shuffleModeChanged == null)
104                 {
105                     UnregisterShuffleModeChangedEvent();
106                 }
107             }
108         }
109
110         internal event EventHandler<ScanModeChangedEventArgs> ScanModeChanged
111         {
112             add
113             {
114                 if (_scanModeChanged == null)
115                 {
116                     RegisterScanModeChangedEvent();
117                 }
118                 _scanModeChanged += value;
119             }
120             remove
121             {
122                 _scanModeChanged -= value;
123                 if (_scanModeChanged == null)
124                 {
125                     UnregisterScanModeChangedEvent();
126                 }
127             }
128         }
129
130         private void RegisterEqualizerStateChangedEvent()
131         {
132             _equalizerStateChangedCallback = (int equalizer, IntPtr userData) =>
133             {
134                 if (_equalizerStateChanged != null)
135                 {
136                     EqualizerState state = (EqualizerState) equalizer;
137                     _equalizerStateChanged(null, new EqualizerStateChangedEventArgs(state));
138                 }
139             };
140             int ret = Interop.Bluetooth.SetEqualizerStateChangedCallback(_equalizerStateChangedCallback, IntPtr.Zero);
141             if (ret != (int)BluetoothError.None)
142             {
143                 Log.Error(Globals.LogTag, "Failed to set equalizer state changed callback, Error - " + (BluetoothError)ret);
144             }
145         }
146         private void UnregisterEqualizerStateChangedEvent()
147         {
148             int ret = Interop.Bluetooth.UnsetEqualizerStateChangedCallback();
149             if (ret != (int)BluetoothError.None)
150             {
151                 Log.Error(Globals.LogTag, "Failed to unset equalizer state changed callback, Error - " + (BluetoothError)ret);
152             }
153         }
154
155         private void RegisterRepeatModeChangedEvent()
156         {
157             _repeatModeChangedCallback = (int repeat, IntPtr userData) =>
158             {
159                 if (_repeatModeChanged != null)
160                 {
161                     RepeatMode mode = (RepeatMode)repeat;
162                     _repeatModeChanged(null, new RepeatModeChangedEventArgs(mode));
163                 }
164             };
165             int ret = Interop.Bluetooth.SetRepeatModeChangedCallback(_repeatModeChangedCallback, IntPtr.Zero);
166             if (ret != (int)BluetoothError.None)
167             {
168                 Log.Error(Globals.LogTag, "Failed to set repeat mode changed callback, Error - " + (BluetoothError)ret);
169             }
170         }
171         private void UnregisterRepeatModeChangedEvent()
172         {
173             int ret = Interop.Bluetooth.UnsetRepeatModeChangedCallback();
174             if (ret != (int)BluetoothError.None)
175             {
176                 Log.Error(Globals.LogTag, "Failed to unset repeat mode changed callback, Error - " + (BluetoothError)ret);
177             }
178         }
179
180         private void RegisterShuffleModeChangedEvent()
181         {
182             Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent");
183             _shuffleModeChangedCallback = (int shuffle, IntPtr userData) =>
184             {
185                 Log.Debug (Globals.LogTag, "inside RegisterShuffleModeChangedEvent callback");
186                 if (_shuffleModeChanged != null)
187                 {
188                     ShuffleMode mode = (ShuffleMode) shuffle;
189                     _shuffleModeChanged(null, new ShuffleModeChangedeventArgs(mode));
190                 }
191             };
192             int ret = Interop.Bluetooth.SetShuffleModeChangedCallback(_shuffleModeChangedCallback, IntPtr.Zero);
193             if (ret != (int)BluetoothError.None)
194             {
195                 Log.Debug (Globals.LogTag, "failed inside RegisterShuffleModeChangedEvent");
196                 Log.Error(Globals.LogTag, "Failed to set shuffle mode changed callback, Error - " + (BluetoothError)ret);
197             }
198         }
199         private void UnregisterShuffleModeChangedEvent()
200         {
201             int ret = Interop.Bluetooth.UnsetShuffleModeChangedCallback();
202             if (ret != (int)BluetoothError.None)
203             {
204                 Log.Error(Globals.LogTag, "Failed to unset shuffle mode changed callback, Error - " + (BluetoothError)ret);
205             }
206         }
207
208         private void RegisterScanModeChangedEvent()
209         {
210             _scanModeChangedCallback = (int scan, IntPtr userData) =>
211             {
212                 if (_scanModeChanged != null)
213                 {
214                     ScanMode mode = (ScanMode) scan;
215                     _scanModeChanged(null, new ScanModeChangedEventArgs(mode));
216                 }
217             };
218             int ret = Interop.Bluetooth.SetScanModeChangedCallback(_scanModeChangedCallback, IntPtr.Zero);
219             if (ret != (int)BluetoothError.None)
220             {
221                 Log.Error(Globals.LogTag, "Failed to set scan mode changed callback, Error - " + (BluetoothError)ret);
222             }
223         }
224         private void UnregisterScanModeChangedEvent()
225         {
226             int ret = Interop.Bluetooth.UnsetScanModeChangedCallback();
227             if (ret != (int)BluetoothError.None)
228             {
229                 Log.Error(Globals.LogTag, "Failed to unset scan mode changed callback, Error - " + (BluetoothError)ret);
230             }
231         }
232
233         private void targetInitialize()
234         {
235             if (Globals.IsInitialize)
236             {
237                 _targetConnectionChangedCallback = (bool connected, string deviceAddress, IntPtr userData) =>
238                 {
239                     if (_targetConnectionChanged != null)
240                     {
241                         _targetConnectionChanged(null, new TargetConnectionStateChangedEventArgs(connected, deviceAddress));
242                     }
243                 };
244
245                 int ret = Interop.Bluetooth.InitializeAvrcp(_targetConnectionChangedCallback, IntPtr.Zero);
246                 if (ret != (int)BluetoothError.None)
247                 {
248                     Log.Error (Globals.LogTag, "Failed to initialize bluetooth avrcp, Error - " + (BluetoothError)ret);
249                     BluetoothErrorFactory.ThrowBluetoothException(ret);
250                 }
251                 else
252                 {
253                     Globals.IsAudioInitialize = true;
254                 }
255             }
256             else
257             {
258                 Log.Error(Globals.LogTag, "Failed to initialize Avrcp, BT not initialized");
259                 BluetoothErrorFactory.ThrowBluetoothException((int)BluetoothError.NotInitialized);
260             }
261         }
262
263         private void targetDeinitialize()
264         {
265             if (Globals.IsAudioInitialize)
266             {
267                 int ret = Interop.Bluetooth.DeinitializeAvrcp();
268                 if (ret != (int)BluetoothError.None)
269                 {
270                     Log.Error (Globals.LogTag, "Failed to deinitialize bluetooth avrcp, Error - " + (BluetoothError)ret);
271                     BluetoothErrorFactory.ThrowBluetoothException(ret);
272                 }
273                 else
274                 {
275                     Globals.IsAudioInitialize = false;
276                 }
277             }
278         }
279
280         internal void NotifyEqualizeState(EqualizerState state)
281         {
282             int ret = Interop.Bluetooth.NotifyEqualizerState((int)state);
283             if (ret != (int)BluetoothError.None)
284             {
285                 Log.Error(Globals.LogTag, "Failed to notify equalizer state to remote device, Error - " + (BluetoothError)ret);
286                 BluetoothErrorFactory.ThrowBluetoothException(ret);
287             }
288         }
289
290         internal void NotifyRepeatMode(RepeatMode repeat)
291         {
292             int ret = Interop.Bluetooth.NotifyRepeatMode((int)repeat);
293             if (ret != (int)BluetoothError.None)
294             {
295                 Log.Error(Globals.LogTag, "Failed to notify repeat mode to remote device, Error - " + (BluetoothError)ret);
296                 BluetoothErrorFactory.ThrowBluetoothException(ret);
297             }
298         }
299
300         internal void NotifyShuffleMode(ShuffleMode shuffle)
301         {
302             int ret = Interop.Bluetooth.NotifyShuffleMode((int)shuffle);
303             if (ret != (int)BluetoothError.None)
304             {
305                 Log.Error(Globals.LogTag, "Failed to notify shuffle mode to remote device, Error - " + (BluetoothError)ret);
306                 BluetoothErrorFactory.ThrowBluetoothException(ret);
307             }
308         }
309
310         internal void NotifyScanMode(ScanMode scan)
311         {
312             int ret = Interop.Bluetooth.NotifyScanMode((int)scan);
313             if (ret != (int)BluetoothError.None)
314             {
315                 Log.Error(Globals.LogTag, "Failed to notify scan mode to remote device, Error - " + (BluetoothError)ret);
316                 BluetoothErrorFactory.ThrowBluetoothException(ret);
317             }
318         }
319
320         internal void NotifyPlayerState(PlayerState state)
321         {
322             int ret = Interop.Bluetooth.NotifyPlayerState((int)state);
323             if (ret != (int)BluetoothError.None)
324             {
325                 Log.Error(Globals.LogTag, "Failed to notify player state to remote device, Error - " + (BluetoothError)ret);
326                 BluetoothErrorFactory.ThrowBluetoothException(ret);
327             }
328         }
329
330         internal void NotifyCurrentPosition(uint position)
331         {
332             int ret = Interop.Bluetooth.NotifyCurrentPosition(position);
333             if (ret != (int)BluetoothError.None)
334             {
335                 Log.Error(Globals.LogTag, "Failed to notify position to remote device, Error - " + (BluetoothError)ret);
336                 BluetoothErrorFactory.ThrowBluetoothException(ret);
337             }
338         }
339
340         internal void NotifyTrack(Track trackData)
341         {
342             string title = trackData.Title;
343             string artist = trackData.Artist;
344             string album = trackData.Album;
345             string genre = trackData.Genre;
346             uint trackNum = trackData.TrackNum;
347             uint totalTracks = trackData.TotalTracks;
348             uint duration = trackData.Duration;
349
350             int ret = Interop.Bluetooth.NotifyTrack(title, artist, album, genre, trackNum, totalTracks, duration);
351             if (ret != (int)BluetoothError.None)
352             {
353                 Log.Error(Globals.LogTag, "Failed to notify track data to the remote device, Error - " + (BluetoothError)ret);
354                 BluetoothErrorFactory.ThrowBluetoothException(ret);
355             }
356         }
357
358         internal static BluetoothAvrcpImpl Instance
359         {
360             get
361             {
362                 return _instance;
363             }
364         }
365
366         private BluetoothAvrcpImpl()
367         {
368             targetInitialize();
369         }
370
371         ~BluetoothAvrcpImpl()
372         {
373             Dispose(false);
374         }
375
376         public void Dispose()
377         {
378             Dispose(true);
379             GC.SuppressFinalize(this);
380         }
381
382         private void Dispose(bool disposing)
383         {
384             if (disposed)
385                 return;
386
387             if (disposing)
388             {
389                 // Free managed objects.
390             }
391             //Free unmanaged objects
392             targetDeinitialize();
393             RemoveAllRegisteredEvent();
394             disposed = true;
395         }
396
397         private void RemoveAllRegisteredEvent()
398         {
399             //unregister all remaining events when this object is released.
400             if (_equalizerStateChanged != null)
401             {
402                 UnregisterEqualizerStateChangedEvent();
403             }
404             if (_repeatModeChanged != null)
405             {
406                 UnregisterRepeatModeChangedEvent();
407             }
408             if (_scanModeChanged != null)
409             {
410                 UnregisterScanModeChangedEvent();
411             }
412             if (_shuffleModeChanged != null)
413             {
414                 UnregisterShuffleModeChangedEvent();
415             }
416         }
417     }
418 }
419