From: Jaemin Ahn Date: Wed, 27 Mar 2013 01:09:07 +0000 (+0900) Subject: Activate Wi-Fi when the application calls NetConnection.Start() on Wi-Fi bearer. X-Git-Tag: accepted/tizen_2.1/20130425.034729~40 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=86539467c7762ccf833f97888225ba8405b3c5e3;p=framework%2Fosp%2Fnet.git Activate Wi-Fi when the application calls NetConnection.Start() on Wi-Fi bearer. Change-Id: I67e3f6ad59ef45bf94678f35d086c708b817624f Signed-off-by: Jaemin Ahn --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt old mode 100755 new mode 100644 index 4a208c8..ed85888 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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" ) diff --git a/src/FNet_NetConnectionEvent.cpp b/src/FNet_NetConnectionEvent.cpp index b8fdd12..4f7f5d8 100644 --- a/src/FNet_NetConnectionEvent.cpp +++ b/src/FNet_NetConnectionEvent.cpp @@ -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 diff --git a/src/FNet_NetConnectionEvent.h b/src/FNet_NetConnectionEvent.h index be6a26c..d57a365 100644 --- a/src/FNet_NetConnectionEvent.h +++ b/src/FNet_NetConnectionEvent.h @@ -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 diff --git a/src/FNet_NetConnectionImpl.cpp b/src/FNet_NetConnectionImpl.cpp index 469cae2..f1ebfc3 100644 --- a/src/FNet_NetConnectionImpl.cpp +++ b/src/FNet_NetConnectionImpl.cpp @@ -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; diff --git a/src/FNet_WifiSystemNetConnection.cpp b/src/FNet_WifiSystemNetConnection.cpp index f721d8c..f7bde44 100644 --- a/src/FNet_WifiSystemNetConnection.cpp +++ b/src/FNet_WifiSystemNetConnection.cpp @@ -23,10 +23,13 @@ */ #include +#include #include #include #include +#include #include +#include #include "FNet_NetTypes.h" #include "FNet_NetConnectionInfoImpl.h" #include "FNet_WifiSystemNetConnection.h" @@ -36,12 +39,16 @@ #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 pConnectionHandle; + unique_ptr 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) { diff --git a/src/FNet_WifiSystemNetConnection.h b/src/FNet_WifiSystemNetConnection.h index 7c9e662..ea06896 100644 --- a/src/FNet_WifiSystemNetConnection.h +++ b/src/FNet_WifiSystemNetConnection.h @@ -24,6 +24,8 @@ #ifndef _FNET_INTERNAL_WIFI_SYSTEM_NET_CONNECTION_H_ #define _FNET_INTERNAL_WIFI_SYSTEM_NET_CONNECTION_H_ +#include +#include #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 __pConnectionHandle; + std::unique_ptr __pTimer; }; // _WifiSystemNetConnection diff --git a/src/wifi/FNetWifi_WifiSystemAdapter.cpp b/src/wifi/FNetWifi_WifiSystemAdapter.cpp index bd219b9..8d887e0 100644 --- a/src/wifi/FNetWifi_WifiSystemAdapter.cpp +++ b/src/wifi/FNetWifi_WifiSystemAdapter.cpp @@ -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()");