1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <algorithm> 6 7 #include "base/logging.h" 8 #include "base/stl_util.h" 9 #include "chrome/browser/automation/automation_event_observers.h" 10 #include "chrome/browser/automation/automation_event_queue.h" 11 #include "chrome/browser/automation/automation_provider_json.h" 12 #include "content/public/browser/notification_service.h" 13 #include "content/public/browser/notification_types.h" 14 15 AutomationEventQueue::CompareObserverId::CompareObserverId(int id) : id_(id) {} 16 17 bool AutomationEventQueue::CompareObserverId::operator()( 18 AutomationEvent* event) const { 19 return event->GetId() < 0 || event->GetId() == id_; 20 } 21 22 AutomationEventQueue::AutomationEventQueue() 23 : observer_id_count_(0), wait_observer_id_(-1) {} 24 25 AutomationEventQueue::~AutomationEventQueue() { 26 Clear(); 27 } 28 29 AutomationEventQueue::AutomationEvent::AutomationEvent( 30 int observer_id, DictionaryValue* event_value) 31 : observer_id_(observer_id), event_value_(event_value) {} 32 33 void AutomationEventQueue::GetNextEvent(AutomationJSONReply* reply, 34 int observer_id, 35 bool blocking) { 36 wait_automation_reply_.reset(reply); 37 wait_observer_id_ = observer_id; 38 if (!CheckReturnEvent() && !blocking && wait_automation_reply_.get()) { 39 wait_automation_reply_->SendSuccess(NULL); 40 wait_automation_reply_.reset(); 41 } 42 } 43 44 void AutomationEventQueue::Clear() { 45 ClearObservers(); 46 ClearEvents(); 47 } 48 49 bool AutomationEventQueue::IsEmpty() const { 50 return event_queue_.empty(); 51 } 52 53 AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent() { 54 if (event_queue_.empty()) { 55 return NULL; 56 } 57 AutomationEvent* event = event_queue_.back(); 58 event_queue_.pop_back(); 59 return event; 60 } 61 62 AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent( 63 int observer_id) { 64 AutomationEvent* event = NULL; 65 std::list<AutomationEvent*>::reverse_iterator it = 66 std::find_if(event_queue_.rbegin(), event_queue_.rend(), 67 CompareObserverId(observer_id)); 68 if (it != event_queue_.rend()) { 69 event = *it; 70 event_queue_.remove(event); 71 } 72 return event; 73 } 74 75 void AutomationEventQueue::NotifyEvent( 76 AutomationEventQueue::AutomationEvent* event) { 77 DCHECK(event); 78 VLOG(2) << "AutomationEventQueue::NotifyEvent id=" << event->GetId(); 79 event_queue_.push_front(event); 80 CheckReturnEvent(); 81 } 82 83 int AutomationEventQueue::AddObserver(AutomationEventObserver* observer) { 84 int id = observer_id_count_++; 85 observer->Init(id); 86 observers_[id] = observer; 87 return id; 88 } 89 90 bool AutomationEventQueue::RemoveObserver(int observer_id) { 91 if (observers_.find(observer_id) != observers_.end()) { 92 VLOG(2) << "AutomationEventQueue::RemoveObserver id=" << observer_id; 93 delete observers_[observer_id]; 94 observers_.erase(observer_id); 95 return true; 96 } 97 return false; 98 } 99 100 void AutomationEventQueue::ClearObservers() { 101 STLDeleteValues(&observers_); 102 } 103 104 void AutomationEventQueue::ClearEvents() { 105 STLDeleteElements(&event_queue_); 106 } 107 108 bool AutomationEventQueue::CheckReturnEvent() { 109 if (wait_automation_reply_.get()) { 110 AutomationEventQueue::AutomationEvent* event = wait_observer_id_ < 0 ? 111 PopEvent() : 112 PopEvent(wait_observer_id_); 113 if (event) { 114 wait_automation_reply_->SendSuccess(event->GetValue()); 115 wait_automation_reply_.reset(); 116 wait_observer_id_ = -1; 117 delete event; 118 return true; 119 } 120 } 121 return false; 122 } 123