// // Open Service Platform // Copyright (c) 2012 Samsung Electronics Co., Ltd. // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /** * @file FScl_AccountDbMonitor.cpp * @brief This is the implementation for _AccountDbMonitor class. * * This file contains definitions of @e _AccountDbMonitor class. */ #include #include #include #include #include "FScl_IAccountDbChangeEventListener.h" #include "FScl_AccountDbChangeEvent.h" #include "FScl_AccountDbChangeEventArg.h" #include "FScl_AccountDbConnector.h" #include "FScl_AccountDbMonitor.h" using namespace Tizen::Base; using namespace Tizen::Base::Runtime; namespace Tizen { namespace Social { _AccountDbMonitor* _AccountDbMonitor::__pTheInstance = null; _AccountDbMonitor::__Callback::__Callback(account_subscribe_h accountSubscribeHandle, account_event_cb callback, void* pUserData) : __accountSubscribeHandle(accountSubscribeHandle) , __callback(callback) , __pUserData(pUserData) { // empty body } result _AccountDbMonitor::__Callback::Register(void) { int ret = account_subscribe_notification(__accountSubscribeHandle, __callback, __pUserData); SysTryReturnResult(NID_SCL, ret == ACCOUNT_ERROR_NONE, E_SYSTEM, "The method cannot proceed due to a severe system error."); return E_SUCCESS; } _AccountDbMonitor::__Callback::~__Callback(void) { if (__accountSubscribeHandle) { account_unsubscribe_notification(__accountSubscribeHandle); } } _AccountDbMonitor::_AccountDbMonitor(void) : __pEvent(null) , __pMutex(null) , __pAccountChangeCallback(null) { // empty body } _AccountDbMonitor::~_AccountDbMonitor(void) { // empty body } result _AccountDbMonitor::Construct(void) { SysTryReturn(NID_SCL, _AccountDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult())); std::unique_ptr pMutex(new (std::nothrow) Mutex()); SysTryReturn(NID_SCL, pMutex != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pMutex->Create(); SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r)); std::unique_ptr<_AccountDbChangeEvent> pEvent(new (std::nothrow) _AccountDbChangeEvent()); SysTryReturnResult(NID_SCL, pEvent != null, E_OUT_OF_MEMORY, "Memory allocation failed."); r = pEvent->Construct(); SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r)); account_subscribe_h accountSubscribeHandle = null; int ret = account_subscribe_create(&accountSubscribeHandle); SysTryReturnResult(NID_SCL, ret == ACCOUNT_ERROR_NONE, E_OUT_OF_MEMORY, "Memory allocation failed."); std::unique_ptr<__Callback> pAccountChangeCallback(new (std::nothrow) __Callback(accountSubscribeHandle, OnAccountChangeEventReceived, this)); SysTryCatch(NID_SCL, pAccountChangeCallback != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); r = pAccountChangeCallback->Register(); SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r)); __pMutex = move(pMutex); __pEvent = move(pEvent); __pAccountChangeCallback = move(pAccountChangeCallback); return E_SUCCESS; CATCH: account_unsubscribe_notification(accountSubscribeHandle); return r; } result _AccountDbMonitor::AddListener(const _IAccountDbChangeEventListener& listener) { result r = __pMutex->Acquire(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); r = __pEvent->AddListener(listener); SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); r = __pMutex->Release(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); return E_SUCCESS; CATCH: r = __pMutex->Release(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); return r; } result _AccountDbMonitor::RemoveListener(const _IAccountDbChangeEventListener& listener) { result r = __pMutex->Acquire(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); r = __pEvent->RemoveListener(listener); SysTryCatch(NID_SCL, !IsFailed(r), , r, "[%s] Propagating.", GetErrorMessage(r)); r = __pMutex->Release(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); return E_SUCCESS; CATCH: r = __pMutex->Release(); SysTryReturn(NID_SCL, !IsFailed(r), E_SYSTEM, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); return r; } _AccountDbMonitor* _AccountDbMonitor::GetInstance(void) { static pthread_once_t onceBlock = PTHREAD_ONCE_INIT; if (__pTheInstance == null) { ClearLastResult(); pthread_once(&onceBlock, InitSingleton); result r = GetLastResult(); if (IsFailed(r)) { onceBlock = PTHREAD_ONCE_INIT; } } return __pTheInstance; } bool _AccountDbMonitor::OnAccountChangeEventReceived(const char* pEventType, int accountId, void* pUserData) { SysTryReturn(NID_SCL, pEventType != null, false, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); std::unique_ptr pAccountChangeEventType(new (std::nothrow) String(pEventType)); SysTryReturn(NID_SCL, pAccountChangeEventType != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); _AccountDbMonitor* pAccountDbMonitor = static_cast<_AccountDbMonitor*>(pUserData); _AccountDbChangeEvent* pEvent = pAccountDbMonitor->__pEvent.get(); std::unique_ptr<_AccountDbChangeEventArg> pArg(null); if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_INSERT))) { pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_ADD)); SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); } else if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_UPDATE))) { pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_UPDATE)); SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); } else if (pAccountChangeEventType->Equals(String(ACCOUNT_NOTI_NAME_DELETE))) { pArg.reset(new (std::nothrow) _AccountDbChangeEventArg(accountId, _ACCOUNT_DB_CHANGE_TYPE_REMOVE)); SysTryReturn(NID_SCL, pArg != null, false, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); } else { SysLogException(NID_SCL, E_SYSTEM, "[%s] The method cannot proceed due to a severe system error.", GetErrorMessage(E_SYSTEM)); return false; } result r = pEvent->Fire(*pArg); SysTryReturn(NID_SCL, !IsFailed(r), false, r, "[%s] Propagating.", GetErrorMessage(r)); pArg.release(); return true; } void _AccountDbMonitor::InitSingleton(void) { std::unique_ptr<_AccountDbMonitor> pInst(new (std::nothrow) _AccountDbMonitor()); SysTryReturnVoidResult(NID_SCL, pInst, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY)); result r = pInst->Construct(); SysTryReturnVoidResult(NID_SCL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r)); __pTheInstance = pInst.release(); std::atexit(DestroySingleton); } void _AccountDbMonitor::DestroySingleton(void) { delete __pTheInstance; } }} // Tizen::Social