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 <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.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.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider_json.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/dom_operation_notification_details.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* DomEventObserver::kSubstringReplaceWithObserverId = "$(id)"; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventObserver::AutomationEventObserver( 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationEventQueue* event_queue, bool recurring) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_queue_(event_queue), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recurring_(recurring), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_id_(-1), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_count_(0) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(event_queue_ != NULL); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationEventObserver::~AutomationEventObserver() {} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventObserver::NotifyEvent(DictionaryValue* value) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_queue_) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = new DictionaryValue; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value->SetInteger("observer_id", GetId()); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_->NotifyEvent( 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AutomationEventQueue::AutomationEvent( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetId(), value)); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_count_++; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete value; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventObserver::Init(int observer_id) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_id_ = observer_id; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AutomationEventObserver::GetId() const { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observer_id_; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationEventObserver::RemoveIfDone() { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!recurring_ && event_count_ > 0 && event_queue_) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_->RemoveObserver(GetId()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DomEventObserver::DomEventObserver( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationEventQueue* event_queue, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int automation_id, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool recurring) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : AutomationEventObserver(event_queue, recurring), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_(event_name), 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_base_(event_name), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automation_id_(automation_id) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DomEventObserver::~DomEventObserver() {} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DomEventObserver::Init(int observer_id) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutomationEventObserver::Init(observer_id); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id_string = base::StringPrintf("%d", observer_id); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_ = event_name_base_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int replace_pos = 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_.find(kSubstringReplaceWithObserverId); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (replace_pos != (int)std::string::npos) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_.replace(replace_pos, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::strlen(kSubstringReplaceWithObserverId), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_string); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DomEventObserver::Observe( 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<content::DomOperationNotificationDetails> dom_op_details( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dom_op_details->automation_id == automation_id_ || 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) automation_id_ == -1) && 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (event_name_.length() == 0 || 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name_.compare(dom_op_details->json) == 0)) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* dict = new DictionaryValue; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("type", "raised_event"); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetString("name", dom_op_details->json); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyEvent(dict); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing should happen after RemoveIfDone() as it may delete the object. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveIfDone(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 106