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 "sync/js/sync_js_controller.h" 6 7 #include "base/location.h" 8 #include "sync/js/js_backend.h" 9 #include "sync/js/js_event_details.h" 10 11 namespace syncer { 12 13 SyncJsController::PendingJsMessage::PendingJsMessage( 14 const std::string& name, const JsArgList& args, 15 const WeakHandle<JsReplyHandler>& reply_handler) 16 : name(name), args(args), reply_handler(reply_handler) {} 17 18 SyncJsController::PendingJsMessage::~PendingJsMessage() {} 19 20 SyncJsController::SyncJsController() {} 21 22 SyncJsController::~SyncJsController() { 23 AttachJsBackend(WeakHandle<JsBackend>()); 24 } 25 26 void SyncJsController::AddJsEventHandler(JsEventHandler* event_handler) { 27 js_event_handlers_.AddObserver(event_handler); 28 UpdateBackendEventHandler(); 29 } 30 31 void SyncJsController::RemoveJsEventHandler(JsEventHandler* event_handler) { 32 js_event_handlers_.RemoveObserver(event_handler); 33 UpdateBackendEventHandler(); 34 } 35 36 void SyncJsController::AttachJsBackend( 37 const WeakHandle<JsBackend>& js_backend) { 38 js_backend_ = js_backend; 39 UpdateBackendEventHandler(); 40 41 if (js_backend_.IsInitialized()) { 42 // Process any queued messages. 43 for (PendingJsMessageList::const_iterator it = 44 pending_js_messages_.begin(); 45 it != pending_js_messages_.end(); ++it) { 46 js_backend_.Call(FROM_HERE, &JsBackend::ProcessJsMessage, 47 it->name, it->args, it->reply_handler); 48 } 49 } 50 } 51 52 void SyncJsController::ProcessJsMessage( 53 const std::string& name, const JsArgList& args, 54 const WeakHandle<JsReplyHandler>& reply_handler) { 55 if (js_backend_.IsInitialized()) { 56 js_backend_.Call(FROM_HERE, &JsBackend::ProcessJsMessage, 57 name, args, reply_handler); 58 } else { 59 pending_js_messages_.push_back( 60 PendingJsMessage(name, args, reply_handler)); 61 } 62 } 63 64 void SyncJsController::HandleJsEvent(const std::string& name, 65 const JsEventDetails& details) { 66 FOR_EACH_OBSERVER(JsEventHandler, js_event_handlers_, 67 HandleJsEvent(name, details)); 68 } 69 70 void SyncJsController::UpdateBackendEventHandler() { 71 if (js_backend_.IsInitialized()) { 72 // To avoid making the backend send useless events, we clear the 73 // event handler we pass to it if we don't have any event 74 // handlers. 75 WeakHandle<JsEventHandler> backend_event_handler = 76 (js_event_handlers_.size() > 0) ? 77 MakeWeakHandle(AsWeakPtr()) : WeakHandle<SyncJsController>(); 78 js_backend_.Call(FROM_HERE, &JsBackend::SetJsEventHandler, 79 backend_event_handler); 80 } 81 } 82 83 } // namespace syncer 84