/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "Broadcast.h" #include #include namespace Util { /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ class BroadcastObserver { public: BroadcastObserver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter): _pReceiver(&receiver), _pFilter(pFilter) { } void broadcast(Intent::Ptr pIntent) { if (_pFilter->match(pIntent)) _pReceiver->onReceive(pIntent); } bool equals(const BroadcastObserver& observer) { return _pReceiver == observer._pReceiver; } bool isBoundTo(BroadcastReceiver& receiver) { return _pReceiver == &receiver; } private: BroadcastReceiver* _pReceiver; IntentFilter::Ptr _pFilter; }; class BroadcastCore { public: void sendBroadcast(Intent::Ptr pIntent) { Poco::ScopedLockWithUnlock lock(_mutex); BroadcastObserverList list(_broadcastObservers); lock.unlock(); for (auto& p : list) p->broadcast(pIntent); } void registerReceiver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter) { Poco::Mutex::ScopedLock lock(_mutex); for (auto& obs : _broadcastObservers) { if (obs->isBoundTo(receiver)) return; } _broadcastObservers.push_back(new BroadcastObserver(receiver, pFilter)); } void unregisterReceiver(BroadcastReceiver& receiver) { Poco::Mutex::ScopedLock lock(_mutex); for (BroadcastObserverList::iterator it = _broadcastObservers.begin(); it != _broadcastObservers.end();) { if ((*it)->isBoundTo(receiver)) it = _broadcastObservers.erase(it); else ++it; } } private: using BroadcastObserverPtr = Poco::SharedPtr; using BroadcastObserverList = std::vector; BroadcastObserverList _broadcastObservers; mutable Poco::Mutex _mutex; }; /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ Intent& Intent::putExtra(const std::string& key, const char* value) { return putExtra(key, std::string(value)); } /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ void IntentFilter::addAction(const std::string& action) { _actions.push_back(action); } bool IntentFilter::match(Intent::Ptr pIntent) const { const std::string& target = pIntent->getAction(); return std::find(_actions.begin(), _actions.end(), target) != _actions.end(); } /* ******************************************************************************* * LOCAL VARIABLES ******************************************************************************* */ namespace { static BroadcastCore core; } /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ void BroadcastSender::sendBroadcast(Intent::Ptr pIntent) { core.sendBroadcast(pIntent); } void BroadcastReceiverRegistry::registerReceiver(BroadcastReceiver& receiver, IntentFilter::Ptr pFilter) { core.registerReceiver(receiver, pFilter); } void BroadcastReceiverRegistry::unregisterReceiver(BroadcastReceiver& receiver) { core.unregisterReceiver(receiver); } }