Home | History | Annotate | Download | only in automation
      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