2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FScl_ContactDbMonitor.cpp
19 * @brief This is the implementation for _ContactDbMonitor class.
21 * This file contains definitions of @e _ContactDbMonitor class.
26 #include <FBaseRtMutex.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseColArrayListT.h>
29 #include "FScl_IContactDbChangeEventListener.h"
30 #include "FScl_ContactDbChangeEvent.h"
31 #include "FScl_ContactDbChangeEventArg.h"
32 #include "FScl_ContactDbConnector.h"
33 #include "FScl_ContactDbMonitor.h"
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Runtime;
38 namespace Tizen { namespace Social
41 _ContactDbMonitor* _ContactDbMonitor::__pTheInstance = null;
43 _ContactDbMonitor::__Callback::__Callback(const char* uri, contacts_db_changed_cb callback, void* pData)
45 , __callback(callback)
47 , __registerred(false)
53 _ContactDbMonitor::__Callback::Register(void)
55 int ret = contacts_db_add_changed_cb(__uri, __callback, __pData);
56 SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
63 _ContactDbMonitor::__Callback::~__Callback(void)
67 contacts_db_remove_changed_cb(__uri, __callback, __pData);
76 _ContactDbMonitor::_ContactDbMonitor(void)
79 , __pContactChangeCallback(null)
80 , __pGroupChangeCallback(null)
81 , __pGroupRelationChagneCallback(null)
82 , __pAddressbookChagneCallback(null)
83 , __pAddressbookList(null)
88 _ContactDbMonitor::~_ContactDbMonitor(void)
90 if (__pAddressbookList != null)
92 contacts_list_destroy(__pAddressbookList, true);
97 _ContactDbMonitor::Construct(void)
99 SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
101 result r = E_SUCCESS;
103 std::unique_ptr<Mutex> pMutex(new (std::nothrow) Mutex());
104 SysTryReturn(NID_SCL, pMutex != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
106 r = pMutex->Create();
107 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
109 std::unique_ptr<_ContactDbChangeEvent> pEvent(new (std::nothrow) _ContactDbChangeEvent());
110 SysTryReturnResult(NID_SCL, pEvent != null, E_OUT_OF_MEMORY, "Not enough memory.");
112 r = pEvent->Construct();
113 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
115 std::unique_ptr<__Callback> pContactChangeCallback(new (std::nothrow) __Callback(_contacts_contact._uri, OnContactDbChanged, this));
116 SysTryReturn(NID_SCL, pContactChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
118 r = pContactChangeCallback->Register();
119 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
121 std::unique_ptr<__Callback> pGroupChangeCallback(new (std::nothrow) __Callback(_contacts_group._uri, OnContactDbChanged, this));
122 SysTryReturn(NID_SCL, pGroupChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
124 r = pGroupChangeCallback->Register();
125 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
127 std::unique_ptr<__Callback> pGroupRelationChangeCallback(new (std::nothrow) __Callback(_contacts_group_relation._uri, OnContactDbChanged, this));
128 SysTryReturn(NID_SCL, pGroupRelationChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
130 r = pGroupRelationChangeCallback->Register();
131 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
133 std::unique_ptr<__Callback> pAddressbookChangeCallback(new (std::nothrow) __Callback(_contacts_address_book._uri, OnContactDbChanged, this));
134 SysTryReturn(NID_SCL, pAddressbookChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
136 r = pAddressbookChangeCallback->Register();
137 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
139 __pMutex = move(pMutex);
140 __pEvent = move(pEvent);
141 __pContactChangeCallback = move(pContactChangeCallback);
142 __pGroupChangeCallback = move(pGroupChangeCallback);
143 __pGroupRelationChagneCallback = move(pGroupRelationChangeCallback);
144 __pAddressbookChagneCallback = move(pAddressbookChangeCallback);
150 _ContactDbMonitor::AddListener(const _IContactDbChangeEventListener& listener)
152 result r = __pMutex->Acquire();
153 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
155 r = __pEvent->AddListener(listener);
156 SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
158 r = __pMutex->Release();
159 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
164 r = __pMutex->Release();
165 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
171 _ContactDbMonitor::RemoveListener(const _IContactDbChangeEventListener& listener)
173 result r = __pMutex->Acquire();
174 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
176 r = __pEvent->RemoveListener(listener);
177 SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
179 r = __pMutex->Release();
180 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
185 r = __pMutex->Release();
186 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
192 _ContactDbMonitor::GetInstance(void)
194 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
195 if (__pTheInstance == null)
199 pthread_once(&onceBlock, InitSingleton);
201 result r = GetLastResult();
204 onceBlock = PTHREAD_ONCE_INIT;
208 return __pTheInstance;
212 _ContactDbMonitor::OnContactDbChanged(const char* viewUri, void* pUserData)
214 result r = E_SUCCESS;
216 _ContactDbMonitor* pContactDbMonitor = static_cast<_ContactDbMonitor*>(pUserData);
217 _ContactDbChangeEvent* pEvent = pContactDbMonitor->__pEvent.get();
219 std::unique_ptr<_ContactDbChangeEventArg> pArg;
221 if (strcmp(viewUri, _contacts_contact._uri) == 0)
223 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_CONTACT));
224 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
226 else if (strcmp(viewUri, _contacts_group._uri) == 0)
228 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_GROUP));
229 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
232 else if (strcmp(viewUri, _contacts_group_relation._uri) == 0)
234 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_RELATION));
235 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
238 else if (strcmp(viewUri, _contacts_address_book._uri) == 0)
240 pContactDbMonitor->UpdateAddressbookList();
242 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_ADDRESSBOOK));
243 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
250 r = pEvent->Fire(*pArg);
251 SysTryReturnVoidResult(NID_SCL, !IsFailed(r), r, "[%s] Propagating.", GetErrorMessage(r));
257 _ContactDbMonitor::UpdateAddressbookList(void)
259 SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
263 contacts_list_h pAddressbookList = null;
264 int ret = contacts_db_get_all_records(_contacts_address_book._uri, 0, 0, &pAddressbookList);
265 SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
266 SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
268 __List list(pAddressbookList);
270 __Lock lock(__pMutex.get());
271 result r = GetLastResult();
272 SysTryReturn(NID_SCL, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
274 if (__pAddressbookList != null)
276 contacts_list_destroy(__pAddressbookList, true);
279 __pAddressbookList = list.Release();
285 _ContactDbMonitor::GetAccountIdByAddressbookId(int addressbookId)
289 __Lock lock(__pMutex.get());
291 if (__pAddressbookList == null)
293 result r = UpdateAddressbookList();
294 SysTryReturn(NID_SCL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
298 unsigned int count = 0;
299 contacts_record_h pAddressbook = null;
301 contacts_list_get_count(__pAddressbookList, &count);
302 contacts_list_first(__pAddressbookList);
304 for (unsigned int i = 0; i < count; i++)
306 contacts_list_get_current_record_p(__pAddressbookList, &pAddressbook);
307 contacts_record_get_int(pAddressbook, _contacts_address_book.id, &intValue);
308 if (intValue == addressbookId)
310 contacts_record_get_int(pAddressbook, _contacts_address_book.account_id, &intValue);
315 if (contacts_list_next(__pAddressbookList) != CONTACTS_ERROR_NONE)
325 _ContactDbMonitor::InitSingleton(void)
327 std::unique_ptr<_ContactDbMonitor> pInst(new (std::nothrow) _ContactDbMonitor());
328 SysTryReturnVoidResult(NID_SCL, pInst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
330 result r = pInst->Construct();
331 SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
333 __pTheInstance = pInst.release();
335 std::atexit(DestroySingleton);
339 _ContactDbMonitor::DestroySingleton(void)
341 delete __pTheInstance;