[Connection][WiFi] Use TizenSynchronizationContext.Post for asynchronous methods...
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Connection / Tizen.Network.Connection / ConnectionProfile.cs
old mode 100644 (file)
new mode 100755 (executable)
index 6849fc0..9ba3f3a
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Licensed under the Apache License, Version 2.0 (the License);
@@ -19,54 +19,81 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Runtime.InteropServices;
+using Tizen.Applications;
 
 namespace Tizen.Network.Connection
 {
     /// <summary>
-    /// This Class is ConnectionProfile
+    /// This is the ConnectionProfile class. It provides event and properties of the connection profile.
     /// </summary>
+    /// <since_tizen> 3 </since_tizen>
     public class ConnectionProfile : IDisposable
     {
         internal IntPtr ProfileHandle = IntPtr.Zero;
-        private IAddressInformation Ipv4;
-        private IAddressInformation Ipv6;
+        private IAddressInformation IPv4;
+        private IAddressInformation IPv6;
         private bool disposed = false;
-        private EventHandler _ProfileStateChanged;
+        private EventHandler<ProfileStateEventArgs> _ProfileStateChanged = null;
+
+        private Interop.ConnectionProfile.ProfileStateChangedCallback _profileChangedCallback;
+
+        private TizenSynchronizationContext context = new TizenSynchronizationContext();
+
+        internal IntPtr GetHandle()
+        {
+            return ProfileHandle;
+        }
 
         /// <summary>
-        /// The event that is called when the state of profile is changed.
+        /// The event is called when the state of profile is changed.
         /// </summary>
-        public event EventHandler ProfileStateChanged
+        /// <since_tizen> 3 </since_tizen>
+        /// <feature>http://tizen.org/feature/network.ethernet</feature>
+        /// <feature>http://tizen.org/feature/network.telephony</feature>
+        /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.wifi</feature>
+        /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
+        public event EventHandler<ProfileStateEventArgs> ProfileStateChanged
         {
             add
             {
-                if (_ProfileStateChanged == null)
+                Log.Debug(Globals.LogTag, "ProfileStateChanged add");
+                context.Post((x) =>
                 {
-                    ProfileStateChangedStart();
-                }
-                _ProfileStateChanged += value;
+                    if (_ProfileStateChanged == null)
+                    {
+                        ProfileStateChangedStart();
+                    }
+                    _ProfileStateChanged += value;
+                }, null);
             }
             remove
             {
-                _ProfileStateChanged -= value;
-                if (_ProfileStateChanged == null)
+                Log.Debug(Globals.LogTag, "ProfileStateChanged remove");
+                context.Post((x) =>
                 {
-                    ProfileStateChangedStop();
-                }
+                    _ProfileStateChanged -= value;
+                    if (_ProfileStateChanged == null)
+                    {
+                        ProfileStateChangedStop();
+                    }
+                }, null);
             }
         }
 
-        private void TypeChangedCallback(ProfileState state, IntPtr userData)
+        private void ProfileStateChangedStart()
         {
-            if (_ProfileStateChanged != null)
+            _profileChangedCallback = (ProfileState state, IntPtr userData) =>
             {
-                _ProfileStateChanged(null, new ProfileStateEventArgs(state));
-            }
-        }
+                Log.Info(Globals.LogTag, "***** MOON ProfileStateChanged occur");
+                if (_ProfileStateChanged != null)
+                {
+                    _ProfileStateChanged(null, new ProfileStateEventArgs(state));
+                }
+            };
 
-        private void ProfileStateChangedStart()
-        {
-            int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, TypeChangedCallback, IntPtr.Zero);
+            Log.Debug(Globals.LogTag, "ProfileStateChangedStart");
+            int ret = Interop.ConnectionProfile.SetStateChangeCallback(ProfileHandle, _profileChangedCallback, IntPtr.Zero);
             if ((ConnectionError)ret != ConnectionError.None)
             {
                 Log.Error(Globals.LogTag, "It failed to register callback for changing profile state, " + (ConnectionError)ret);
@@ -75,6 +102,7 @@ namespace Tizen.Network.Connection
 
         private void ProfileStateChangedStop()
         {
+            Log.Debug(Globals.LogTag, "ProfileStateChangedStop");
             int ret = Interop.ConnectionProfile.UnsetStateChangeCallback(ProfileHandle);
             if ((ConnectionError)ret != ConnectionError.None)
             {
@@ -82,18 +110,25 @@ namespace Tizen.Network.Connection
             }
         }
 
-        public ConnectionProfile(IntPtr handle)
+        internal ConnectionProfile(IntPtr handle)
         {
             ProfileHandle = handle;
-            Ipv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.Ipv4);
-            Ipv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.Ipv6);
+            IPv4 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv4);
+            IPv6 = new ConnectionAddressInformation(ProfileHandle, AddressFamily.IPv6);
         }
 
+        /// <summary>
+        /// Destroy the ConnectionProfile object
+        /// </summary>
         ~ConnectionProfile()
         {
             Dispose(false);
         }
 
+        /// <summary>
+        /// Disposes the memory allocated to unmanaged resources.
+        /// </summary>
+        /// <since_tizen> 3 </since_tizen>
         public void Dispose()
         {
             Dispose(true);
@@ -102,21 +137,43 @@ namespace Tizen.Network.Connection
 
         private void Dispose(bool disposing)
         {
+            Log.Debug(Globals.LogTag, ">>> ConnectionProfile Dispose with " + disposing);
             if (disposed)
                 return;
 
-            if (disposing)
+            // Free unmanaged objects
+            UnregisterEvents();
+            Destroy();
+            disposed = true;
+        }
+
+        private void UnregisterEvents()
+        {
+            if (_ProfileStateChanged != null)
             {
-                // Free managed objects.
+                ProfileStateChangedStop();
             }
+        }
+
+        private void Destroy()
+        {
             Interop.ConnectionProfile.Destroy(ProfileHandle);
-            ProfileStateChangedStop();
-            disposed = true;
+            ProfileHandle = IntPtr.Zero;
+        }
+
+        internal void CheckDisposed()
+        {
+            if (disposed)
+            {
+                throw new ObjectDisposedException(GetType().FullName);
+            }
         }
 
         /// <summary>
-        /// Gets the profile ID.
+        /// The profile ID.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Unique ID of the profile.</value>
         public string Id
         {
             get
@@ -134,9 +191,10 @@ namespace Tizen.Network.Connection
         }
 
         /// <summary>
-        /// Gets the profile name.
+        /// The profile name.
         /// </summary>
-        /// <privilege>http://tizen.org/privilege/network.get</privilege>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>User friendly name of the profile.</value>
         public string Name
         {
             get
@@ -154,8 +212,10 @@ namespace Tizen.Network.Connection
         }
 
         /// <summary>
-        /// Gets the network type.
+        /// The network type.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Profile type of the network connection.</value>
         public ConnectionProfileType Type
         {
             get
@@ -171,8 +231,10 @@ namespace Tizen.Network.Connection
         }
 
         /// <summary>
-        /// Gets the name of the network interface, e.g. eth0 and pdp0.
+        /// The name of the network interface.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Network interface name, for example, eth0 and pdp0.</value>
         public string InterfaceName
         {
             get
@@ -190,25 +252,82 @@ namespace Tizen.Network.Connection
         }
 
         /// <summary>
-        /// Gets the profile state.
+        /// Refreshes the profile information.
         /// </summary>
-        public ProfileState State
+        /// <since_tizen> 3 </since_tizen>
+        /// <privilege>http://tizen.org/privilege/network.get</privilege>
+        /// <feature>http://tizen.org/feature/network.ethernet</feature>
+        /// <feature>http://tizen.org/feature/network.telephony</feature>
+        /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.wifi</feature>
+        /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
+        /// <exception cref="System.UnauthorizedAccessException">Thrown when a permission is denied.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when a value is an invalid parameter.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
+        /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
+        public void Refresh()
         {
-            get
+            CheckDisposed();
+            int ret = Interop.ConnectionProfile.Refresh(ProfileHandle);
+            if ((ConnectionError)ret != ConnectionError.None)
             {
-                int Value;
-                int ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
-                if ((ConnectionError)ret != ConnectionError.None)
-                {
-                    Log.Error(Globals.LogTag, "It failed to get profile state, " + (ConnectionError)ret);
-                }
-                return (ProfileState)Value;
+                Log.Error(Globals.LogTag, "It failed to get network interface name, " + (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, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+                ConnectionErrorFactory.ThrowConnectionException(ret);
+            }
+        }
+
+        /// <summary>
+        /// Gets the network state.
+        /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <param name="family">The address family.</param>
+        /// <returns>The network state.</returns>
+        /// <feature>http://tizen.org/feature/network.ethernet</feature>
+        /// <feature>http://tizen.org/feature/network.telephony</feature>
+        /// <feature>http://tizen.org/feature/network.tethering.bluetooth</feature>
+        /// <feature>http://tizen.org/feature/network.wifi</feature>
+        /// <exception cref="System.NotSupportedException">Thrown when a feature is not supported.</exception>
+        /// <exception cref="System.ArgumentException">Thrown when a value is an invalid parameter.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
+        /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
+        public ProfileState GetState(AddressFamily family)
+        {
+            CheckDisposed();
+            int Value;
+            int ret = (int)ConnectionError.None;
+            if (family == AddressFamily.IPv4)
+            {
+                ret = Interop.ConnectionProfile.GetState(ProfileHandle, out Value);
+            }
+
+            else
+            {
+                ret = Interop.ConnectionProfile.GetIPv6State(ProfileHandle, out Value);
+            }
+
+            if ((ConnectionError)ret != ConnectionError.None)
+            {
+                Log.Error(Globals.LogTag, "It failed to get profile state, " + (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.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+                ConnectionErrorFactory.ThrowConnectionException(ret);
             }
+
+            return (ProfileState)Value;
         }
 
         /// <summary>
-        /// Gets the Proxy type.
+        /// The Proxy type.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Proxy type of the connection.</value>
+        /// <exception cref="System.NotSupportedException">Thrown during set when a feature is not supported.</exception>
+        /// <exception cref="System.ArgumentException">Thrown during set when a value is an invalid parameter.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
+        /// <exception cref="System.ObjectDisposedException">Thrown during set when a operation is performed on a disposed object.</exception>
         public ProxyType ProxyType
         {
             get
@@ -222,12 +341,16 @@ namespace Tizen.Network.Connection
                 return (ProxyType)Value;
 
             }
+
             set
             {
+                CheckDisposed();
                 int ret = Interop.ConnectionProfile.SetProxyType(ProfileHandle, (int)value);
                 if ((ConnectionError)ret != ConnectionError.None)
                 {
                     Log.Error(Globals.LogTag, "It failed to set proxy type, " + (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.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
                     ConnectionErrorFactory.ThrowConnectionException(ret);
                 }
             }
@@ -236,12 +359,19 @@ namespace Tizen.Network.Connection
         /// <summary>
         /// The proxy address.
         /// </summary>
-        public String ProxyAddress
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Proxy address of the connection.</value>
+        /// <exception cref="System.NotSupportedException">Thrown during set when a feature is not supported.</exception>
+        /// <exception cref="System.ArgumentException">Thrown during set when a value is an invalid parameter.</exception>
+        /// <exception cref="System.ArgumentNullException">Thrown during set when a value is null.</exception>
+        /// <exception cref="System.InvalidOperationException">Thrown during set when a profile instance is invalid or when a method fails due to an invalid operation.</exception>
+        /// <exception cref="System.ObjectDisposedException">Thrown when an operation is performed on a disposed object.</exception>
+        public string ProxyAddress
         {
             get
             {
                 IntPtr Value;
-                int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.Ipv4, out Value);
+                int ret = Interop.ConnectionProfile.GetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, out Value);
                 if ((ConnectionError)ret != ConnectionError.None)
                 {
                     Log.Error(Globals.LogTag, "It failed to get proxy address, " + (ConnectionError)ret);
@@ -251,44 +381,61 @@ namespace Tizen.Network.Connection
                 return result;
 
             }
+
             set
             {
-                int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.Ipv4, value.ToString());
-                if ((ConnectionError)ret != ConnectionError.None)
+                CheckDisposed();
+                if (value != null)
                 {
-                    Log.Error(Globals.LogTag, "It failed to set proxy address, " + (ConnectionError)ret);
-                    ConnectionErrorFactory.ThrowConnectionException(ret);
+                    int ret = Interop.ConnectionProfile.SetProxyAddress(ProfileHandle, (int)AddressFamily.IPv4, value);
+                    if ((ConnectionError)ret != ConnectionError.None)
+                    {
+                        Log.Error(Globals.LogTag, "It failed to set proxy address, " + (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.CheckHandleNullException(ret, (ProfileHandle == IntPtr.Zero), "ProfileHandle may have been disposed or released");
+                        ConnectionErrorFactory.ThrowConnectionException(ret);
+                    }
+                }
+
+                else
+                {
+                    throw new ArgumentNullException("ProxyAddress is null");
                 }
             }
         }
 
         /// <summary>
-        /// The subnet mask address(Ipv4).
+        /// The address information (IPv4).
         /// </summary>
-        public IAddressInformation Ipv4Settings
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Instance of IAddressInformation with IPV4 address.</value>
+        public IAddressInformation IPv4Settings
         {
             get
             {
-                return Ipv4;
+                return IPv4;
 
             }
         }
 
         /// <summary>
-        /// The subnet mask address(Ipv4).
+        /// The address information (IPv6).
         /// </summary>
-        public IAddressInformation Ipv6Settings
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>Instance of IAddressInformation with IPV6 address.</value>
+        public IAddressInformation IPv6Settings
         {
             get
             {
-                return Ipv6;
+                return IPv6;
             }
         }
     }
 
     /// <summary>
-    /// An extended EventArgs class which contains changed profile state.
+    /// An extended EventArgs class, which contains changed profile state.
     /// </summary>
+    /// <since_tizen> 3 </since_tizen>
     public class ProfileStateEventArgs : EventArgs
     {
         private ProfileState _State = ProfileState.Disconnected;
@@ -301,6 +448,8 @@ namespace Tizen.Network.Connection
         /// <summary>
         /// The profile state.
         /// </summary>
+        /// <since_tizen> 3 </since_tizen>
+        /// <value>State type of the connection profile.</value>
         public ProfileState State
         {
             get