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