| // 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 <algorithm> |
| |
| #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<AutomationEvent*>::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; |
| } |