1. Should avoid using TaskFactory.StartNew with a single argument due to the SynchronizationContext issue.
2. Must set exceptions to the TaskCompletionSource when the opeartion fails instead of throwing exceptions in the delegates of tasks. Otherwise, the wrapping tasks could be blocked forever.
Change-Id: Icb7bf1c82add0b62b2b57932a5cd327b178a1eca
Signed-off-by: coderhyme <jhyo.kim@samsung.com>
internal static extern ScreenMirroringErrorCode Connect(IntPtr handle);
[DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_start")]
- internal static extern ScreenMirroringErrorCode StartAsync(IntPtr handle);
+ internal static extern ScreenMirroringErrorCode Start(IntPtr handle);
[DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_pause")]
- internal static extern ScreenMirroringErrorCode PauseAsync(IntPtr handle);
+ internal static extern ScreenMirroringErrorCode Pause(IntPtr handle);
[DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_resume")]
- internal static extern ScreenMirroringErrorCode ResumeAsync(IntPtr handle);
+ internal static extern ScreenMirroringErrorCode Resume(IntPtr handle);
[DllImport(Libraries.ScreenMirroring, EntryPoint = "scmirroring_sink_disconnect")]
internal static extern ScreenMirroringErrorCode Disconnect(IntPtr handle);
{
if (IsSupported() == false)
{
- throw new PlatformNotSupportedException($"The feature({Feature}) is not supported on the current device");
+ throw new PlatformNotSupportedException(
+ $"The feature({Feature}) is not supported on the current device.");
}
Native.Create(out _handle).ThrowIfError("Failed to create ScreenMirroring.");
}
}
+ private Task RunAsync(Func<IntPtr, ScreenMirroringErrorCode> func, string failMessage)
+ {
+ var tcs = new TaskCompletionSource<bool>();
+
+ Task.Run(() =>
+ {
+ var ret = func(Handle);
+
+ if (ret == ScreenMirroringErrorCode.None)
+ {
+ tcs.SetResult(true);
+ }
+ else
+ {
+ tcs.SetException(ret.AsException(failMessage));
+ }
+ });
+
+ return tcs.Task;
+ }
+
/// <summary>
/// Creates the connection and ready for receiving data from a mirroring source.
/// </summary>
Native.SetIpAndPort(Handle, sourceIp, Port.ToString()).ThrowIfError("Failed to set ip.");
- var tcs = new TaskCompletionSource<bool>();
-
- Task.Factory.StartNew(() =>
- {
- Native.Connect(Handle).ThrowIfError("Failed to connect");
- tcs.SetResult(true);
- });
-
- return tcs.Task;
+ return RunAsync(Native.Connect, "Failed to connect.");
}
/// <summary>
{
ValidateState(ScreenMirroringState.Connected);
- var tcs = new TaskCompletionSource<bool>();
-
- Task.Factory.StartNew(() =>
- {
- Native.StartAsync(Handle).ThrowIfError("Failed to start.");
- tcs.TrySetResult(true);
- });
-
- return tcs.Task;
+ return RunAsync(Native.Start, "Failed to start.");
}
/// <summary>
{
ValidateState(ScreenMirroringState.Playing);
- var tcs = new TaskCompletionSource<bool>();
-
- Task.Factory.StartNew(() =>
- {
- Native.PauseAsync(Handle).ThrowIfError("Failed to prepare.");
- tcs.TrySetResult(true);
- });
-
- return tcs.Task;
+ return RunAsync(Native.Pause, "Failed to pause.");
}
/// <summary>
{
ValidateState(ScreenMirroringState.Paused);
- var tcs = new TaskCompletionSource<bool>();
-
- Task.Factory.StartNew(() =>
- {
- Native.ResumeAsync(Handle).ThrowIfError("Failed to resume.");
- tcs.TrySetResult(true);
- });
-
- return tcs.Task;
+ return RunAsync(Native.Resume, "Failed to resume.");
}
/// <summary>
*/
using System;
+using System.Diagnostics;
using Tizen.Internals.Errors;
namespace Tizen.Multimedia.Remoting
return;
}
+ throw err.AsException(message);
+ }
+
+ internal static Exception AsException(this ScreenMirroringErrorCode err, string message)
+ {
+ Debug.Assert(err != ScreenMirroringErrorCode.None);
+
switch (err)
{
case ScreenMirroringErrorCode.InvalidParameter:
- throw new ArgumentException(message);
+ return new ArgumentException(message);
case ScreenMirroringErrorCode.OutOfMemory:
- throw new OutOfMemoryException(message);
+ return new OutOfMemoryException(message);
case ScreenMirroringErrorCode.PermissionDenied:
- throw new UnauthorizedAccessException(message);
+ return new UnauthorizedAccessException(message);
case ScreenMirroringErrorCode.NotSupported:
- throw new NotSupportedException(message);
+ return new NotSupportedException(message);
case ScreenMirroringErrorCode.InvalidOperation:
- throw new InvalidOperationException(message);
+ return new InvalidOperationException(message);
case ScreenMirroringErrorCode.ConnectionTimeOut:
- throw new TimeoutException(message);
+ return new TimeoutException(message);
default:
- throw new InvalidOperationException($"Unknown error : {err.ToString()}.");
+ return new InvalidOperationException($"Unknown error : {err.ToString()}.");
}
}
}