Merge "Fixed exception handling codes" into tizen_2.1
[framework/osp/social.git] / src / FScl_AccountDbMonitor.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FScl_AccountDbMonitor.cpp
19  * @brief               This is the implementation for _AccountDbMonitor class.
20  *
21  * This file contains definitions of @e _AccountDbMonitor class.
22  */
23
24 #include <new>
25 #include <FBaseRtMutex.h>
26 #include <FBaseSysLog.h>
27 #include <FBaseColArrayListT.h>
28 #include "FScl_IAccountDbChangeEventListener.h"
29 #include "FScl_AccountDbChangeEvent.h"
30 #include "FScl_AccountDbChangeEventArg.h"
31 #include "FScl_AccountDbConnector.h"
32 #include "FScl_AccountDbMonitor.h"
33
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Runtime;
36
37 namespace Tizen { namespace Social
38 {
39
40 _AccountDbMonitor* _AccountDbMonitor::__pTheInstance = null;
41
42 _AccountDbMonitor::__Callback::__Callback(account_subscribe_h accountSubscribeHandle, account_event_cb callback, void* pUserData)
43         : __accountSubscribeHandle(accountSubscribeHandle)
44         , __callback(callback)
45         , __pUserData(pUserData)
46 {
47         // empty body
48 }
49
50 result
51 _AccountDbMonitor::__Callback::Register(void)
52 {
53         int ret = account_subscribe_notification(__accountSubscribeHandle, __callback, __pUserData);
54         SysTryReturnResult(NID_SCL, ret == ACCOUNT_ERROR_NONE, E_SYSTEM, "The method cannot proceed due to a severe system error.");
55
56         return E_SUCCESS;
57 }
58
59 _AccountDbMonitor::__Callback::~__Callback(void)
60 {
61         if (__accountSubscribeHandle)
62         {
63                 account_unsubscribe_notification(__accountSubscribeHandle);
64         }
65 }
66
67 _AccountDbMonitor::_AccountDbMonitor(void)
68         : __pEvent(null)
69         , __pMutex(null)
70         , __pAccountChangeCallback(null)
71 {
72         // empty body
73 }
74
75 _AccountDbMonitor::~_AccountDbMonitor(void)
76 {
77         // empty body
78 }
79
80 result
81 _AccountDbMonitor::Construct(void)
82 {
83         SysTryReturn(NID_SCL, _AccountDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
84
85         std::unique_ptr<Mutex> pMutex(new (std::nothrow) Mutex());
86         SysTryReturn(NID_SCL, pMutex != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
87
88         result r = pMutex->Create();
89         SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
90
91         std::unique_ptr<_AccountDbChangeEvent> pEvent(new (std::nothrow) _AccountDbChangeEvent());
92         SysTryReturnResult(NID_SCL, pEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
93
94         r = pEvent->Construct();
95         SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
96
97         account_subscribe_h accountSubscribeHandle = null;
98         int ret = account_subscribe_create(&accountSubscribeHandle);
99         SysTryReturnResult(NID_SCL, ret == ACCOUNT_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed.");
100
101         std::unique_ptr<__Callback> pAccountChangeCallback(new (std::nothrow) __Callback(accountSubscribeHandle, OnAccountChangeEventReceived, this));
102         SysTryCatch(NID_SCL, pAccountChangeCallback != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
103
104         r = pAccountChangeCallback->Register();
105         SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
106
107         __pMutex = move(pMutex);
108         __pEvent = move(pEvent);
109         __pAccountChangeCallback = move(pAccountChangeCallback);
110
111         return E_SUCCESS;
112
113 CATCH:
114         account_unsubscribe_notification(accountSubscribeHandle);
115
116         return r;
117 }
118
119 result
120 _AccountDbMonitor::AddListener(const _IAccountDbChangeEventListener& listener)
121 {
122         result r = __pMutex->Acquire();
123         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
124
125         r = __pEvent->AddListener(listener);
126         SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
127
128         r = __pMutex->Release();
129         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
130
131         return E_SUCCESS;
132
133 CATCH:
134         r = __pMutex->Release();
135         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
136
137         return r;
138 }
139
140 result
141 _AccountDbMonitor::RemoveListener(const _IAccountDbChangeEventListener& listener)
142 {
143         result r = __pMutex->Acquire();
144         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
145
146         r = __pEvent->RemoveListener(listener);
147         SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
148
149         r = __pMutex->Release();
150         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
151
152         return E_SUCCESS;
153
154 CATCH:
155         r = __pMutex->Release();
156         SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
157
158         return r;
159 }
160
161 _AccountDbMonitor*
162 _AccountDbMonitor::GetInstance(void)
163 {
164         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
165         if (__pTheInstance == null)
166         {
167                 ClearLastResult();
168
169                 pthread_once(&onceBlock, InitSingleton);
170
171                 result r = GetLastResult();
172                 if (IsFailed(r))
173                 {
174                         onceBlock = PTHREAD_ONCE_INIT;
175                 }
176         }
177
178         return __pTheInstance;
179 }
180
181 bool
182 _AccountDbMonitor::OnAccountChangeEventReceived(const char* pEventType, int accountId, void* pUserData)
183 {
184         SysTryReturn(NID_SCL, pEventType != null, false, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
185
186         std::unique_ptr<String> pAccountChangeEventType(new (std::nothrow) String(pEventType));
187         SysTryReturn(NID_SCL, pAccountChangeEventType != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
188
189         _AccountDbMonitor* pAccountDbMonitor = static_cast<_AccountDbMonitor*>(pUserData);
190         _AccountDbChangeEvent* pEvent = pAccountDbMonitor->__pEvent.get();
191
192         std::unique_ptr<_AccountDbChangeEventArg> pArg(null);
193
194         if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_INSERT)))
195         {
196                 pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_ADD));
197                 SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
198         }
199         else if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_UPDATE)))
200         {
201                 pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_UPDATE));
202                 SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
203         }
204         else if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_DELETE)))
205         {
206                 pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_REMOVE));
207                 SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
208         }
209         else
210         {
211                 SysLogException(NID_SCL, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM));
212                 return false;
213         }
214
215         result r = pEvent->Fire(*pArg);
216         SysTryReturn(NID_SCL, !IsFailed(r), false, r, "[%s] Propagating.", GetErrorMessage(r));
217
218         pArg.release();
219
220         return true;
221 }
222
223 void
224 _AccountDbMonitor::InitSingleton(void)
225 {
226         std::unique_ptr<_AccountDbMonitor> pInst(new (std::nothrow) _AccountDbMonitor());
227         SysTryReturnVoidResult(NID_SCL, pInst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
228
229         result r = pInst->Construct();
230         SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
231
232         __pTheInstance = pInst.release();
233
234         std::atexit(DestroySingleton);
235 }
236
237 void
238 _AccountDbMonitor::DestroySingleton(void)
239 {
240         delete __pTheInstance;
241 }
242
243 }}  // Tizen::Social