// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "base/logging.h" #include "base/stl_util.h" #include "chrome/browser/automation/automation_event_observers.h" #include "chrome/browser/automation/automation_event_queue.h" #include "chrome/browser/automation/automation_provider_json.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" AutomationEventQueue::CompareObserverId::CompareObserverId(int id) : id_(id) {} bool AutomationEventQueue::CompareObserverId::operator()( AutomationEvent* event) const { return event->GetId() < 0 || event->GetId() == id_; } AutomationEventQueue::AutomationEventQueue() : observer_id_count_(0), wait_observer_id_(-1) {} AutomationEventQueue::~AutomationEventQueue() { Clear(); } AutomationEventQueue::AutomationEvent::AutomationEvent( int observer_id, DictionaryValue* event_value) : observer_id_(observer_id), event_value_(event_value) {} void AutomationEventQueue::GetNextEvent(AutomationJSONReply* reply, int observer_id, bool blocking) { wait_automation_reply_.reset(reply); wait_observer_id_ = observer_id; if (!CheckReturnEvent() && !blocking && wait_automation_reply_.get()) { wait_automation_reply_->SendSuccess(NULL); wait_automation_reply_.reset(); } } void AutomationEventQueue::Clear() { ClearObservers(); ClearEvents(); } bool AutomationEventQueue::IsEmpty() const { return event_queue_.empty(); } AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent() { if (event_queue_.empty()) { return NULL; } AutomationEvent* event = event_queue_.back(); event_queue_.pop_back(); return event; } AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent( int observer_id) { AutomationEvent* event = NULL; std::list::reverse_iterator it = std::find_if(event_queue_.rbegin(), event_queue_.rend(), CompareObserverId(observer_id)); if (it != event_queue_.rend()) { event = *it; event_queue_.remove(event); } return event; } void AutomationEventQueue::NotifyEvent( AutomationEventQueue::AutomationEvent* event) { DCHECK(event); VLOG(2) << "AutomationEventQueue::NotifyEvent id=" << event->GetId(); event_queue_.push_front(event); CheckReturnEvent(); } int AutomationEventQueue::AddObserver(AutomationEventObserver* observer) { int id = observer_id_count_++; observer->Init(id); observers_[id] = observer; return id; } bool AutomationEventQueue::RemoveObserver(int observer_id) { if (observers_.find(observer_id) != observers_.end()) { VLOG(2) << "AutomationEventQueue::RemoveObserver id=" << observer_id; delete observers_[observer_id]; observers_.erase(observer_id); return true; } return false; } void AutomationEventQueue::ClearObservers() { STLDeleteValues(&observers_); } void AutomationEventQueue::ClearEvents() { STLDeleteElements(&event_queue_); } bool AutomationEventQueue::CheckReturnEvent() { if (wait_automation_reply_.get()) { AutomationEventQueue::AutomationEvent* event = wait_observer_id_ < 0 ? PopEvent() : PopEvent(wait_observer_id_); if (event) { wait_automation_reply_->SendSuccess(event->GetValue()); wait_automation_reply_.reset(); wait_observer_id_ = -1; delete event; return true; } } return false; }