2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 * @file FScl_ContactDbMonitor.cpp
18 * @brief This is the implementation for _ContactDbMonitor class.
20 * This file contains definitions of @e _ContactDbMonitor class.
25 #include <FBaseRtMutex.h>
26 #include <FBaseSysLog.h>
27 #include <FBaseColArrayListT.h>
28 #include "FScl_IContactDbChangeEventListener.h"
29 #include "FScl_ContactDbChangeEvent.h"
30 #include "FScl_ContactDbChangeEventArg.h"
31 #include "FScl_ContactDbConnector.h"
32 #include "FScl_ContactDbMonitor.h"
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Runtime;
37 namespace Tizen { namespace Social
40 _ContactDbMonitor* _ContactDbMonitor::__pTheInstance = null;
42 _ContactDbMonitor::__Callback::__Callback(const char* uri, contacts_db_changed_cb callback, void* pData)
44 , __callback(callback)
46 , __registerred(false)
52 _ContactDbMonitor::__Callback::Register(void)
54 int ret = contacts_db_add_changed_cb(__uri, __callback, __pData);
55 SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
62 _ContactDbMonitor::__Callback::~__Callback(void)
66 contacts_db_remove_changed_cb(__uri, __callback, __pData);
75 _ContactDbMonitor::_ContactDbMonitor(void)
78 , __pContactChangeCallback(null)
79 , __pGroupChangeCallback(null)
80 , __pGroupRelationChagneCallback(null)
81 , __pAddressbookChagneCallback(null)
82 , __pAddressbookList(null)
87 _ContactDbMonitor::~_ContactDbMonitor(void)
89 if (__pAddressbookList != null)
91 contacts_list_destroy(__pAddressbookList, true);
96 _ContactDbMonitor::Construct(void)
98 SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
100 result r = E_SUCCESS;
102 std::unique_ptr<Mutex> pMutex(new (std::nothrow) Mutex());
103 SysTryReturn(NID_SCL, pMutex != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
105 r = pMutex->Create();
106 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
108 std::unique_ptr<_ContactDbChangeEvent> pEvent(new (std::nothrow) _ContactDbChangeEvent());
109 SysTryReturnResult(NID_SCL, pEvent != null, E_OUT_OF_MEMORY, "Not enough memory.");
111 r = pEvent->Construct();
112 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
114 std::unique_ptr<__Callback> pContactChangeCallback(new (std::nothrow) __Callback(_contacts_contact._uri, OnContactDbChanged, this));
115 SysTryReturn(NID_SCL, pContactChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
117 r = pContactChangeCallback->Register();
118 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
120 std::unique_ptr<__Callback> pGroupChangeCallback(new (std::nothrow) __Callback(_contacts_group._uri, OnContactDbChanged, this));
121 SysTryReturn(NID_SCL, pGroupChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
123 r = pGroupChangeCallback->Register();
124 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
126 std::unique_ptr<__Callback> pGroupRelationChangeCallback(new (std::nothrow) __Callback(_contacts_group_relation._uri, OnContactDbChanged, this));
127 SysTryReturn(NID_SCL, pGroupRelationChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
129 r = pGroupRelationChangeCallback->Register();
130 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
132 std::unique_ptr<__Callback> pAddressbookChangeCallback(new (std::nothrow) __Callback(_contacts_address_book._uri, OnContactDbChanged, this));
133 SysTryReturn(NID_SCL, pAddressbookChangeCallback != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
135 r = pAddressbookChangeCallback->Register();
136 SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
138 __pMutex = move(pMutex);
139 __pEvent = move(pEvent);
140 __pContactChangeCallback = move(pContactChangeCallback);
141 __pGroupChangeCallback = move(pGroupChangeCallback);
142 __pGroupRelationChagneCallback = move(pGroupRelationChangeCallback);
143 __pAddressbookChagneCallback = move(pAddressbookChangeCallback);
149 _ContactDbMonitor::AddListener(const _IContactDbChangeEventListener& listener)
151 result r = __pMutex->Acquire();
152 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
154 r = __pEvent->AddListener(listener);
155 SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
157 r = __pMutex->Release();
158 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
163 r = __pMutex->Release();
164 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
170 _ContactDbMonitor::RemoveListener(const _IContactDbChangeEventListener& listener)
172 result r = __pMutex->Acquire();
173 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
175 r = __pEvent->RemoveListener(listener);
176 SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r));
178 r = __pMutex->Release();
179 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
184 r = __pMutex->Release();
185 SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
191 _ContactDbMonitor::GetInstance(void)
193 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
194 if (__pTheInstance == null)
198 pthread_once(&onceBlock, InitSingleton);
200 result r = GetLastResult();
203 onceBlock = PTHREAD_ONCE_INIT;
207 return __pTheInstance;
211 _ContactDbMonitor::OnContactDbChanged(const char* viewUri, void* pUserData)
213 result r = E_SUCCESS;
215 _ContactDbMonitor* pContactDbMonitor = static_cast<_ContactDbMonitor*>(pUserData);
216 _ContactDbChangeEvent* pEvent = pContactDbMonitor->__pEvent.get();
218 std::unique_ptr<_ContactDbChangeEventArg> pArg;
220 if (strcmp(viewUri, _contacts_contact._uri) == 0)
222 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_CONTACT));
223 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
225 else if (strcmp(viewUri, _contacts_group._uri) == 0)
227 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_GROUP));
228 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
231 else if (strcmp(viewUri, _contacts_group_relation._uri) == 0)
233 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_RELATION));
234 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
237 else if (strcmp(viewUri, _contacts_address_book._uri) == 0)
239 pContactDbMonitor->UpdateAddressbookList();
241 pArg.reset(new (std::nothrow) _ContactDbChangeEventArg(_CONTACT_DB_CHANGE_TYPE_ADDRESSBOOK));
242 SysTryReturnVoidResult(NID_SCL, pArg != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
249 r = pEvent->Fire(*pArg);
250 SysTryReturnVoidResult(NID_SCL, !IsFailed(r), r, "[%s] Propagating.", GetErrorMessage(r));
256 _ContactDbMonitor::UpdateAddressbookList(void)
258 SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
262 contacts_list_h pAddressbookList = null;
263 int ret = contacts_db_get_all_records(_contacts_address_book._uri, 0, 0, &pAddressbookList);
264 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));
265 SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
267 __List list(pAddressbookList);
269 __Lock lock(__pMutex.get());
270 result r = GetLastResult();
271 SysTryReturn(NID_SCL, r == E_SUCCESS, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
273 if (__pAddressbookList != null)
275 contacts_list_destroy(__pAddressbookList, true);
278 __pAddressbookList = list.Release();
284 _ContactDbMonitor::GetAccountIdByAddressbookId(int addressbookId)
288 __Lock lock(__pMutex.get());
290 if (__pAddressbookList == null)
292 result r = UpdateAddressbookList();
293 SysTryReturn(NID_SCL, r == E_SUCCESS, -1, r, "[%s] Propagating.", GetErrorMessage(r));
297 unsigned int count = 0;
298 contacts_record_h pAddressbook = null;
300 contacts_list_get_count(__pAddressbookList, &count);
301 contacts_list_first(__pAddressbookList);
303 for (unsigned int i = 0; i < count; i++)
305 contacts_list_get_current_record_p(__pAddressbookList, &pAddressbook);
306 contacts_record_get_int(pAddressbook, _contacts_address_book.id, &intValue);
307 if (intValue == addressbookId)
309 contacts_record_get_int(pAddressbook, _contacts_address_book.account_id, &intValue);
314 if (contacts_list_next(__pAddressbookList) != CONTACTS_ERROR_NONE)
324 _ContactDbMonitor::InitSingleton(void)
326 std::unique_ptr<_ContactDbMonitor> pInst(new (std::nothrow) _ContactDbMonitor());
327 SysTryReturnVoidResult(NID_SCL, pInst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
329 result r = pInst->Construct();
330 SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
332 __pTheInstance = pInst.release();
334 std::atexit(DestroySingleton);
338 _ContactDbMonitor::DestroySingleton(void)
340 delete __pTheInstance;