Release 4.0.0-preview1-00051
[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     internal static class AudioManagerLog
23     {
24         internal const string Tag = "Tizen.Multimedia.AudioManager";
25     }
26
27     /// <summary>
28     /// The Audio Manager class provides functions to get and set sound parameters like volume and devices.
29     /// </summary>
30     public static class AudioManager
31     {
32         private static int _deviceConnectionChangedCallbackId = -1;
33         private static int _deviceStateChangedCallbackId = -1;
34
35         private static Interop.SoundDeviceConnectionChangedCallback _audioDeviceConnectionChangedCallback;
36         private static Interop.SoundDeviceStateChangedCallback _audioDeviceStateChangedCallback;
37
38         private static EventHandler<AudioDeviceConnectionChangedEventArgs> _audioDeviceConnectionChanged;
39         private static EventHandler<AudioDeviceStateChangedEventArgs> _audioDeviceStateChanged;
40
41         /// <summary>
42         /// Constructor for AudioManager. Initializes the VolumeController property etc.
43         /// </summary>
44         static AudioManager()
45         {
46             VolumeController = new AudioVolume();
47         }
48
49         /// <summary>
50         /// Registers/Unregisters a function to be invoked when the state of connection of an Audio device was changed.
51         /// </summary>
52         public static event EventHandler<AudioDeviceConnectionChangedEventArgs> DeviceConnectionChanged
53         {
54             add
55             {
56                 if (_audioDeviceConnectionChanged == null)
57                 {
58                     RegisterAudioDeviceEvent();
59                     Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event registered");
60                 }
61                 _audioDeviceConnectionChanged += value;
62                 Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event added");
63             }
64             remove
65             {
66                 if (_audioDeviceConnectionChanged?.GetInvocationList()?.GetLength(0) == 1)
67                 {
68                     UnregisterDeviceConnectionChangedEvent();
69                 }
70                 _audioDeviceConnectionChanged -= value;
71                 Tizen.Log.Info(AudioManagerLog.Tag, "DeviceConnectionChanged event removed");
72             }
73         }
74
75         /// <summary>
76         /// Registers/Unregisters a callback function to be invoked when the state of an Audio sound device was changed.
77         /// </summary>
78         public static event EventHandler<AudioDeviceStateChangedEventArgs> DeviceStateChanged
79         {
80             add
81             {
82                 if (_audioDeviceStateChanged == null)
83                 {
84                     RegisterDeviceStateChangedEvent();
85                 }
86                 _audioDeviceStateChanged += value;
87                 Tizen.Log.Info(AudioManagerLog.Tag, "DeviceStateChanged event added");
88             }
89             remove
90             {
91                 if (_audioDeviceStateChanged?.GetInvocationList()?.GetLength(0) == 1)
92                 {
93                     UnregisterDeviceStateChangedEvent();
94                 }
95                 _audioDeviceStateChanged -= value;
96                 Tizen.Log.Info(AudioManagerLog.Tag, "DeviceStateChanged event removed");
97             }
98         }
99
100         /// <summary>
101         /// The VolumeController object (singleton) is-a part of SoundManager and its properties and methods are used via AudioManager
102         /// </summary>
103         public static AudioVolume VolumeController { get; }
104
105         /// <summary>
106         /// Gets the list consisting of all devices currently connected.
107         /// </summary>
108         /// <param name="options">The audio device options</param>
109         /// <returns>The list of connected devices: IEnumerable of Device objects</returns>
110         public static IEnumerable<AudioDevice> GetCurrentDevices(AudioDeviceOptions options)
111         {
112             List<AudioDevice> audioDeviceList = new List<AudioDevice>();
113             IntPtr deviceListHandle;
114             IntPtr handlePosition;
115             AudioDeviceIoDirection ioDirection;
116
117             int ret = Interop.AudioDevice.GetCurrentDeviceList(options, out deviceListHandle);
118             if (ret != (int)AudioManagerError.NoData)
119             {
120                 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to get next device");
121             }
122             while (ret == (int)AudioManagerError.None)
123             {
124                 ret = Interop.AudioDevice.GetNextDevice(deviceListHandle, out handlePosition);
125                 if (ret == (int)AudioManagerError.NoData)
126                 {
127                     break;
128                 }
129                 else if (ret != (int)AudioManagerError.None)
130                 {
131                     AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to get next device");
132                 }
133
134                 if (options == AudioDeviceOptions.Input || (options == AudioDeviceOptions.Output))
135                 {
136                     ret = Interop.AudioDevice.GetDeviceIoDirection(handlePosition, out ioDirection);
137                     if (ret != 0)
138                     {
139                         Tizen.Log.Error(AudioManagerLog.Tag, "Unable to get device IoDirection" + (AudioManagerError)ret);
140                         AudioManagerErrorFactory.CheckAndThrowException(ret, handlePosition, "Unable to get device IO Direction");
141                     }
142                     else if (ioDirection == AudioDeviceIoDirection.InputAndOutput)
143                     {
144                         continue;
145                     }
146                 }
147                 audioDeviceList.Add(new AudioDevice(handlePosition));
148             }
149             return audioDeviceList;
150         }
151
152         private static void RegisterAudioDeviceEvent()
153         {
154             _audioDeviceConnectionChangedCallback = (IntPtr device, bool isConnected, IntPtr userData) =>
155             {
156                 AudioDeviceConnectionChangedEventArgs eventArgs = new AudioDeviceConnectionChangedEventArgs(new AudioDevice(device), isConnected);
157                 _audioDeviceConnectionChanged?.Invoke(null, eventArgs);
158             };
159             int ret = Interop.AudioDevice.AddDeviceConnectionChangedCallback(AudioDeviceOptions.All, _audioDeviceConnectionChangedCallback, IntPtr.Zero, out _deviceConnectionChangedCallbackId);
160             AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device connection changed callback");
161             Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceConnectionChanged Event registered");
162         }
163
164         private static void RegisterDeviceStateChangedEvent()
165         {
166             _audioDeviceStateChangedCallback = (IntPtr device, AudioDeviceState changedState, IntPtr userData) =>
167             {
168                 AudioDeviceStateChangedEventArgs eventArgs = new AudioDeviceStateChangedEventArgs(new AudioDevice(device), changedState);
169                 _audioDeviceStateChanged?.Invoke(null, eventArgs);
170             };
171             int ret = Interop.AudioDevice.AddDeviceStateChangedCallback(AudioDeviceOptions.All, _audioDeviceStateChangedCallback, IntPtr.Zero, out _deviceStateChangedCallbackId);
172             AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device state changed callback");
173             Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceStateChangedEvent callback registered");
174         }
175
176         private static void UnregisterDeviceConnectionChangedEvent()
177         {
178             if (_deviceConnectionChangedCallbackId > 0)
179             {
180                 int ret = Interop.AudioDevice.RemoveDeviceConnectionChangedCallback(_deviceConnectionChangedCallbackId);
181                 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device connection changed callback");
182                 Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceConnectionChangedEvent callback unregistered");
183                 _deviceConnectionChangedCallbackId = -1;
184             }
185         }
186
187         private static void UnregisterDeviceStateChangedEvent()
188         {
189             if (_deviceStateChangedCallbackId > 0)
190             {
191                 int ret = Interop.AudioDevice.RemoveDeviceStateChangedCallback(_deviceStateChangedCallbackId);
192                 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device state changed callback");
193                 Tizen.Log.Info(AudioManagerLog.Tag, "AudioDeviceStateChanged callback unregistered");
194                 _deviceStateChangedCallbackId = -1;
195             }
196         }
197     }
198 }