• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/browser/sync/js_event_handler_list.h"
6 
7 #include <cstddef>
8 
9 #include "base/logging.h"
10 #include "chrome/browser/sync/js_backend.h"
11 #include "chrome/browser/sync/js_event_handler.h"
12 
13 namespace browser_sync {
14 
PendingMessage(const std::string & name,const JsArgList & args,const JsEventHandler * sender)15 JsEventHandlerList::PendingMessage::PendingMessage(
16     const std::string& name, const JsArgList& args,
17     const JsEventHandler* sender)
18     : name(name), args(args), sender(sender) {}
19 
JsEventHandlerList()20 JsEventHandlerList::JsEventHandlerList() : backend_(NULL) {}
21 
~JsEventHandlerList()22 JsEventHandlerList::~JsEventHandlerList() {
23   RemoveBackend();
24 }
25 
26 // We connect to the backend only when necessary, i.e. when there is
27 // at least one handler.
28 
AddHandler(JsEventHandler * handler)29 void JsEventHandlerList::AddHandler(JsEventHandler* handler) {
30   handlers_.AddObserver(handler);
31   if (backend_) {
32     backend_->SetParentJsEventRouter(this);
33   }
34 }
35 
RemoveHandler(JsEventHandler * handler)36 void JsEventHandlerList::RemoveHandler(JsEventHandler* handler) {
37   handlers_.RemoveObserver(handler);
38   if (backend_ && handlers_.size() == 0) {
39     backend_->RemoveParentJsEventRouter();
40   }
41 }
42 
SetBackend(JsBackend * backend)43 void JsEventHandlerList::SetBackend(JsBackend* backend) {
44   DCHECK(!backend_);
45   DCHECK(backend);
46   backend_ = backend;
47 
48   if (handlers_.size() > 0) {
49     backend_->SetParentJsEventRouter(this);
50 
51     // Process any queued messages.
52     PendingMessageList pending_messages;
53     pending_messages_.swap(pending_messages);
54     for (PendingMessageList::const_iterator it = pending_messages.begin();
55          it != pending_messages.end(); ++it) {
56       backend_->ProcessMessage(it->name, it->args, it->sender);
57     }
58   }
59 }
60 
RemoveBackend()61 void JsEventHandlerList::RemoveBackend() {
62   if (backend_) {
63     backend_->RemoveParentJsEventRouter();
64     backend_ = NULL;
65   }
66 }
67 
ProcessMessage(const std::string & name,const JsArgList & args,const JsEventHandler * sender)68 void JsEventHandlerList::ProcessMessage(
69     const std::string& name, const JsArgList& args,
70     const JsEventHandler* sender) {
71   if (backend_) {
72     backend_->ProcessMessage(name, args, sender);
73   } else {
74     pending_messages_.push_back(PendingMessage(name, args, sender));
75   }
76 }
77 
RouteJsEvent(const std::string & name,const JsArgList & args,const JsEventHandler * target)78 void JsEventHandlerList::RouteJsEvent(const std::string& name,
79                                       const JsArgList& args,
80                                       const JsEventHandler* target) {
81   if (target) {
82     JsEventHandler* non_const_target(const_cast<JsEventHandler*>(target));
83     if (handlers_.HasObserver(non_const_target)) {
84       non_const_target->HandleJsEvent(name, args);
85     } else {
86       VLOG(1) << "Unknown target; dropping event " << name
87               << " with args " << args.ToString();
88     }
89   } else {
90     FOR_EACH_OBSERVER(JsEventHandler, handlers_, HandleJsEvent(name, args));
91   }
92 }
93 
94 }  // namespace browser_sync
95