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.Multimedia
21 internal static class AudioStreamPolicyLog
23 internal const string Tag = "Tizen.Multimedia.AudioStreamPolicy";
27 /// The Stream Policy API provides functions to control a sound stream.
29 public class AudioStreamPolicy : IDisposable
31 private static int _focusStateWatchCounter = 0;
32 private static EventHandler<FocusStateChangedEventArgs> _focusStateWatchForPlayback;
33 private static EventHandler<FocusStateChangedEventArgs> _focusStateWatchForRecording;
34 private static Interop.SoundStreamFocusStateWatchCallback _focusStateWatchCallback;
35 private static int _focusWatchCbId;
37 private IntPtr _streamInfo;
38 private AudioStreamType _streamType;
39 private bool _disposed = false;
40 private EventHandler<StreamFocusStateChangedEventArgs> _focusStateChanged;
41 private Interop.SoundStreamFocusStateChangedCallback _focusStateChangedCallback;
44 /// Creates and returns an AudioStreamPolicy object
47 /// To apply the stream policy according to this stream information, this object should be passed to other APIs
48 /// related to playback or recording. (e.g., player, wav-player, audio-io, etc.)
50 /// <param name="streamType">Type of sound stream for which policy needs to be created</param>
51 /// <returns>StreamPolicy object</returns>
52 public AudioStreamPolicy(AudioStreamType streamType)
54 _streamType = streamType;
56 _focusStateChangedCallback = (IntPtr streamInfo, AudioStreamFocusOptions focusMask, AudioStreamFocusState focusState, int reason, int audioStreamBehavior, string extraInfo, IntPtr userData) => {
57 StreamFocusStateChangedEventArgs eventArgs = new StreamFocusStateChangedEventArgs((AudioStreamFocusChangedReason)reason, extraInfo);
58 _focusStateChanged?.Invoke(this, eventArgs);
60 int ret = Interop.AudioStreamPolicy.CreateStreamInformation((int)streamType, _focusStateChangedCallback, IntPtr.Zero, out _streamInfo);
61 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to create stream information");
70 /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
72 /// Remarks: You can set this only once per process.
75 public static event EventHandler<FocusStateChangedEventArgs> PlaybackFocusStateWatch {
77 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
78 if(_focusStateWatchCounter == 0) {
79 RegisterFocusStateWatchEvent();
81 _focusStateWatchCounter++;
82 _focusStateWatchForPlayback += value;
85 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
86 _focusStateWatchForPlayback -= value;
87 _focusStateWatchCounter--;
88 if(_focusStateWatchCounter == 0) {
89 UnregisterFocusStateWatch();
95 /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
97 /// Remarks: You can set this only once per process.
100 public static event EventHandler<FocusStateChangedEventArgs> RecordingFocusStateWatch {
102 if(_focusStateWatchCounter == 0) {
103 RegisterFocusStateWatchEvent();
105 _focusStateWatchCounter++;
106 _focusStateWatchForRecording += value;
109 _focusStateWatchForRecording -= value;
110 _focusStateWatchCounter--;
111 if(_focusStateWatchCounter == 0) {
112 UnregisterFocusStateWatch();
118 /// Registers function to be called when the state of focus that belongs to the current
119 /// streamInfo is changed.
122 /// Remarks: This function is issued in the internal thread of the sound manager. Therefore it is recommended not to call UI update function in this function.
123 /// Postcondition : Check PlaybackFocusState and RecordingFocusState in the registered event handler to figure out how the focus state of the StreamInfo has been changed.
125 public event EventHandler<StreamFocusStateChangedEventArgs> StreamFocusStateChanged {
127 _focusStateChanged += value;
130 _focusStateChanged -= value;
135 /// The sound type of the stream information.
137 public AudioVolumeType VolumeType {
139 AudioVolumeType soundType;
140 int ret = Interop.AudioStreamPolicy.GetSoundType(_streamInfo, out soundType);
142 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get sound type:" + (AudioManagerError)ret);
143 return AudioVolumeType.None;
150 /// The state of focus for playback.
152 public AudioStreamFocusState PlaybackFocusState {
154 AudioStreamFocusState stateForPlayback;
155 AudioStreamFocusState stateForRecording;
156 int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
158 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
159 return AudioStreamFocusState.Released;
161 return stateForPlayback;
166 /// The state of focus for recording.
168 public AudioStreamFocusState RecordingFocusState {
170 AudioStreamFocusState stateForPlayback;
171 AudioStreamFocusState stateForRecording;
172 int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
174 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
175 return AudioStreamFocusState.Released;
177 return stateForRecording;
182 /// Auto focus reacquisition property
185 /// The focus reacquistion is set as default. If you don't want to reacquire the focus you've lost automatically, disable the focus reacqusition setting by using this API and vice versa.
187 public bool FocusReacquisitionEnabled {
190 int ret = Interop.AudioStreamPolicy.GetFocusReacquisition(_streamInfo, out enabled);
192 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus reacquisition" + (AudioManagerError)ret);
198 int ret = Interop.AudioStreamPolicy.SetFocusReacquisition(_streamInfo, value);
199 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus reacquisition");
203 public IntPtr Handle {
210 /// Acquires the stream focus.
212 /// <param name="focusMask">The focus mask that user wants to acquire</param>
213 /// <param name="extraInformation">The Extra information for this request (optional, this can be null)</param>
215 /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
217 public void AcquireFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
219 int ret = Interop.AudioStreamPolicy.AcquireFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
220 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Acquire focus return: " + ret);
221 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to acquire focus");
225 /// Releases the acquired focus.
227 /// <param name="options">The focus mask that user wants to release</param>
228 /// <param name="extraInformation">he Extra information for this request (optional, this can be null)</param>
230 /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
232 public void ReleaseFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
234 int ret = Interop.AudioStreamPolicy.ReleaseFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
235 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Release focus return: " + ret);
236 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to release focus");
240 /// Applies the stream routing.
243 /// If the stream has not been made yet, this setting will be applied when the stream starts to play.
244 /// Precondition: Call AddDeviceForStreamRouting() before calling this function.
246 public void ApplyStreamRouting()
248 int ret = Interop.AudioStreamPolicy.ApplyStreamRouting(_streamInfo);
249 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Apply Routing: " + (AudioManagerError)ret);
250 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to apply stream routing");
254 /// Adds the device to the stream information for the stream routing.
257 /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
258 /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
259 /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
261 /// <param name="soundDevice">The device item from the current sound devices list.</param>
262 public void AddDeviceForStreamRouting(AudioDevice soundDevice)
264 int ret = Interop.AudioStreamPolicy.AddDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
265 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Add stream routing: " + (AudioManagerError)ret);
267 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device for stream routing");
271 /// Removes the device to the stream information for the stream routing.
274 /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
275 /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
276 /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
278 /// <param name="soundDevice">The device item from the current sound devices list.</param>
279 public void RemoveDeviceForStreamRouting(AudioDevice soundDevice)
281 int ret = Interop.AudioStreamPolicy.RemoveDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
282 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Remove stream routing: " + (AudioManagerError)ret);
283 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device for stream routing");
286 public void Dispose()
289 GC.SuppressFinalize(this);
292 protected virtual void Dispose(bool disposing)
296 // to be used if there are any other disposable objects
298 if(_streamInfo != IntPtr.Zero) {
299 Interop.AudioStreamPolicy.DestroyStreamInformation(_streamInfo); // Destroy the handle
300 _streamInfo = IntPtr.Zero;
306 private static void RegisterFocusStateWatchEvent()
308 _focusStateWatchCallback = (int id, AudioStreamFocusOptions options, AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInfo, IntPtr userData) => {
309 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _Inside _focusStateWatchCallback : id = " + id + "options = " + options);
310 FocusStateChangedEventArgs eventArgs = new FocusStateChangedEventArgs(focusState, reason, extraInfo);
311 if(options == AudioStreamFocusOptions.Playback) {
312 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _eventArgs = " + eventArgs);
313 _focusStateWatchForPlayback?.Invoke(null, eventArgs);
314 } else if(options == AudioStreamFocusOptions.Recording) {
315 _focusStateWatchForRecording?.Invoke(null, eventArgs);
316 } else if(options == (AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording)) {
317 _focusStateWatchForPlayback?.Invoke(null, eventArgs);
318 _focusStateWatchForRecording?.Invoke(null, eventArgs);
321 int ret = Interop.AudioStreamPolicy.AddFocusStateWatchCallback(AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording, _focusStateWatchCallback, IntPtr.Zero, out _focusWatchCbId);
322 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _AddFocusStateWatchCallback : ret = " + ret + " ID = " + _focusWatchCbId);
323 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus state watch callback");
326 private static void UnregisterFocusStateWatch()
328 int ret = Interop.AudioStreamPolicy.RemoveFocusStateWatchCallback(_focusWatchCbId);
329 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to unset focus state watch callback");