[Remoting] Modified task related codes in ScreenMirroring. 86/165186/1
authorcoderhyme <jhyo.kim@samsung.com>
Wed, 27 Dec 2017 03:10:46 +0000 (12:10 +0900)
committercoderhyme <jhyo.kim@samsung.com>
Wed, 27 Dec 2017 03:10:46 +0000 (12:10 +0900)
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>
src/Tizen.Multimedia.Remoting/Interop/Interop.ScreenMirroring.cs
src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroring.cs
src/Tizen.Multimedia.Remoting/ScreenMirroring/ScreenMirroringError.cs

index ef4b026..ef91193 100755 (executable)
@@ -49,13 +49,13 @@ internal static partial class Interop
         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);
index 5b3c96a..6865586 100644 (file)
@@ -64,7 +64,8 @@ namespace Tizen.Multimedia.Remoting
         {
             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.");
@@ -240,6 +241,27 @@ namespace Tizen.Multimedia.Remoting
             }
         }
 
+        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>
@@ -276,15 +298,7 @@ namespace Tizen.Multimedia.Remoting
 
             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>
@@ -308,15 +322,7 @@ namespace Tizen.Multimedia.Remoting
         {
             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>
@@ -340,15 +346,7 @@ namespace Tizen.Multimedia.Remoting
         {
             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>
@@ -372,15 +370,7 @@ namespace Tizen.Multimedia.Remoting
         {
             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>
index 7c76fd4..e00302a 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 using System;
+using System.Diagnostics;
 using Tizen.Internals.Errors;
 
 namespace Tizen.Multimedia.Remoting
@@ -40,28 +41,35 @@ 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()}.");
             }
         }
     }