Activate Wi-Fi when the application calls NetConnection.Start() on Wi-Fi bearer.
authorJaemin Ahn <j.m.ahn@samsung.com>
Wed, 27 Mar 2013 01:09:07 +0000 (10:09 +0900)
committerJaemin Ahn <j.m.ahn@samsung.com>
Wed, 27 Mar 2013 01:09:07 +0000 (10:09 +0900)
Change-Id: I67e3f6ad59ef45bf94678f35d086c708b817624f
Signed-off-by: Jaemin Ahn <j.m.ahn@samsung.com>
src/CMakeLists.txt [changed mode: 0755->0644]
src/FNet_NetConnectionEvent.cpp
src/FNet_NetConnectionEvent.h
src/FNet_NetConnectionImpl.cpp
src/FNet_WifiSystemNetConnection.cpp
src/FNet_WifiSystemNetConnection.h
src/wifi/FNetWifi_WifiSystemAdapter.cpp

old mode 100755 (executable)
new mode 100644 (file)
index 4a208c8..ed85888
@@ -145,6 +145,7 @@ TARGET_LINK_LIBRARIES(${this_target} "-lchromium" )
 TARGET_LINK_LIBRARIES(${this_target} "-L/usr/lib/osp -losp-appfw" )
 TARGET_LINK_LIBRARIES(${this_target} "-lcapi-network-connection" )
 TARGET_LINK_LIBRARIES(${this_target} "-lcapi-network-tethering" )
+TARGET_LINK_LIBRARIES(${this_target} "-lcapi-network-wifi" )
 TARGET_LINK_LIBRARIES(${this_target} "-lssl" )
 TARGET_LINK_LIBRARIES(${this_target} "-lcurl" )
 TARGET_LINK_LIBRARIES(${this_target} "-lwifi-direct" )
index b8fdd12..4f7f5d8 100644 (file)
@@ -82,6 +82,7 @@ _NetConnectionEvent::_NetConnectionEvent(void)
        : __refCount(1)
        , __connectionState(NET_CONNECTION_STATE_NONE)
        , __pSystemConnection(null)
+       , __isManagedSystemConnection(false)
        , __pListenerMap(null)
 {
 }
@@ -212,9 +213,16 @@ _NetConnectionEvent::GetConnectionState(void) const
 }
 
 void
-_NetConnectionEvent::SetSystemConnection(_SystemNetConnection* pSystemConnection)
+_NetConnectionEvent::SetSystemConnection(_SystemNetConnection* pSystemConnection, bool isManaged)
 {
        __pSystemConnection = pSystemConnection;
+       __isManagedSystemConnection = isManaged;
+}
+
+bool
+_NetConnectionEvent::IsManagedSystemConnection(void) const
+{
+       return __isManagedSystemConnection;
 }
 
 int
index be6a26c..d57a365 100644 (file)
@@ -105,7 +105,8 @@ public:
        void SetConnectionState(NetConnectionState connectionState);
        NetConnectionState GetConnectionState(void) const;
 
-       void SetSystemConnection(_SystemNetConnection* pConnection);
+       void SetSystemConnection(_SystemNetConnection* pConnection, bool isManaged = true);
+       bool IsManagedSystemConnection(void) const;
 
        int AddRef(void);
        int Release(void);
@@ -134,6 +135,7 @@ private:
        _NetListenerComparer __comparer;
        NetConnectionState __connectionState;
        _SystemNetConnection* __pSystemConnection;
+       bool __isManagedSystemConnection;
        Tizen::Base::Collection::HashMapT<_NetListenerKey, Tizen::Base::Object*>* __pListenerMap;
 }; // _NetConnectionEvent
 
index 469cae2..f1ebfc3 100644 (file)
@@ -152,7 +152,7 @@ _NetConnectionImpl::Construct(NetConnection* pNetConnection, NetAccountId netAcc
        r = pSystemNetConnection->AddEvent(*pEvent);
        SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
 
-       pEvent->SetSystemConnection(pSystemNetConnection);
+       pEvent->SetSystemConnection(pSystemNetConnection, false);
 
        __pNetConnection = pNetConnection;
        __netAccountId = netAccountId;
index f721d8c..f7bde44 100644 (file)
  */
 
 #include <net_connection.h>
+#include <wifi.h>
 #include <FNetNetConnectionInfo.h>
 #include <FBaseRtMutexGuard.h>
 #include <FBaseSysLog.h>
+#include <FSysSettingInfo.h>
 #include <FBase_StringConverter.h>
+#include <FApp_AppManagerImpl.h>
 #include "FNet_NetTypes.h"
 #include "FNet_NetConnectionInfoImpl.h"
 #include "FNet_WifiSystemNetConnection.h"
 #include "FNet_NetConnectionEventArg.h"
 
 using namespace std;
+using namespace Tizen::App;
 using namespace Tizen::Base;
 using namespace Tizen::Base::Collection;
 using namespace Tizen::Base::Runtime;
+using namespace Tizen::System;
 
 namespace Tizen { namespace Net {
 
+static const char* _WIFI_QS_APP_ID = "net.wifi-qs";
+
 void
 WifiConnectionTypeChangedCallback(connection_type_e type, void* pUserData)
 {
@@ -65,21 +72,66 @@ WifiConnectionTypeChangedCallback(connection_type_e type, void* pUserData)
                                E_SYSTEM, "WIFI profileHandle is not found.");
 
                SysLog(NID_NET, "Wifi is connected.");
-               pConnection->HandleStartEvent();
-               pConnection->UpdateConnectionInfo(profileHandle);
+
+               if (pConnection->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+               {
+                       pConnection->HandleStartResponse(E_SUCCESS, profileHandle);
+               }
+               else
+               {
+                       pConnection->HandleStartEvent();
+                       pConnection->UpdateConnectionInfo(profileHandle);
+               }
 
                connection_profile_destroy(profileHandle);
        }
        else
        {
                SysLog(NID_NET, "Wifi is not connected.");
-               pConnection->HandleStopEvent(E_NETWORK_FAILED);
-               pConnection->UpdateConnectionInfo(null);
+
+               if (pConnection->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+               {
+                       bool isWifiQsRunning = false;
+
+                       isWifiQsRunning = _AppManagerImpl::GetInstance()->IsRunning(String(_WIFI_QS_APP_ID));
+
+                       if (isWifiQsRunning)
+                       {
+                               SysLog(NID_NET, "Ignore disconnected event on the starting state because Wi-Fi QuickStart is running.");
+                       }
+                       else
+                       {
+                               SysLog(NID_NET, "Failed to connect Wifi.");
+                               pConnection->HandleStartResponse(E_NETWORK_FAILED, null);
+                       }
+               }
+               else
+               {
+                       pConnection->HandleStopEvent(E_NETWORK_FAILED);
+                       pConnection->UpdateConnectionInfo(null);
+               }
        }
 }
 
+void
+WifiActivatedCallback(wifi_error_e res, void* pUserData)
+{
+       _WifiSystemNetConnection* pConnection = static_cast<_WifiSystemNetConnection*>(pUserData);
+
+       SysLog(NID_NET, "Enter with res[%d].", res);
+
+       if (res != WIFI_ERROR_NONE)
+       {
+               SysLogException(NID_NET, E_NETWORK_FAILED, "[E_NETWORK_FAILED] Failed to activate Wi-Fi.");
+               pConnection->HandleStartResponse(E_NETWORK_FAILED, null);
+       }
+
+       SysLog(NID_NET, "Exit.");
+}
+
 _WifiSystemNetConnection::_WifiSystemNetConnection(void)
        : __pConnectionHandle(null)
+       , __pTimer(null)
 {
 }
 
@@ -92,6 +144,8 @@ _WifiSystemNetConnection::Construct(void)
 {
        result r = E_SUCCESS;
        unique_ptr<void, _ConnectionDeleter> pConnectionHandle;
+       unique_ptr<Timer> pTimer;
+
        int ret = CONNECTION_ERROR_NONE;
        connection_h connectionHandle = null;
        connection_profile_h profileHandle = null;
@@ -100,9 +154,19 @@ _WifiSystemNetConnection::Construct(void)
        SysAssertf(__pConnectionHandle == null,
                        "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class.");
 
+       pTimer.reset(new (std::nothrow) Timer());
+       SysTryReturnResult(NID_NET, pTimer != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+       r = pTimer->Construct(*this);
+       SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.");
+
        r = _SystemNetConnection::Initialize(L"WIFI");
        SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.", GetErrorMessage(r));
 
+       ret = wifi_initialize();
+       SysTryCatch(NID_NET, ((ret == WIFI_ERROR_NONE) || (ret == WIFI_ERROR_INVALID_OPERATION)),
+                       r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] wifi_initialize() failed with ret=[%d]", ret);
+
        ret = connection_create(&connectionHandle);
        SysTryCatch(NID_NET, ret == CONNECTION_ERROR_NONE, r = E_SYSTEM, E_SYSTEM,
                        "[%s] A system error has been occurred. The return value from connection_create() is %d", GetErrorMessage(E_SYSTEM), ret);
@@ -138,6 +202,7 @@ _WifiSystemNetConnection::Construct(void)
        }
 
        __pConnectionHandle = move(pConnectionHandle);
+       __pTimer = move(pTimer);
 
        return r;
 
@@ -147,6 +212,187 @@ CATCH:
        return r;
 }
 
+result
+_WifiSystemNetConnection::Start(_NetConnectionEvent& event)
+{
+       SysLog(NID_NET, "Starting WIFI connection.");
+
+       result r = E_SUCCESS;
+
+       SysAssertf(_pEventList != null, "Not yet constructed. Construct() should be called before use.");
+
+       MutexGuard locked(*_pLock);
+
+       if (_connectionState == NET_CONNECTION_STATE_STARTED)
+       {
+               // Already Started
+               SysLog(NID_NET, "WIFI connection is already started.");
+
+               if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTED)
+               {
+                       unique_ptr<_NetConnectionEventArg> pEventArg(new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, E_SUCCESS));
+                       SysTryReturnResult(NID_NET, pEventArg != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+                       event.SetConnectionState(NET_CONNECTION_STATE_STARTED);
+                       r = event.FireAsync(*pEventArg);
+                       SysTryReturnResult(NID_NET, r == E_SUCCESS, r, "Propagating.", GetErrorMessage(r));
+
+                       _refCount++;
+                       pEventArg.release();
+               }
+       }
+       else if ((_connectionState == NET_CONNECTION_STATE_STARTING) || (_connectionState == NET_CONNECTION_STATE_STOPPING))
+       {
+               // Waiting Response
+               SysLog(NID_NET, "WIFI connection is waiting response.");
+
+               if (event.GetConnectionState() != NET_CONNECTION_STATE_STARTING)
+               {
+                       event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
+                       _refCount++;
+               }
+       }
+       else
+       {
+               // None or Stopped
+               SysLog(NID_NET, "WIFI connection is not active.");
+
+               SysTryReturnResult(NID_NET, !event.IsManagedSystemConnection(), E_INVALID_CONNECTION, "Wi-Fi activation is not allowed for a managed network connection.");
+
+               int ret = WIFI_ERROR_NONE;
+               bool isActivated = false;
+
+               ret = wifi_is_activated(&isActivated);
+               SysTryReturnResult(NID_NET, ret == WIFI_ERROR_NONE, E_SYSTEM, "wifi_is_activated() failed with ret=[%d].", ret);
+               SysTryReturnResult(NID_NET, !isActivated, E_INVALID_CONNECTION, "Wi-Fi is already activated, so can't start it.");
+
+           bool isFlightModeEnabled = false;
+           r = SettingInfo::GetValue(L"http://tizen.org/setting/network.flight_mode", isFlightModeEnabled);
+               SysTryReturnResult(NID_NET, r == E_SUCCESS && !isFlightModeEnabled, E_INVALID_CONNECTION, "Flight mode is enabled.");
+
+               r = _AppManagerImpl::GetInstance()->AddAppEventListener(*this);
+               SysTryReturnResult(NID_NET, r == E_SUCCESS, E_SYSTEM, "Failed to set application event listener.");
+
+               ret = wifi_activate(WifiActivatedCallback, this);
+               if (ret != WIFI_ERROR_NONE)
+               {
+                       SysLogException(NID_NET, E_SYSTEM, "[E_SYSTEM] wifi_activate() failed with ret=[%d].", ret);
+
+                       _AppManagerImpl::GetInstance()->RemoveAppEventListener(*this);
+
+                       return E_SYSTEM;
+               }
+
+               _connectionState = NET_CONNECTION_STATE_STARTING;
+               event.SetConnectionState(NET_CONNECTION_STATE_STARTING);
+               _refCount++;
+       }
+
+       locked.Unlock();
+
+       SysLog(NID_NET, "Exit with result[%s].", GetErrorMessage(r));
+
+       return r;
+}
+
+void
+_WifiSystemNetConnection::HandleStartResponse(result error, void* pData)
+{
+       SysLog(NID_NET, "Start response is received with result[%s].", GetErrorMessage(error));
+
+       IEnumerator* pEnum = null;
+       _NetConnectionEvent* pEvent = null;
+       _NetConnectionEventArg* pStartEventArg = null;
+
+       if (_connectionState != NET_CONNECTION_STATE_STARTING)
+       {
+               SysLog(NID_NET, "Ignore _WifiSystemNetConnection::HandleStartResponse() because this is NOT in starting state.");
+               return;
+       }
+
+       _AppManagerImpl::GetInstance()->RemoveAppEventListener(*this);
+
+       MutexGuard locked(*_pLock);
+
+       if (error == E_SUCCESS)
+       {
+               _bearerType = NET_BEARER_WIFI;
+               _connectionState = NET_CONNECTION_STATE_STARTED;
+               _pConnectionInfo->Update(pData);
+       }
+       else
+       {
+               _bearerType = NET_BEARER_NONE;
+               _connectionState = NET_CONNECTION_STATE_STOPPED;
+               _pConnectionInfo->Clear();
+               _refCount = 0;
+       }
+
+       pEnum = _pEventList->GetEnumeratorN();
+       if (pEnum != null)
+       {
+               while (pEnum->MoveNext() == E_SUCCESS)
+               {
+                       pEvent = dynamic_cast<_NetConnectionEvent*>(pEnum->GetCurrent());
+                       if (pEvent != null)
+                       {
+                               if (pEvent->GetConnectionState() == NET_CONNECTION_STATE_STARTING)
+                               {
+                                       if (error == E_SUCCESS)
+                                       {
+                                               pEvent->SetConnectionState(NET_CONNECTION_STATE_STARTED);
+                                       }
+                                       else
+                                       {
+                                               pEvent->SetConnectionState(NET_CONNECTION_STATE_STOPPED);
+                                       }
+
+                                       pStartEventArg = new (std::nothrow) _NetConnectionEventArg(_NET_CONNECTION_EVENT_TYPE_STARTED, error);
+                                       if (pStartEventArg != null)
+                                       {
+                                               pEvent->FireAsync(*pStartEventArg);
+                                       }
+                               }
+                       }
+               }
+
+               delete pEnum;
+       }
+
+       locked.Unlock();
+
+       SysLog(NID_NET, "Exit.");
+}
+
+void
+_WifiSystemNetConnection::OnApplicationLaunched(const AppId& appId, int pid)
+{
+       SysLog(NID_NET, "App is launched. appid[%ls] pid[%d].", appId.GetPointer(), pid);
+}
+
+void
+_WifiSystemNetConnection::OnApplicationTerminated(const AppId& appId, int pid)
+{
+       SysLog(NID_NET, "App is terminated. appid[%ls] pid[%d].", appId.GetPointer(), pid);
+
+       if (appId.Equals(String(_WIFI_QS_APP_ID), false))
+       {
+               SysLog(NID_NET, "Wi-Fi QuickStart is terminated before Wi-Fi is connected.");
+               __pTimer->Start(1);
+
+               // ToDo - Remove timer and call HandleStartResponse here (After lockup issue is resolved.)
+//             HandleStartResponse(E_NETWORK_FAILED, null);
+       }
+}
+
+void
+_WifiSystemNetConnection::OnTimerExpired(Timer& timer)
+{
+       SysLog(NID_NET, "Timer is expired, so treat as an error.");
+
+       HandleStartResponse(E_NETWORK_FAILED, null);
+}
+
 void
 _WifiSystemNetConnection::UpdateConnectionInfo(void* pData)
 {
index 7c9e662..ea06896 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef _FNET_INTERNAL_WIFI_SYSTEM_NET_CONNECTION_H_
 #define _FNET_INTERNAL_WIFI_SYSTEM_NET_CONNECTION_H_
 
+#include <FBase.h>
+#include <FApp_IAppEventListener.h>
 #include "FNet_SystemNetConnection.h"
 #include "FNet_NetUtility.h"
 
@@ -39,6 +41,8 @@ namespace Tizen { namespace Net {
 
 class _WifiSystemNetConnection
        : public _SystemNetConnection
+       , public Tizen::App::_IAppEventListener
+       , virtual public Tizen::Base::Runtime::ITimerEventListener
 {
 public:
        /**
@@ -64,6 +68,26 @@ public:
         */
        result Construct(void);
 
+       /**
+        * Starts the network connection.
+        *
+        * @since                       3.0
+        *
+        * @return                      An error code
+        * @exception   E_SUCCESS                               The method was successful.
+        * @exception   E_INVALID_STATE         This instance is in an invalid state.
+        * @exception   E_SYSTEM                                        An internal error occurred.
+        * @see                 Stop()
+        */
+       virtual result Start(_NetConnectionEvent& event);
+
+       virtual void HandleStartResponse(result error, void* pData);
+
+       virtual void OnApplicationLaunched(const Tizen::App::AppId& appId, int pid);
+       virtual void OnApplicationTerminated(const Tizen::App::AppId& appId, int pid);
+
+       virtual void OnTimerExpired(Tizen::Base::Runtime::Timer& timer);
+
        void UpdateConnectionInfo(void* pData);
 
        void* GetConnectionHandle(void) const;
@@ -85,6 +109,7 @@ private:
 
 private:
        std::unique_ptr<void, _ConnectionDeleter> __pConnectionHandle;
+       std::unique_ptr<Tizen::Base::Runtime::Timer> __pTimer;
 
 }; // _WifiSystemNetConnection
 
index bd219b9..8d887e0 100644 (file)
@@ -67,7 +67,7 @@ _WifiSystemAdapter::Construct(void)
     int err = WIFI_ERROR_NONE;
 
     err = wifi_initialize();
-    SysTryReturnResult(NID_NET_WIFI, err == WIFI_ERROR_NONE, E_SYSTEM, "Failed to wifi_initialize()");
+    SysTryReturnResult(NID_NET_WIFI, ((err == WIFI_ERROR_NONE) || (err == WIFI_ERROR_INVALID_OPERATION)), E_SYSTEM, "Failed to wifi_initialize()");
 
     err = wifi_set_device_state_changed_cb(OnWifiDeviceStateChanged, null);
     SysTryReturnResult(NID_NET_WIFI, err == WIFI_ERROR_NONE, E_SYSTEM, "Failed to wifi_set_device_state_changed_cb()");