Merge from 2.2
[platform/framework/native/telephony.git] / src / FTel_TelephonyIpcProxy.cpp
index ebddb2e..9e68c73 100755 (executable)
 #include <pthread.h>
 #include <unique_ptr.h>
 #include <FBaseSysLog.h>
+#include <FBaseRtMutexGuard.h>
+#include <FBaseColArrayList.h>
+#include <FTelNetworkStatus.h>
 #include <FIo_IpcClient.h>
 #include <FTel_ConnectivityIpcMessages.h>
 #include "FTel_TelephonyIpcProxy.h"
 #include "FTel_CallManagerImpl.h"
+#include "FTel_NetworkManagerEvent.h"
+#include "FTel_NetworkManagerEventArg.h"
 #include "FTel_NetworkManagerImpl.h"
+#include "FTel_NetworkStatusImpl.h"
 
+using namespace std;
 using namespace Tizen::Base;
+using namespace Tizen::Base::Runtime;
+using namespace Tizen::Base::Collection;
 using namespace Tizen::Io;
 
 namespace Tizen { namespace Telephony
@@ -40,7 +49,10 @@ namespace Tizen { namespace Telephony
 _TelephonyIpcProxy* _TelephonyIpcProxy::__pInstance = null;
 
 _TelephonyIpcProxy::_TelephonyIpcProxy(void)
-       : __pIpcClient(null)
+    : __pIpcClient(null)
+       , __pLock(null)
+       , __pNetworkEventList(null)
+       , __networkEventCount(0)
     , __pNetworkManagerImplForGet(null)
        , __pNetworkManagerImplForSelect(null)
        , __pNetworkManagerImplForSearch(null)
@@ -52,7 +64,17 @@ _TelephonyIpcProxy::_TelephonyIpcProxy(void)
 
 _TelephonyIpcProxy::~_TelephonyIpcProxy(void)
 {
-       delete __pIpcClient;
+       if ((__networkEventCount > 0) &&(__pIpcClient != null))
+    {
+           result r = E_SUCCESS;
+           unsigned long ret = 0;
+
+           std::unique_ptr<IPC::Message> pMessage( new (std::nothrow) ConnectivityTelephonyServiceMsg_removeNetworkStatusEventListener(&ret));
+           SysTryReturnVoidResult(NID_TEL, pMessage != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
+
+           r = __pIpcClient->SendRequest(*pMessage);
+           SysLog(NID_TEL, "RemoveNetworkStatusEventListener[%s][%s]", GetErrorMessage(r), GetErrorMessage(ret));
+    }
 }
 
 result
@@ -60,18 +82,28 @@ _TelephonyIpcProxy::Construct(void)
 {
        result r = E_SUCCESS;
 
-       __pIpcClient = new (std::nothrow) _IpcClient();
-       SysTryReturnResult(NID_TEL, __pIpcClient != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+    unique_ptr<ArrayList> pNetworkEventList(new (std::nothrow) ArrayList());
+    SysTryReturnResult(NID_TEL, pNetworkEventList != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
 
-       r = __pIpcClient->Construct(TELEPHONY_CONNECTIVITY_IPC_SERVER_NAME, this);
-       SysTryReturnResult(NID_TEL, r != E_OUT_OF_MEMORY, r, "Propagating.");
+    r = pNetworkEventList->Construct();
+    SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
 
-       if (r != E_SUCCESS)
-       {
-               SysLogException(NID_TEL, r, "[%s] Propagating", GetErrorMessage(r));
-               delete __pIpcClient;
-               __pIpcClient = null;
-       }
+    unique_ptr<Mutex> pLock(new (std::nothrow) Mutex());
+    SysTryReturnResult(NID_TEL, pLock != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+    r = pLock->Create();
+    SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
+
+    unique_ptr<_IpcClient> pIpcClient(new (std::nothrow) _IpcClient());
+       SysTryReturnResult(NID_TEL, pIpcClient != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
+
+       r = pIpcClient->Construct(TELEPHONY_CONNECTIVITY_IPC_SERVER_NAME, this);
+    SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
+
+    __pIpcClient = move(pIpcClient);
+    __pLock = move(pLock);
+    __pNetworkEventList = move(pNetworkEventList);
+    __networkEventCount = 0;
 
        return r;
 }
@@ -98,13 +130,17 @@ _TelephonyIpcProxy::GetInstance(void)
 void
 _TelephonyIpcProxy::InitSingleton(void)
 {
-       result r = E_SUCCESS;
-       static _TelephonyIpcProxy instance;
+    result r = E_SUCCESS;
 
-       r = instance.Construct();
-       SysTryReturnVoidResult(NID_TEL, r == E_SUCCESS, r, "[%s] Propagating", GetErrorMessage(r));
+    unique_ptr<_TelephonyIpcProxy> pInstance(new (std::nothrow) _TelephonyIpcProxy());
+       SysTryReturnVoidResult(NID_TEL, pInstance != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
 
-       __pInstance = &instance;
+       r = pInstance->Construct();
+       SysTryReturnVoidResult(NID_TEL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
+
+       ClearLastResult();
+
+       __pInstance = pInstance.release();
 }
 
 result
@@ -286,6 +322,61 @@ _TelephonyIpcProxy::GetCallForwardNumber(_CallManagerImpl* pCallManagerImpl)
     return E_SUCCESS;
 }
 
+result
+_TelephonyIpcProxy::AddNetworkEvent(_NetworkManagerEvent* pEvent)
+{
+       result r = E_SUCCESS;
+
+    SysTryReturnResult(NID_TEL, pEvent != null, E_INVALID_ARG, "Event is null.");
+
+    MutexGuard locked(*__pLock);
+
+       r = __pNetworkEventList->Add(*pEvent);
+    SysTryReturnResult(NID_TEL, r == E_SUCCESS, r, "Propagating.");
+
+       if (__networkEventCount == 0)
+       {
+               SysLog(NID_TEL, "Set network event callback.");
+
+           unsigned long ret = 0;
+
+           std::unique_ptr<IPC::Message> pMessage( new (std::nothrow) ConnectivityTelephonyServiceMsg_addNetworkStatusEventListener(&ret));
+           r = __pIpcClient->SendRequest(*pMessage);
+           SysTryReturnResult(NID_TEL, r == E_SUCCESS, E_SYSTEM, "A system error has been occurred. Failed to send a request.");
+           SysTryReturnResult(NID_TEL, ret == E_SUCCESS, ret, "Propagating.");
+       }
+
+    __networkEventCount++;
+
+       return r;
+}
+
+void
+_TelephonyIpcProxy::RemoveNetworkEvent(_NetworkManagerEvent* pEvent)
+{
+       SysTryReturnVoidResult(NID_TEL, pEvent != null, E_INVALID_ARG, "[E_INVALID_ARG] Event is null.");
+
+       MutexGuard locked(*__pLock);
+
+       __pNetworkEventList->Remove(*pEvent);
+
+    __networkEventCount--;
+
+       if (__networkEventCount == 0)
+       {
+               SysLog(NID_TEL, "Unset network event callback.");
+
+               result r = E_SUCCESS;
+           unsigned long ret = 0;
+
+           std::unique_ptr<IPC::Message> pMessage( new (std::nothrow) ConnectivityTelephonyServiceMsg_removeNetworkStatusEventListener(&ret));
+           SysTryReturnVoidResult(NID_TEL, pMessage != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
+
+           r = __pIpcClient->SendRequest(*pMessage);
+           SysLog(NID_TEL, "RemoveNetworkStatusEventListener[%s][%s]", GetErrorMessage(r), GetErrorMessage(ret));
+       }
+}
+
 void
 _TelephonyIpcProxy::OnIpcResponseReceived(Tizen::Io::_IpcClient& client, const IPC::Message& message)
 {
@@ -298,6 +389,7 @@ _TelephonyIpcProxy::OnIpcResponseReceived(Tizen::Io::_IpcClient& client, const I
     IPC_MESSAGE_HANDLER(ConnectivityTelephonyServiceMsg_onCallForwardNumberReceived, OnTelephonyCallForwardNumberReceived, &client);
     IPC_MESSAGE_HANDLER(ConnectivityTelephonyServiceMsg_onCallForwardResponseReceived, OnTelephonyCallForwardResponseReceived, &client);
     IPC_MESSAGE_HANDLER(ConnectivityTelephonyServiceMsg_onCallForwardStopped, OnTelephonyCallForwardStopped, &client);
+    IPC_MESSAGE_HANDLER(ConnectivityTelephonyServiceMsg_onNetworkStatusChanged, OnNetworkStatusChanged, &client);
     IPC_END_MESSAGE_MAP()
 }
 
@@ -361,4 +453,35 @@ _TelephonyIpcProxy::OnTelephonyCallForwardStopped(Tizen::Base::String phoneNumbe
     __pCallManagerImplForStop->OnTelephonyCallForwardStopped(phoneNumber, res);
 }
 
+void
+_TelephonyIpcProxy::OnNetworkStatusChanged(bool isCallServiceAvailable, bool isDataServiceAvailable, bool isRoaming)
+{
+    SysLog(NID_TEL, "Network status is changed. [%d][%d][%d]", isCallServiceAvailable, isDataServiceAvailable, isRoaming);
+
+    NetworkStatus networkStatus;
+       _NetworkManagerEvent* pEvent = null;
+       _NetworkManagerEventArg* pEventArg = null;
+
+       _NetworkStatusImpl::GetInstance(networkStatus)->SetIsCallServiceAvailable(isCallServiceAvailable);
+       _NetworkStatusImpl::GetInstance(networkStatus)->SetIsDataServiceAvailable(isDataServiceAvailable);
+       _NetworkStatusImpl::GetInstance(networkStatus)->SetIsRoaming(isRoaming);
+
+       unique_ptr<IEnumerator> pEnum(__pNetworkEventList->GetEnumeratorN());
+       if (pEnum != null)
+       {
+               while (pEnum->MoveNext() == E_SUCCESS)
+               {
+                       pEvent = dynamic_cast<_NetworkManagerEvent*>(pEnum->GetCurrent());
+                       if (pEvent != null)
+                       {
+                               pEventArg = new (std::nothrow)_NetworkManagerEventArg(networkStatus);
+                               if (pEventArg != null)
+                               {
+                                       pEvent->FireAsync(*pEventArg);
+                               }
+                       }
+               }
+       }
+}
+
 }} // Tizen::Telephony