15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_event_observers.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_event_queue.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider_json.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::CompareObserverId::CompareObserverId(int id) : id_(id) {}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationEventQueue::CompareObserverId::operator()(
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationEvent* event) const {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return event->GetId() < 0 || event->GetId() == id_;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::AutomationEventQueue()
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : observer_id_count_(0), wait_observer_id_(-1) {}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::~AutomationEventQueue() {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Clear();
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::AutomationEvent::AutomationEvent(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int observer_id, DictionaryValue* event_value)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : observer_id_(observer_id), event_value_(event_value) {}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventQueue::GetNextEvent(AutomationJSONReply* reply,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        int observer_id,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bool blocking) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_automation_reply_.reset(reply);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_observer_id_ = observer_id;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CheckReturnEvent() && !blocking && wait_automation_reply_.get()) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_automation_reply_->SendSuccess(NULL);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_automation_reply_.reset();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventQueue::Clear() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearObservers();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearEvents();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationEventQueue::IsEmpty() const {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return event_queue_.empty();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (event_queue_.empty()) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationEvent* event = event_queue_.back();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_queue_.pop_back();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return event;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int observer_id) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationEvent* event = NULL;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::list<AutomationEvent*>::reverse_iterator it =
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::find_if(event_queue_.rbegin(), event_queue_.rend(),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   CompareObserverId(observer_id));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != event_queue_.rend()) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event = *it;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event_queue_.remove(event);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return event;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventQueue::NotifyEvent(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationEventQueue::AutomationEvent* event) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(event);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(2) << "AutomationEventQueue::NotifyEvent id=" << event->GetId();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  event_queue_.push_front(event);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckReturnEvent();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AutomationEventQueue::AddObserver(AutomationEventObserver* observer) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int id = observer_id_count_++;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer->Init(id);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_[id] = observer;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationEventQueue::RemoveObserver(int observer_id) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observers_.find(observer_id) != observers_.end()) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(2) << "AutomationEventQueue::RemoveObserver id=" << observer_id;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete observers_[observer_id];
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.erase(observer_id);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventQueue::ClearObservers() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteValues(&observers_);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventQueue::ClearEvents() {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLDeleteElements(&event_queue_);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutomationEventQueue::CheckReturnEvent() {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (wait_automation_reply_.get()) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationEventQueue::AutomationEvent* event = wait_observer_id_ < 0 ?
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   PopEvent() :
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   PopEvent(wait_observer_id_);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_automation_reply_->SendSuccess(event->GetValue());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_automation_reply_.reset();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_observer_id_ = -1;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete event;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
123