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 <string>
      6 
      7 #include "base/logging.h"
      8 #include "base/strings/stringprintf.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.h"
     12 #include "chrome/browser/automation/automation_provider_json.h"
     13 #include "content/public/browser/dom_operation_notification_details.h"
     14 #include "content/public/browser/notification_service.h"
     15 #include "content/public/browser/notification_types.h"
     16 
     17 const char* DomEventObserver::kSubstringReplaceWithObserverId = "$(id)";
     18 
     19 AutomationEventObserver::AutomationEventObserver(
     20     AutomationEventQueue* event_queue, bool recurring)
     21     : event_queue_(event_queue),
     22       recurring_(recurring),
     23       observer_id_(-1),
     24       event_count_(0) {
     25   DCHECK(event_queue_ != NULL);
     26 }
     27 
     28 AutomationEventObserver::~AutomationEventObserver() {}
     29 
     30 void AutomationEventObserver::NotifyEvent(DictionaryValue* value) {
     31   if (event_queue_) {
     32     if (!value)
     33       value = new DictionaryValue;
     34     value->SetInteger("observer_id", GetId());
     35     event_queue_->NotifyEvent(
     36         new AutomationEventQueue::AutomationEvent(
     37             GetId(), value));
     38     event_count_++;
     39   } else if (value) {
     40     delete value;
     41   }
     42 }
     43 
     44 void AutomationEventObserver::Init(int observer_id) {
     45     observer_id_ = observer_id;
     46 }
     47 
     48 int AutomationEventObserver::GetId() const {
     49   return observer_id_;
     50 }
     51 
     52 void AutomationEventObserver::RemoveIfDone() {
     53   if (!recurring_ && event_count_ > 0 && event_queue_) {
     54     event_queue_->RemoveObserver(GetId());
     55   }
     56 }
     57 
     58 DomEventObserver::DomEventObserver(
     59     AutomationEventQueue* event_queue,
     60     const std::string& event_name,
     61     int automation_id,
     62     bool recurring)
     63     : AutomationEventObserver(event_queue, recurring),
     64       event_name_(event_name),
     65       event_name_base_(event_name),
     66       automation_id_(automation_id) {
     67   registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
     68                  content::NotificationService::AllSources());
     69 }
     70 
     71 DomEventObserver::~DomEventObserver() {}
     72 
     73 void DomEventObserver::Init(int observer_id) {
     74     AutomationEventObserver::Init(observer_id);
     75     std::string id_string = base::StringPrintf("%d", observer_id);
     76     event_name_ = event_name_base_;
     77     int replace_pos =
     78         event_name_.find(kSubstringReplaceWithObserverId);
     79     if (replace_pos != (int)std::string::npos) {
     80       event_name_.replace(replace_pos,
     81                           ::strlen(kSubstringReplaceWithObserverId),
     82                           id_string);
     83     }
     84 }
     85 
     86 void DomEventObserver::Observe(
     87     int type,
     88     const content::NotificationSource& source,
     89     const content::NotificationDetails& details) {
     90   if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) {
     91     content::Details<content::DomOperationNotificationDetails> dom_op_details(
     92         details);
     93     if ((dom_op_details->automation_id == automation_id_ ||
     94          automation_id_ == -1) &&
     95         (event_name_.length() == 0 ||
     96          event_name_.compare(dom_op_details->json) == 0)) {
     97       DictionaryValue* dict = new DictionaryValue;
     98       dict->SetString("type", "raised_event");
     99       dict->SetString("name", dom_op_details->json);
    100       NotifyEvent(dict);
    101     }
    102   }
    103   // Nothing should happen after RemoveIfDone() as it may delete the object.
    104   RemoveIfDone();
    105 }
    106