[WiFi][Connection] Apply CAPIs for thread handling (#134)
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionInternalManager.cs
index cad51a7..a4ef319 100755 (executable)
@@ -25,15 +25,17 @@ using System.Threading;
 
 namespace Tizen.Network.Connection
 {
-    class HandleHolder : IDisposable
+    class HandleHolder
     {
         private IntPtr Handle;
-        private bool disposed = false;
+        private int tid;
 
         public HandleHolder()
         {
-            Log.Debug(Globals.LogTag, "Handle: " + Handle);
-            int ret = Interop.Connection.Create(out Handle);
+            tid = Thread.CurrentThread.ManagedThreadId;
+            Log.Info(Globals.LogTag, "PInvoke connection_destroy for Thread " + tid);
+            int ret = Interop.Connection.Create(tid, out Handle);
+            Log.Info(Globals.LogTag, "Handle: " + Handle);
             if(ret != (int)ConnectionError.None)
             {
                 ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
@@ -44,7 +46,7 @@ namespace Tizen.Network.Connection
 
         ~HandleHolder()
         {
-            Dispose(false);
+            Destroy();
         }
 
         internal IntPtr GetHandle()
@@ -52,30 +54,11 @@ namespace Tizen.Network.Connection
             Log.Debug(Globals.LogTag, "handleholder handle = " + Handle);
             return Handle;
         }
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        private void Dispose(bool disposing)
-        {
-            Log.Debug(Globals.LogTag, ">>> HandleHolder Dispose with " + disposing);
-            Log.Debug(Globals.LogTag, ">>> Handle: " + Handle);
-            if (disposed)
-                return;
-
-            if (disposing)
-            {
-                // Free managed objects.
-                Destroy();
-            }
-            disposed = true;
-        }
 
         private void Destroy()
         {
-            Interop.Connection.Destroy(Handle);
+            Log.Info(Globals.LogTag, "PInvoke connection_destroy for Thread " + tid);
+            Interop.Connection.Destroy(tid, Handle);
             if (Handle != IntPtr.Zero)
             {
                 Handle = IntPtr.Zero;
@@ -85,28 +68,24 @@ namespace Tizen.Network.Connection
 
     internal class ConnectionInternalManager
     {
-        private bool disposed = false;
-        private static ConnectionInternalManager s_instance = null;
+        private static readonly Lazy<ConnectionInternalManager> s_instance =
+            new Lazy<ConnectionInternalManager>(() => new ConnectionInternalManager());
 
-        private EventHandler _ConnectionTypeChanged = null;
-        private EventHandler _IPAddressChanged = null;
-        private EventHandler _EthernetCableStateChanged = null;
-        private EventHandler _ProxyAddressChanged = null;
+        private EventHandler<ConnectionTypeEventArgs> _ConnectionTypeChanged = null;
+        private EventHandler<AddressEventArgs> _IPAddressChanged = null;
+        private EventHandler<EthernetCableStateEventArgs> _EthernetCableStateChanged = null;
+        private EventHandler<AddressEventArgs> _ProxyAddressChanged = null;
 
         private Interop.Connection.ConnectionAddressChangedCallback _connectionAddressChangedCallback;
         private Interop.Connection.ConnectionTypeChangedCallback _connectionTypeChangedCallback;
         private Interop.Connection.ConnectionAddressChangedCallback _proxyAddressChangedCallback;
+        private Interop.Connection.EthernetCableStateChangedCallback _ethernetCableStateChangedCallback;
 
         internal static ConnectionInternalManager Instance
         {
             get
             {
-                if (s_instance == null)
-                {
-                    s_instance = new ConnectionInternalManager();
-                }
-
-                return s_instance;
+                return s_instance.Value;
             }
         }
 
@@ -118,34 +97,11 @@ namespace Tizen.Network.Connection
 
         private ConnectionInternalManager()
         {
-
+            Log.Info(Globals.LogTag, "ConnectionInternalManager constructor");
         }
 
         ~ConnectionInternalManager()
         {
-            Dispose(false);
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        private void Dispose(bool disposing)
-        {
-            Log.Debug(Globals.LogTag, ">>> ConnectionInternalManager Dispose with disposing " + disposing + ", disposed " + disposed);
-            Log.Debug(Globals.LogTag, ">>> Handle: " + GetHandle());
-            if (disposed)
-                return;
-
-            if (disposing)
-            {
-                // Free managed objects.
-            }
-
-            UnregisterEvents();
-            disposed = true;
         }
 
         internal IntPtr GetHandle()
@@ -153,7 +109,7 @@ namespace Tizen.Network.Connection
             return s_threadName.Value.GetHandle();
         }
 
-        internal event EventHandler ConnectionTypeChanged
+        internal event EventHandler<ConnectionTypeEventArgs> ConnectionTypeChanged
         {
             add
             {
@@ -202,7 +158,7 @@ namespace Tizen.Network.Connection
             }
         }
 
-        internal event EventHandler EthernetCableStateChanged
+        internal event EventHandler<EthernetCableStateEventArgs> EthernetCableStateChanged
         {
             add
             {
@@ -224,10 +180,20 @@ namespace Tizen.Network.Connection
 
         private void EthernetCableStateChangedStart()
         {
-            int ret = Interop.Connection.SetEthernetCableStateChagedCallback(GetHandle(), EthernetCableStateChangedCallback, IntPtr.Zero);
+            _ethernetCableStateChangedCallback = (EthernetCableState state, IntPtr user_data) =>
+            {
+                if (_EthernetCableStateChanged != null)
+                {
+                    _EthernetCableStateChanged(null, new EthernetCableStateEventArgs(state));
+                }
+            };
+            int ret = Interop.Connection.SetEthernetCableStateChagedCallback(GetHandle(),
+                    _ethernetCableStateChangedCallback, IntPtr.Zero);
             if ((ConnectionError)ret != ConnectionError.None)
             {
-                Log.Error(Globals.LogTag, "It failed to register ethernet cable state changed callback, " + (ConnectionError)ret);
+                Log.Error(Globals.LogTag,
+                        "It failed to register ethernet cable state changed callback, " +
+                        (ConnectionError)ret);
                 ConnectionErrorFactory.ThrowConnectionException(ret);
             }
         }
@@ -237,20 +203,14 @@ namespace Tizen.Network.Connection
             int ret = Interop.Connection.UnsetEthernetCableStateChagedCallback(GetHandle());
             if ((ConnectionError)ret != ConnectionError.None)
             {
-                Log.Error(Globals.LogTag, "It failed to unregister ethernet cable state changed callback, " + (ConnectionError)ret);
+                Log.Error(Globals.LogTag,
+                        "It failed to unregister ethernet cable state changed callback, " + 
+                        (ConnectionError)ret);
                 ConnectionErrorFactory.ThrowConnectionException(ret);
             }
         }
 
-        private void EthernetCableStateChangedCallback(EthernetCableState state, IntPtr user_data)
-        {
-            if (_EthernetCableStateChanged != null)
-            {
-                _EthernetCableStateChanged(null, new EthernetCableStateEventArgs(state));
-            }
-        }
-
-        internal event EventHandler IPAddressChanged
+        internal event EventHandler<AddressEventArgs> IPAddressChanged
         {
             add
             {
@@ -303,7 +263,7 @@ namespace Tizen.Network.Connection
             }
         }
 
-        internal event EventHandler ProxyAddressChanged
+        internal event EventHandler<AddressEventArgs> ProxyAddressChanged
         {
             add
             {
@@ -400,7 +360,7 @@ namespace Tizen.Network.Connection
 
         internal System.Net.IPAddress GetIPAddress(AddressFamily family)
         {
-            Log.Debug(Globals.LogTag, "GetIPAddress " + family);
+            Log.Info(Globals.LogTag, "GetIPAddress " + family);
             IntPtr ip;
             int ret = Interop.Connection.GetIPAddress(GetHandle(), (int)family, out ip);
             if ((ConnectionError)ret != ConnectionError.None)
@@ -413,7 +373,15 @@ namespace Tizen.Network.Connection
 
             string result = Marshal.PtrToStringAnsi(ip);
             Interop.Libc.Free(ip);
-            return System.Net.IPAddress.Parse(result);;
+            Log.Info(Globals.LogTag, "IPAddress " + result + " (" + result.Length + ")");
+            if (result.Length == 0)
+            {
+                if (family == AddressFamily.IPv4)
+                    return System.Net.IPAddress.Parse("0.0.0.0");
+                else
+                    return System.Net.IPAddress.Parse("::");
+            }
+            return System.Net.IPAddress.Parse(result);
         }
 
         internal IEnumerable<System.Net.IPAddress> GetAllIPv6Addresses(ConnectionType type)
@@ -425,7 +393,10 @@ namespace Tizen.Network.Connection
                 if (ipv6Address != IntPtr.Zero)
                 {
                     string ipv6 = Marshal.PtrToStringAnsi(ipv6Address);
-                    ipList.Add(System.Net.IPAddress.Parse(ipv6));
+                    if (ipv6.Length == 0)
+                        ipList.Add(System.Net.IPAddress.Parse("::"));
+                    else
+                        ipList.Add(System.Net.IPAddress.Parse(ipv6));
                     return true;
                 }
                 return false;
@@ -463,7 +434,7 @@ namespace Tizen.Network.Connection
 
         internal string GetMacAddress(ConnectionType type)
         {
-            Log.Debug(Globals.LogTag, "GetMacAddress " + type);
+            Log.Info(Globals.LogTag, "GetMacAddress " + type);
             IntPtr mac;
             int ret = Interop.Connection.GetMacAddress(GetHandle(), (int)type, out mac);
             if ((ConnectionError)ret != ConnectionError.None)
@@ -559,7 +530,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get ConnectionType");
+                Log.Info(Globals.LogTag, "get ConnectionType");
                 int type = 0;
                 int ret = Interop.Connection.GetType(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -575,7 +546,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get CellularState");
+                Log.Info(Globals.LogTag, "get CellularState");
                 int type = 0;
                 int ret = Interop.Connection.GetCellularState(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -591,7 +562,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get WiFiState");
+                Log.Info(Globals.LogTag, "get WiFiState");
                 int type = 0;
                 int ret = Interop.Connection.GetWiFiState(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -607,7 +578,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get BluetoothState");
+                Log.Info(Globals.LogTag, "get BluetoothState");
                 int type = 0;
                 int ret = Interop.Connection.GetBtState(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -623,7 +594,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get ConnectionType");
+                Log.Info(Globals.LogTag, "get ConnectionType");
                 int type = 0;
                 int ret = Interop.Connection.GetEthernetState(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -639,7 +610,7 @@ namespace Tizen.Network.Connection
         {
             get
             {
-                Log.Debug(Globals.LogTag, "get EthernetCableState");
+                Log.Info(Globals.LogTag, "get EthernetCableState");
                 int type = 0;
                 int ret = Interop.Connection.GetEthernetCableState(GetHandle(), out type);
                 if ((ConnectionError)ret != ConnectionError.None)
@@ -729,7 +700,7 @@ namespace Tizen.Network.Connection
 
         internal void UpdateProfile(ConnectionProfile profile)
         {
-            Log.Debug(Globals.LogTag, "UpdateProfile");
+            Log.Info(Globals.LogTag, "UpdateProfile");
             if (profile != null)
             {
                 int ret = Interop.Connection.UpdateProfile(GetHandle(), profile.ProfileHandle);
@@ -750,16 +721,24 @@ namespace Tizen.Network.Connection
 
         internal ConnectionProfile GetCurrentProfile()
         {
-            Log.Debug(Globals.LogTag, "GetCurrentProfile");
+            Log.Info(Globals.LogTag, "GetCurrentProfile");
             IntPtr ProfileHandle;
             int ret = Interop.Connection.GetCurrentProfile(GetHandle(), out ProfileHandle);
             if ((ConnectionError)ret != ConnectionError.None)
             {
-                Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
-                ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
-                ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
-                ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
-                ConnectionErrorFactory.ThrowConnectionException(ret);
+                if ((ConnectionError)ret == ConnectionError.NoConnection)
+                {
+                    Log.Error(Globals.LogTag, "No connection " + (ConnectionError)ret);
+                    return null;
+                }
+                else
+                {
+                    Log.Error(Globals.LogTag, "It failed to get current profile, " + (ConnectionError)ret);
+                    ConnectionErrorFactory.CheckFeatureUnsupportedException(ret, "http://tizen.org/feature/network.telephony " + "http://tizen.org/feature/network.wifi " + "http://tizen.org/feature/network.tethering.bluetooth " + "http://tizen.org/feature/network.ethernet");
+                    ConnectionErrorFactory.CheckPermissionDeniedException(ret, "(http://tizen.org/privilege/network.get)");
+                    ConnectionErrorFactory.CheckHandleNullException(ret, (GetHandle() == IntPtr.Zero), "Connection Handle may have been disposed or released");
+                    ConnectionErrorFactory.ThrowConnectionException(ret);
+                }
             }
 
             ConnectionProfile Profile = new ConnectionProfile(ProfileHandle);
@@ -798,8 +777,10 @@ namespace Tizen.Network.Connection
                         Log.Error(Globals.LogTag, "Error occurs during set default cellular profile, " + Result);
                         task.SetException(new InvalidOperationException("Error occurs during set default cellular profile, " + Result));
                     }
-
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                 };
 
                 int ret = Interop.Connection.SetDefaultCellularServiceProfileAsync(GetHandle(), (int)type, profile.ProfileHandle, Callback, (IntPtr)0);
@@ -883,8 +864,10 @@ namespace Tizen.Network.Connection
                         Log.Error(Globals.LogTag, "Error occurs during connecting profile, " + Result);
                         task.SetException(new InvalidOperationException("Error occurs during connecting profile, " + Result));
                     }
-
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                 };
 
                 int ret = Interop.Connection.OpenProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);
@@ -919,8 +902,10 @@ namespace Tizen.Network.Connection
                         Log.Error(Globals.LogTag, "Error occurs during disconnecting profile, " + Result);
                         task.SetException(new InvalidOperationException("Error occurs during disconnecting profile, " + Result));
                     }
-
-                    task.SetResult(true);
+                    else
+                    {
+                        task.SetResult(true);
+                    }
                 };
 
                 int ret = Interop.Connection.CloseProfile(GetHandle(), profile.ProfileHandle, Callback, IntPtr.Zero);