X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2FTizen.Multimedia%2FAudioManager%2FAudioStreamPolicy.cs;h=5a50f737b0480c42b7232e9e44224fc36c9eaaca;hb=4c05cfedbfe61d66ffdfefe61e0bb41df720dd9a;hp=b914c9c12393099858f9f2f7642cf7b6e3ed58bd;hpb=60a6696cc226d99a69aa13bf4060c7bdcc85e398;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git
diff --git a/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
old mode 100755
new mode 100644
index b914c9c..5a50f73
--- a/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
+++ b/src/Tizen.Multimedia/AudioManager/AudioStreamPolicy.cs
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
@@ -15,320 +15,486 @@
*/
using System;
+using System.Diagnostics;
namespace Tizen.Multimedia
{
- internal static class AudioStreamPolicyLog
- {
- internal const string Tag = "Tizen.Multimedia.AudioStreamPolicy";
- }
-
///
- /// The Stream Policy API provides functions to control a sound stream.
+ /// Provides the ability to control the sound stream.
///
+ /// 3
public class AudioStreamPolicy : IDisposable
{
- private static int _focusStateWatchCounter = 0;
- private static EventHandler _focusStateWatchForPlayback;
- private static EventHandler _focusStateWatchForRecording;
- private static Interop.SoundStreamFocusStateWatchCallback _focusStateWatchCallback;
- private static int _focusWatchCbId;
-
- private IntPtr _streamInfo;
- private AudioStreamType _streamType;
+ private AudioStreamPolicyHandle _handle;
private bool _disposed = false;
- private EventHandler _focusStateChanged;
- private Interop.SoundStreamFocusStateChangedCallback _focusStateChangedCallback;
+ private Interop.AudioStreamPolicy.FocusStateChangedCallback _focusStateChangedCallback;
+ private static AudioDevice _inputDevice = null;
+ private static AudioDevice _outputDevice = null;
+ private const string Tag = "Tizen.Multimedia.AudioStreamPolicy";
///
- /// Creates and returns an AudioStreamPolicy object
+ /// Initializes a new instance of the class with .
///
///
- /// To apply the stream policy according to this stream information, this object should be passed to other APIs
- /// related to playback or recording. (e.g., player, wav-player, audio-io, etc.)
+ /// To apply the stream policy according to this stream information, the AudioStreamPolicy should
+ /// be passed to other APIs related to playback or recording. (For example., ,
+ /// , etc.)
///
- /// Type of sound stream for which policy needs to be created
- /// StreamPolicy object
+ /// The type of the sound stream for which the policy needs to be created.
+ /// is invalid.
+ /// 3
public AudioStreamPolicy(AudioStreamType streamType)
{
- _streamType = streamType;
+ ValidationUtil.ValidateEnum(typeof(AudioStreamType), streamType, nameof(streamType));
- _focusStateChangedCallback = (IntPtr streamInfo, AudioStreamFocusOptions focusMask, AudioStreamFocusState focusState, int reason, int audioStreamBehavior, string extraInfo, IntPtr userData) => {
- StreamFocusStateChangedEventArgs eventArgs = new StreamFocusStateChangedEventArgs((AudioStreamFocusChangedReason)reason, extraInfo);
- _focusStateChanged?.Invoke(this, eventArgs);
+ _focusStateChangedCallback = (IntPtr streamInfo, AudioStreamFocusOptions focusMask,
+ AudioStreamFocusState state, AudioStreamFocusChangedReason reason, AudioStreamBehaviors behaviors,
+ string extraInfo, IntPtr _) =>
+ {
+ FocusStateChanged?.Invoke(this,
+ new AudioStreamPolicyFocusStateChangedEventArgs(focusMask, state, reason, behaviors, extraInfo));
};
- int ret = Interop.AudioStreamPolicy.CreateStreamInformation((int)streamType, _focusStateChangedCallback, IntPtr.Zero, out _streamInfo);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to create stream information");
- }
- ~AudioStreamPolicy()
- {
- Dispose(false);
+ Interop.AudioStreamPolicy.Create(streamType, _focusStateChangedCallback,
+ IntPtr.Zero, out _handle).ThrowIfError("Unable to create stream information");
+
+ Debug.Assert(_handle != null);
}
///
- /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
+ /// Occurs when the state of focus that belongs to the current AudioStreamPolicy is changed.
+ ///
///
- /// Remarks: You can set this only once per process.
+ /// The event is raised in the internal thread.
///
- ///
- public static event EventHandler PlaybackFocusStateWatch {
- add {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
- if(_focusStateWatchCounter == 0) {
- RegisterFocusStateWatchEvent();
- }
- _focusStateWatchCounter++;
- _focusStateWatchForPlayback += value;
- }
- remove {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _focusStateWatchCounter" + _focusStateWatchCounter);
- _focusStateWatchForPlayback -= value;
- _focusStateWatchCounter--;
- if(_focusStateWatchCounter == 0) {
- UnregisterFocusStateWatch();
- }
- }
- }
+ /// 4
+ public event EventHandler FocusStateChanged;
///
- /// Registers the watch function to be invoked when the focus state for each sound stream type is changed regardless of the process.
+ /// Gets the .
+ ///
///
- /// Remarks: You can set this only once per process.
+ /// If the of the current AudioStreamPolicy is ,
+ /// it returns .
///
- ///
- public static event EventHandler RecordingFocusStateWatch {
- add {
- if(_focusStateWatchCounter == 0) {
- RegisterFocusStateWatchEvent();
- }
- _focusStateWatchCounter++;
- _focusStateWatchForRecording += value;
- }
- remove {
- _focusStateWatchForRecording -= value;
- _focusStateWatchCounter--;
- if(_focusStateWatchCounter == 0) {
- UnregisterFocusStateWatch();
+ /// The of the policy instance.
+ /// The has already been disposed of.
+ /// 3
+ public AudioVolumeType VolumeType
+ {
+ get
+ {
+ var ret = Interop.AudioStreamPolicy.GetSoundType(Handle, out var type);
+ if (ret == AudioManagerError.NoData)
+ {
+ return AudioVolumeType.None;
}
+
+ ret.ThrowIfError("Failed to get volume type");
+
+ return type;
}
}
+ private AudioStreamFocusState GetFocusState(bool playback)
+ {
+ int ret = Interop.AudioStreamPolicy.GetFocusState(Handle, out var stateForPlayback, out var stateForRecording);
+ MultimediaDebug.AssertNoError(ret);
+
+ return playback ? stateForPlayback : stateForRecording;
+ }
+
+ ///
+ /// Gets the state of focus for the playback.
+ ///
+ /// The state of focus for playback.
+ /// The has already been disposed of.
+ /// 3
+ public AudioStreamFocusState PlaybackFocusState => GetFocusState(true);
+
///
- /// Registers function to be called when the state of focus that belongs to the current
- /// streamInfo is changed.
+ /// Gets the state of focus for the recording.
///
+ /// The state of focus for recording.
+ /// The has already been disposed of.
+ /// 3
+ public AudioStreamFocusState RecordingFocusState => GetFocusState(false);
+
+ ///
+ /// Gets or sets the auto focus reacquisition.
+ ///
+ ///
+ /// true if the auto focus reacquisition is enabled; otherwise, false.
+ /// The default is true.
+ ///
///
- /// 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.
- /// Postcondition : Check PlaybackFocusState and RecordingFocusState in the registered event handler to figure out how the focus state of the StreamInfo has been changed.
+ /// If you don't want to reacquire the focus you've lost automatically,
+ /// disable the focus reacquisition.
///
- public event EventHandler StreamFocusStateChanged {
- add {
- _focusStateChanged += value;
+ /// The has already been disposed of.
+ /// 3
+ public bool FocusReacquisitionEnabled
+ {
+ get
+ {
+ Interop.AudioStreamPolicy.GetFocusReacquisition(Handle, out var enabled).
+ ThrowIfError("Failed to get focus reacquisition state");
+
+ return enabled;
}
- remove {
- _focusStateChanged -= value;
+ set
+ {
+ Interop.AudioStreamPolicy.SetFocusReacquisition(Handle, value).
+ ThrowIfError("Failed to set focus reacquisition");
}
}
- ///
- /// The sound type of the stream information.
- ///
- public AudioVolumeType VolumeType {
- get {
- AudioVolumeType soundType;
- int ret = Interop.AudioStreamPolicy.GetSoundType(_streamInfo, out soundType);
- if(ret != 0) {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get sound type:" + (AudioManagerError)ret);
- return AudioVolumeType.None;
+ internal AudioStreamPolicyHandle Handle
+ {
+ get
+ {
+ if (_disposed)
+ {
+ throw new ObjectDisposedException(nameof(AudioStreamPolicy));
}
- return soundType;
+ return _handle;
}
}
///
- /// The state of focus for playback.
+ /// Acquires the stream focus.
///
- public AudioStreamFocusState PlaybackFocusState {
- get {
- AudioStreamFocusState stateForPlayback;
- AudioStreamFocusState stateForRecording;
- int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
- if(ret != 0) {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
- return AudioStreamFocusState.Released;
- }
- return stateForPlayback;
+ /// The focuses that you want to acquire.
+ /// The requesting behaviors.
+ /// The extra information for this request. This value can be null.
+ /// is zero.
+ ///
+ /// contain a invalid bit.
+ /// -or-
+ /// contain a invalid bit.
+ ///
+ /// The focus has already been acquired.
+ /// Called in raised by releasing focus.
+ /// The has already been disposed of.
+ /// 3
+ public void AcquireFocus(AudioStreamFocusOptions options, AudioStreamBehaviors behaviors, string extraInfo)
+ {
+ if (options == 0)
+ {
+ throw new ArgumentException("options can't be zero.", nameof(options));
+ }
+
+ if (options.IsValid() == false)
+ {
+ throw new ArgumentOutOfRangeException(nameof(options), options, "options contains a invalid bit.");
}
+
+ if (behaviors.IsValid() == false)
+ {
+ throw new ArgumentOutOfRangeException(nameof(behaviors), behaviors, "behaviors contains a invalid bit.");
+ }
+
+ Interop.AudioStreamPolicy.AcquireFocus(Handle, options, behaviors, extraInfo).
+ ThrowIfError("Failed to acquire focus");
}
///
- /// The state of focus for recording.
+ /// Releases the acquired focus.
///
- public AudioStreamFocusState RecordingFocusState {
- get {
- AudioStreamFocusState stateForPlayback;
- AudioStreamFocusState stateForRecording;
- int ret = Interop.AudioStreamPolicy.GetFocusState(_streamInfo, out stateForPlayback, out stateForRecording);
- if(ret != 0) {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus state" + (AudioManagerError)ret);
- return AudioStreamFocusState.Released;
- }
- return stateForRecording;
+ /// The focus mask that you want to release.
+ /// The requesting behaviors.
+ /// The extra information for this request. This value can be null.
+ /// is zero.
+ ///
+ /// contain a invalid bit.
+ /// -or-
+ /// contain a invalid bit.
+ ///
+ /// The focus has not been acquired.
+ /// The has already been disposed of.
+ /// 3
+ public void ReleaseFocus(AudioStreamFocusOptions options, AudioStreamBehaviors behaviors, string extraInfo)
+ {
+ if (options == 0)
+ {
+ throw new ArgumentException("options can't be zero.", nameof(options));
+ }
+
+ if (options.IsValid() == false)
+ {
+ throw new ArgumentOutOfRangeException(nameof(options), options, "options contains a invalid bit.");
+ }
+
+ if (behaviors.IsValid() == false)
+ {
+ throw new ArgumentOutOfRangeException(nameof(behaviors), behaviors, "behaviors contains a invalid bit.");
}
+
+ Interop.AudioStreamPolicy.ReleaseFocus(Handle, options, behaviors, extraInfo).
+ ThrowIfError("Failed to release focus");
}
///
- /// Auto focus reacquisition property
+ /// Applies the stream routing.
///
///
- /// 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.
+ /// If the stream has not been made yet, this will be applied when the stream starts to play.
///
- public bool FocusReacquisitionEnabled {
- get {
- bool enabled;
- int ret = Interop.AudioStreamPolicy.GetFocusReacquisition(_streamInfo, out enabled);
- if(ret != 0) {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Unable to get focus reacquisition" + (AudioManagerError)ret);
- return true;
- }
- return enabled;
- }
- set {
- int ret = Interop.AudioStreamPolicy.SetFocusReacquisition(_streamInfo, value);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus reacquisition");
- }
- }
-
- public IntPtr Handle {
- get {
- return _streamInfo;
- }
+ ///
+ ///
+ /// The has already been disposed of.
+ /// 3
+ public void ApplyStreamRouting()
+ {
+ Interop.AudioStreamPolicy.ApplyStreamRouting(Handle).ThrowIfError("Failed to apply stream routing");
}
///
- /// Acquires the stream focus.
+ /// Adds a device for the stream routing.
///
- /// The focus mask that user wants to acquire
- /// The required action for releaser
- /// The Extra information for this request (optional, this can be null)
+ /// The device to add.
///
- /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
+ /// The available is and .
///
- public void AcquireFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
+ ///
+ /// The device is not connected.
+ /// -or-
+ /// An internal error occurs.
+ ///
+ /// is null.
+ /// of is unavailable for this.
+ /// The has already been disposed of.
+ ///
+ ///
+ /// 3
+ public void AddDeviceForStreamRouting(AudioDevice device)
{
- int ret = Interop.AudioStreamPolicy.AcquireFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Acquire focus return: " + ret);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to acquire focus");
+ if (device == null)
+ {
+ throw new ArgumentNullException(nameof(device));
+ }
+
+ var ret = Interop.AudioStreamPolicy.AddDeviceForStreamRouting(Handle, device.Id);
+
+ if (ret == AudioManagerError.NoData)
+ {
+ throw new InvalidOperationException("The device seems not connected.");
+ }
+
+ ret.ThrowIfError("Failed to add device for stream routing");
}
///
- /// Releases the acquired focus.
+ /// Removes the device for the stream routing.
///
- /// The focus mask that user wants to release
- /// The required action for acquirer
- /// he Extra information for this request (optional, this can be null)
+ /// The device to remove.
///
- /// Do not call this API within event handlers of FocuStateChanged and StreamFocusStateWatch else it will throw and exception
+ /// The available is and .
///
- public void ReleaseFocus(AudioStreamFocusOptions options, AudioStreamBehavior audioStreamBehavior, string extraInformation)
+ /// An internal error occurs.
+ /// is null.
+ /// The has already been disposed of.
+ ///
+ /// 3
+ public void RemoveDeviceForStreamRouting(AudioDevice device)
{
- int ret = Interop.AudioStreamPolicy.ReleaseFocus(_streamInfo, options, (int)audioStreamBehavior, extraInformation);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Release focus return: " + ret);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to release focus");
+ if (device == null)
+ {
+ throw new ArgumentNullException(nameof(device));
+ }
+
+ Interop.AudioStreamPolicy.RemoveDeviceForStreamRouting(Handle, device.Id).
+ ThrowIfError("Failed to remove device for stream routing");
}
///
- /// Applies the stream routing.
+ /// Gets or sets the preferred input device.
///
+ ///
+ /// The instance.
+ /// The default is null which means any device is not set on this property.
+ ///
///
- /// If the stream has not been made yet, this setting will be applied when the stream starts to play.
- /// Precondition: Call AddDeviceForStreamRouting() before calling this function.
+ /// This property is to set a specific built-in device when the system has multiple devices of the same built-in device type.
+ /// When there's only one device for a built-in device type in the system, nothing will happen even if this property is set successfully.
///
- public void ApplyStreamRouting()
+ /// A device is not for input.
+ /// An internal error occurs.
+ /// A device is not supported by this instance.
+ /// The has already been disposed of.
+ ///
+ /// 6
+ public AudioDevice PreferredInputDevice
{
- int ret = Interop.AudioStreamPolicy.ApplyStreamRouting(_streamInfo);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Apply Routing: " + (AudioManagerError)ret);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to apply stream routing");
+ get
+ {
+ /* This P/Invoke intends to validate if the core audio system
+ * is normal. Otherwise, it'll throw an error here. */
+ Interop.AudioStreamPolicy.GetPreferredDevice(Handle, out var inDeviceId, out _).
+ ThrowIfError("Failed to get preferred input device");
+
+ Log.Debug(Tag, $"preferred input device id:{inDeviceId}");
+
+ return _inputDevice;
+ }
+ set
+ {
+ Interop.AudioStreamPolicy.SetPreferredDevice(Handle, AudioDeviceIoDirection.Input, value?.Id ?? 0).
+ ThrowIfError("Failed to set preferred input device");
+
+ _inputDevice = value;
+ }
}
///
- /// Adds the device to the stream information for the stream routing.
+ /// Gets or sets the preferred output device.
///
+ ///
+ /// The instance.
+ /// The default is null which means any device is not set on this property.
+ ///
///
- /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
- /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
- /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
+ /// This property is to set a specific built-in device when the system has multiple devices of the same built-in device type.
+ /// When there's only one device for a built-in device type in the system, nothing will happen even if this property is set successfully.
///
- /// The device item from the current sound devices list.
- public void AddDeviceForStreamRouting(AudioDevice soundDevice)
+ /// A device is not for output.
+ /// An internal error occurs.
+ /// A device is not supported by this instance.
+ /// The has already been disposed of.
+ ///
+ /// 6
+ public AudioDevice PreferredOutputDevice
{
- int ret = Interop.AudioStreamPolicy.AddDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Add stream routing: " + (AudioManagerError)ret);
+ get
+ {
+ /* This P/Invoke intends to validate if the core audio system
+ * is normal. Otherwise, it'll throw an error here. */
+ Interop.AudioStreamPolicy.GetPreferredDevice(Handle, out _, out var outDeviceId).
+ ThrowIfError("Failed to get preferred output device");
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to add device for stream routing");
+ Log.Debug(Tag, $"preferred output device id:{outDeviceId}");
+
+ return _outputDevice;
+ }
+ set
+ {
+ Interop.AudioStreamPolicy.SetPreferredDevice(Handle, AudioDeviceIoDirection.Output, value?.Id ?? 0).
+ ThrowIfError("Failed to set preferred output device");
+
+ _outputDevice = value;
+ }
}
///
- /// Removes the device to the stream information for the stream routing.
+ /// Checks if any stream from the current AudioStreamPolicy is using the device.
///
+ /// true if any audio stream from the current AudioStreamPolicy is using the device; otherwise, false.
+ /// The device to be checked.
///
- /// Remarks: Use SoundManager.GetCurrentDeviceList() to get the device.
- /// The available types of the StreamInfo for this API are SoundStreamTypeVoip and SoundStreamTypeMediaExternalOnly.
- /// Postcondition: You can apply this setting by calling ApplyStreamRouting().
+ /// The AudioStreamPolicy can be applied to each playback or recording stream via other API set.
+ /// (For example., , ,
+ /// , , etc.)
+ /// This method returns true only when the device is used for the stream which meets to the two conditions.
+ /// One is that the current AudioStreamPolicy sets a audio route path to the device and the other is that the playback
+ /// or recording stream from other API set should have already started to prepare or to play.(It depends on the API set.)
///
- /// The device item from the current sound devices list.
- public void RemoveDeviceForStreamRouting(AudioDevice soundDevice)
+ /// is null.
+ /// An internal error occurs.
+ /// The has already been disposed of.
+ ///
+ /// 6
+ public bool HasStreamOnDevice(AudioDevice device)
{
- int ret = Interop.AudioStreamPolicy.RemoveDeviceForStreamRouting(_streamInfo, soundDevice.Handle);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "Remove stream routing: " + (AudioManagerError)ret);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to remove device for stream routing");
+ if (device == null)
+ {
+ throw new ArgumentNullException(nameof(device));
+ }
+
+ var ret = Interop.AudioStreamPolicy.IsStreamOnDevice(Handle, device.Id, out var isOn);
+ ret.ThrowIfError("Failed to check stream on device");
+
+ return isOn;
}
+ ///
+ /// Releases all resources used by the .
+ ///
+ /// 3
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
+ ///
+ /// Releases the unmanaged resources used by the .
+ ///
+ /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
+ /// 3
protected virtual void Dispose(bool disposing)
{
- if(!_disposed) {
- if(disposing) {
- // to be used if there are any other disposable objects
- }
- if(_streamInfo != IntPtr.Zero) {
- Interop.AudioStreamPolicy.DestroyStreamInformation(_streamInfo); // Destroy the handle
- _streamInfo = IntPtr.Zero;
+ if (_disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ if (_handle != null)
+ {
+ _handle.Dispose();
}
_disposed = true;
}
}
- private static void RegisterFocusStateWatchEvent()
+ #region Static events
+
+ private static bool _isWatchCallbackRegistered;
+ private static EventHandler _streamFocusStateChanged;
+ private static Interop.AudioStreamPolicy.FocusStateWatchCallback _focusStateWatchCallback;
+ private static readonly object _streamFocusEventLock = new object();
+
+ ///
+ /// Occurs when the focus state for stream types is changed regardless of the process.
+ ///
+ /// 3
+ public static event EventHandler StreamFocusStateChanged
{
- _focusStateWatchCallback = (int id, AudioStreamFocusOptions options, AudioStreamFocusState focusState, AudioStreamFocusChangedReason reason, string extraInfo, IntPtr userData) => {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _Inside _focusStateWatchCallback : id = " + id + "options = " + options);
- FocusStateChangedEventArgs eventArgs = new FocusStateChangedEventArgs(focusState, reason, extraInfo);
- if(options == AudioStreamFocusOptions.Playback) {
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _eventArgs = " + eventArgs);
- _focusStateWatchForPlayback?.Invoke(null, eventArgs);
- } else if(options == AudioStreamFocusOptions.Recording) {
- _focusStateWatchForRecording?.Invoke(null, eventArgs);
- } else if(options == (AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording)) {
- _focusStateWatchForPlayback?.Invoke(null, eventArgs);
- _focusStateWatchForRecording?.Invoke(null, eventArgs);
+ add
+ {
+ lock (_streamFocusEventLock)
+ {
+ if (_isWatchCallbackRegistered == false)
+ {
+ RegisterFocusStateWatch();
+ _isWatchCallbackRegistered = true;
+ }
+ _streamFocusStateChanged += value;
}
- };
- int ret = Interop.AudioStreamPolicy.AddFocusStateWatchCallback(AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording, _focusStateWatchCallback, IntPtr.Zero, out _focusWatchCbId);
- Tizen.Log.Info(AudioStreamPolicyLog.Tag, "############# _AddFocusStateWatchCallback : ret = " + ret + " ID = " + _focusWatchCbId);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to set focus state watch callback");
+ }
+ remove
+ {
+ lock (_streamFocusEventLock)
+ {
+ _streamFocusStateChanged -= value;
+ }
+ }
}
- private static void UnregisterFocusStateWatch()
+ private static void RegisterFocusStateWatch()
{
- int ret = Interop.AudioStreamPolicy.RemoveFocusStateWatchCallback(_focusWatchCbId);
- AudioManagerErrorFactory.CheckAndThrowException(ret, "Unable to unset focus state watch callback");
+ _focusStateWatchCallback = (id, options, focusState, reason, extraInfo, _) =>
+ {
+ _streamFocusStateChanged?.Invoke(null,
+ new StreamFocusStateChangedEventArgs(options, focusState, reason, extraInfo));
+ };
+
+ Interop.AudioStreamPolicy.AddFocusStateWatchCallback(
+ AudioStreamFocusOptions.Playback | AudioStreamFocusOptions.Recording,
+ _focusStateWatchCallback, IntPtr.Zero, out var cbId).
+ ThrowIfError("Failed to initialize focus state event");
}
+ #endregion
}
}