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="options">The focus mask that user wants to acquire</param>
213 /// <param name="audioStreamBehavior">The required action for releaser</param>
214 /// <param name="extraInformation">The Extra information for this request (optional, this can be null)</param>
216 /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
218 public void AcquireFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
220 int ret = Interop.AudioStreamPolicy.AcquireFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
221 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Acquire focus return: " + ret);
222 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to acquire focus");
226 /// Releases the acquired focus.
228 /// <param name="options">The focus mask that user wants to release</param>
229 /// <param name="audioStreamBehavior">The required action for acquirer</param>
230 /// <param name="extraInformation">he Extra information for this request (optional, this can be null)</param>
232 /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
234 public void ReleaseFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
236 int ret = Interop.AudioStreamPolicy.ReleaseFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
237 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Release focus return: " + ret);
238 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to release focus");
242 /// Applies the stream routing.
245 /// If the stream has not been made yet, this setting will be applied when the stream starts to play.
246 /// Precondition: Call AddDeviceForStreamRouting() before calling this function.
248 public void ApplyStreamRouting()
250 int ret = Interop.AudioStreamPolicy.ApplyStreamRouting(_streamInfo);
251 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Apply Routing: " + (AudioManagerError)ret);
252 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to apply stream routing");
256 /// Adds the device to the stream information for the stream routing.
259 /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
260 /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
261 /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
263 /// <param name="soundDevice">The device item from the current sound devices list.</param>
264 public void AddDeviceForStreamRouting(AudioDevice soundDevice)
266 int ret = Interop.AudioStreamPolicy.AddDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
267 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Add stream routing: " + (AudioManagerError)ret);
269 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device for stream routing");
273 /// Removes the device to the stream information for the stream routing.
276 /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
277 /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
278 /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
280 /// <param name="soundDevice">The device item from the current sound devices list.</param>
281 public void RemoveDeviceForStreamRouting(AudioDevice soundDevice)
283 int ret = Interop.AudioStreamPolicy.RemoveDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
284 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Remove stream routing: " + (AudioManagerError)ret);
285 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device for stream routing");
288 public void Dispose()
291 GC.SuppressFinalize(this);
294 protected virtual void Dispose(bool disposing)
298 // to be used if there are any other disposable objects
300 if(_streamInfo != IntPtr.Zero) {
301 Interop.AudioStreamPolicy.DestroyStreamInformation(_streamInfo); // Destroy the handle
302 _streamInfo = IntPtr.Zero;
308 private static void RegisterFocusStateWatchEvent()
310 _focusStateWatchCallback = (int id, AudioStreamFocusOptions options, AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInfo, IntPtr userData) => {
311 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _Inside _focusStateWatchCallback : id = " + id + "options = " + options);
312 FocusStateChangedEventArgs eventArgs = new FocusStateChangedEventArgs(focusState, reason, extraInfo);
313 if(options == AudioStreamFocusOptions.Playback) {
314 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _eventArgs = " + eventArgs);
315 _focusStateWatchForPlayback?.Invoke(null, eventArgs);
316 } else if(options == AudioStreamFocusOptions.Recording) {
317 _focusStateWatchForRecording?.Invoke(null, eventArgs);
318 } else if(options == (AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording)) {
319 _focusStateWatchForPlayback?.Invoke(null, eventArgs);
320 _focusStateWatchForRecording?.Invoke(null, eventArgs);
323 int ret = Interop.AudioStreamPolicy.AddFocusStateWatchCallback(AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording, _focusStateWatchCallback, IntPtr.Zero, out _focusWatchCbId);
324 Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _AddFocusStateWatchCallback : ret = " + ret + " ID = " + _focusWatchCbId);
325 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus state watch callback");
328 private static void UnregisterFocusStateWatch()
330 int ret = Interop.AudioStreamPolicy.RemoveFocusStateWatchCallback(_focusWatchCbId);
331 AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to unset focus state watch callback");