blob: 9ccbe2b0ed2584321818bfbaf0aa5fe7e5e5f5c3 [file] [log] [blame]
// 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;
}