Merge remote-tracking branch 'origin/master' into tizen
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / AudioManager / AudioManager.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 using System.Collections.Generic;
19
20 namespace Tizen.Multimedia
21 {
22     /// <summary>
23     /// Provides the ability to control volume levels and monitor audio devices.
24     /// </summary>
25     /// <since_tizen> 3 </since_tizen>
26     public static class AudioManager
27     {
28         static AudioManager()
29         {
30             VolumeController = new AudioVolume();
31         }
32
33         /// <summary>
34         /// Gets the volume controller.
35         /// </summary>
36         /// <value>The <see cref="AudioVolume"/>.</value>
37         /// <since_tizen> 3 </since_tizen>
38         public static AudioVolume VolumeController { get; }
39
40         /// <summary>
41         /// Gets the all devices currently connected.
42         /// </summary>
43         /// <returns>An IEnumerable&lt;AudioDevice&gt; that contains connected devices.</returns>
44         /// <since_tizen> 4 </since_tizen>
45         public static IEnumerable<AudioDevice> GetConnectedDevices()
46         {
47             IntPtr deviceListHandle = IntPtr.Zero;
48
49             try
50             {
51                 var ret = Interop.AudioDevice.GetDeviceList(AudioDeviceOptions.All, out deviceListHandle);
52
53                 List<AudioDevice> result = new List<AudioDevice>();
54
55                 if (ret == AudioManagerError.NoData)
56                 {
57                     return result;
58                 }
59
60                 ret.Validate("Failed to get connected devices");
61
62                 while (ret == AudioManagerError.None)
63                 {
64                     ret = Interop.AudioDevice.GetNextDevice(deviceListHandle, out var deviceHandle);
65
66                     if (ret == AudioManagerError.NoData)
67                     {
68                         break;
69                     }
70
71                     ret.Validate("Failed to get connected devices");
72
73                     result.Add(new AudioDevice(deviceHandle));
74                 }
75                 return result;
76             }
77             finally
78             {
79                 Interop.AudioDevice.FreeDeviceList(deviceListHandle);
80             }
81         }
82
83         #region DeviceConnectionChanged event
84         private static int _deviceConnectionChangedCallbackId = -1;
85
86         private static Interop.AudioDevice.ConnectionChangedCallback _audioDeviceConnectionChangedCallback;
87         private static EventHandler<AudioDeviceConnectionChangedEventArgs> _audioDeviceConnectionChanged;
88         private static object _audioDeviceConnectionLock = new object();
89
90         /// <summary>
91         /// Occurs when the state of a connection of an audio device changes.
92         /// </summary>
93         /// <since_tizen> 3 </since_tizen>
94         public static event EventHandler<AudioDeviceConnectionChangedEventArgs> DeviceConnectionChanged
95         {
96             add
97             {
98                 lock (_audioDeviceConnectionLock)
99                 {
100                     if (_audioDeviceConnectionChanged == null)
101                     {
102                         RegisterAudioDeviceEvent();
103                     }
104                     _audioDeviceConnectionChanged += value;
105                 }
106             }
107             remove
108             {
109                 if (value == null)
110                 {
111                     return;
112                 }
113
114                 lock (_audioDeviceConnectionLock)
115                 {
116                     if (_audioDeviceConnectionChanged == value)
117                     {
118                         UnregisterDeviceConnectionChangedEvent();
119                     }
120                     _audioDeviceConnectionChanged -= value;
121                 }
122             }
123         }
124
125         private static void RegisterAudioDeviceEvent()
126         {
127             _audioDeviceConnectionChangedCallback = (IntPtr device, bool isConnected, IntPtr userData) =>
128             {
129                 _audioDeviceConnectionChanged?.Invoke(null,
130                     new AudioDeviceConnectionChangedEventArgs(new AudioDevice(device), isConnected));
131             };
132
133             Interop.AudioDevice.AddDeviceConnectionChangedCallback(AudioDeviceOptions.All,
134                 _audioDeviceConnectionChangedCallback, IntPtr.Zero, out _deviceConnectionChangedCallbackId).
135                 Validate("Unable to add device connection changed callback");
136         }
137
138         private static void UnregisterDeviceConnectionChangedEvent()
139         {
140             Interop.AudioDevice.RemoveDeviceConnectionChangedCallback(_deviceConnectionChangedCallbackId).
141                 Validate("Unable to remove device connection changed callback");
142         }
143         #endregion
144
145         #region DeviceStateChanged event
146         private static int _deviceStateChangedCallbackId = -1;
147
148         private static Interop.AudioDevice.StateChangedCallback _audioDeviceStateChangedCallback;
149         private static EventHandler<AudioDeviceStateChangedEventArgs> _audioDeviceStateChanged;
150         private static object _audioDeviceStateLock = new object();
151
152         /// <summary>
153         /// Occurs when the state of an audio device changes.
154         /// </summary>
155         /// <since_tizen> 3 </since_tizen>
156         public static event EventHandler<AudioDeviceStateChangedEventArgs> DeviceStateChanged
157         {
158             add
159             {
160                 lock (_audioDeviceStateLock)
161                 {
162                     if (_audioDeviceStateChanged == null)
163                     {
164                         RegisterDeviceStateChangedEvent();
165                     }
166                     _audioDeviceStateChanged += value;
167                 }
168             }
169             remove
170             {
171                 if (value == null)
172                 {
173                     return;
174                 }
175
176                 lock (_audioDeviceStateLock)
177                 {
178                     if (_audioDeviceStateChanged == value)
179                     {
180                         UnregisterDeviceStateChangedEvent();
181                     }
182                     _audioDeviceStateChanged -= value;
183                 }
184             }
185         }
186
187         private static void RegisterDeviceStateChangedEvent()
188         {
189             _audioDeviceStateChangedCallback = (IntPtr device, AudioDeviceState changedState, IntPtr userData) =>
190             {
191                 _audioDeviceStateChanged?.Invoke(null,
192                     new AudioDeviceStateChangedEventArgs(new AudioDevice(device), changedState));
193             };
194
195             Interop.AudioDevice.AddDeviceStateChangedCallback(AudioDeviceOptions.All,
196                 _audioDeviceStateChangedCallback, IntPtr.Zero, out _deviceStateChangedCallbackId).
197                 Validate("Failed to add device state changed event");
198         }
199
200         private static void UnregisterDeviceStateChangedEvent()
201         {
202             Interop.AudioDevice.RemoveDeviceStateChangedCallback(_deviceStateChangedCallbackId).
203                 Validate("Failed to remove device state changed event");
204         }
205         #endregion
206     }
207 }