using System;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Tizen.System;
using static Tizen.Multimedia.Interop.Radio;
try
{
- SetScanCompletedCb(_handle, ScanCompleteCallback).ThrowIfFailed("Failed to initialize radio");
- SetInterruptedCb(_handle, InterruptedCallback).ThrowIfFailed("Failed to initialize radio");
+ _scanCompletedCallback = _ => ScanCompleted?.Invoke(this, EventArgs.Empty);
+ _interruptedCallback = (reason, _) => Interrupted?.Invoke(this, new RadioInterruptedEventArgs(reason));
+ _scanUpdatedCallback = (frequency, _) => ScanUpdated?.Invoke(this, new ScanUpdatedEventArgs(frequency));
+ _scanStoppedCallback = _ => ScanStopped?.Invoke(this, EventArgs.Empty);
+
+ SetScanCompletedCb(_handle, _scanCompletedCallback).ThrowIfFailed("Failed to initialize radio");
+ SetInterruptedCb(_handle, _interruptedCallback).ThrowIfFailed("Failed to initialize radio");
}
catch (Exception)
{
}
}
+ private ScanUpdatedCallback _scanUpdatedCallback;
+
+ private ScanStoppedCallback _scanStoppedCallback;
+
+ private ScanCompletedCallback _scanCompletedCallback;
+
+ private InterruptedCallback _interruptedCallback;
+
/// <summary>
/// Occurs when the radio scanning information is updated.
/// </summary>
{
ValidateRadioState(RadioState.Ready, RadioState.Playing);
- ScanStart(Handle, ScanUpdatedCallback);
+ ScanStart(Handle, _scanUpdatedCallback).ThrowIfFailed("Failed to start scanning");
}
/// <summary>
{
ValidateRadioState(RadioState.Scanning);
- ScanStop(Handle, ScanStoppedCallback);
+ ScanStop(Handle, _scanStoppedCallback).ThrowIfFailed("Failed to stop scanning");
}
/// <summary>
/// It can be -1 if the seeking operation has failed.
/// </returns>
/// <remarks>The radio must be in the <see cref="RadioState.Playing"/> state.</remarks>
- /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
- public async Task<int> SeekUpAsync()
+ /// <exception cref="InvalidOperationException">
+ /// The radio is not in the valid state.\n
+ /// -or-\n
+ /// Seeking is in progress.
+ /// </exception>
+ public Task<int> SeekUpAsync()
{
- ValidateRadioState(RadioState.Playing);
-
- TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
- SeekCompletedCallback callback = (currentFrequency, _) =>
- {
- tcs.TrySetResult(currentFrequency);
- };
-
- SeekUp(Handle, callback);
- return await tcs.Task;
+ return SeekAsync(SeekUp);
}
/// <summary>
/// It can be -1 if the seeking operation has failed.
/// </returns>
/// <remarks>The radio must be in the <see cref="RadioState.Playing"/> state.</remarks>
- /// <exception cref="InvalidOperationException">The radio is not in the valid state.</exception>
- public async Task<int> SeekDownAsync()
+ /// <exception cref="InvalidOperationException">
+ /// The radio is not in the valid state.\n
+ /// -or-\n
+ /// Seeking is in progress.
+ /// </exception>
+ public Task<int> SeekDownAsync()
+ {
+ return SeekAsync(SeekDown);
+ }
+
+ private async Task<int> SeekAsync(Func<Interop.RadioHandle, SeekCompletedCallback, IntPtr, RadioError> func)
{
ValidateRadioState(RadioState.Playing);
- TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
- SeekCompletedCallback callback = (currentFrequency, _) =>
+ var tcs = new TaskCompletionSource<int>();
+ SeekCompletedCallback callback = (currentFrequency, _) => tcs.TrySetResult(currentFrequency);
+
+ GCHandle gcHandle;
+ try
{
- tcs.TrySetResult(currentFrequency);
- };
+ gcHandle = GCHandle.Alloc(callback);
- SeekDown(Handle, callback);
- return await tcs.Task;
+ func(Handle, callback, IntPtr.Zero).ThrowIfFailed("Failed to seek");
+ return await tcs.Task;
+ }
+ finally
+ {
+ gcHandle.Free();
+ }
}
private void ValidateFeatureSupported(string featurePath)
{
- bool supported = false;
- Information.TryGetValue(featurePath, out supported);
-
- if (supported == false)
+ if (Information.TryGetValue(featurePath, out bool supported) == false || supported == false)
{
throw new NotSupportedException($"The feature({featurePath}) is not supported.");
}
}
- private void ScanUpdatedCallback(int frequency, IntPtr data)
- {
- ScanUpdated?.Invoke(this, new ScanUpdatedEventArgs(frequency));
- }
-
- private void ScanStoppedCallback(IntPtr data)
- {
- ScanStopped?.Invoke(this, EventArgs.Empty);
- }
-
- private void ScanCompleteCallback(IntPtr data)
- {
- ScanCompleted?.Invoke(this, EventArgs.Empty);
- }
-
- private void InterruptedCallback(RadioInterruptedReason reason, IntPtr data)
- {
- Interrupted?.Invoke(this, new RadioInterruptedEventArgs(reason));
- }
-
private void ValidateRadioState(params RadioState[] required)
{
RadioState curState = State;