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/notifier/invalidation_notifier.h" 6 7#include "base/logging.h" 8#include "base/message_loop_proxy.h" 9#include "chrome/browser/sync/notifier/sync_notifier_observer.h" 10#include "chrome/browser/sync/protocol/service_constants.h" 11#include "chrome/browser/sync/syncable/model_type_payload_map.h" 12#include "jingle/notifier/base/const_communicator.h" 13#include "jingle/notifier/base/notifier_options_util.h" 14#include "jingle/notifier/communicator/connection_options.h" 15#include "net/base/host_port_pair.h" 16#include "net/url_request/url_request_context.h" 17#include "talk/xmpp/jid.h" 18#include "talk/xmpp/xmppclientsettings.h" 19 20namespace sync_notifier { 21 22InvalidationNotifier::InvalidationNotifier( 23 const notifier::NotifierOptions& notifier_options, 24 const std::string& client_info) 25 : state_(STOPPED), 26 notifier_options_(notifier_options), 27 client_info_(client_info) { 28 DCHECK_EQ(notifier::NOTIFICATION_SERVER, 29 notifier_options.notification_method); 30 DCHECK(notifier_options_.request_context_getter); 31 // TODO(akalin): Replace NonThreadSafe checks with IO thread checks. 32 DCHECK(notifier_options_.request_context_getter->GetIOMessageLoopProxy()-> 33 BelongsToCurrentThread()); 34} 35 36InvalidationNotifier::~InvalidationNotifier() { 37 DCHECK(non_thread_safe_.CalledOnValidThread()); 38} 39 40void InvalidationNotifier::AddObserver(SyncNotifierObserver* observer) { 41 DCHECK(non_thread_safe_.CalledOnValidThread()); 42 observers_.AddObserver(observer); 43} 44 45void InvalidationNotifier::RemoveObserver(SyncNotifierObserver* observer) { 46 DCHECK(non_thread_safe_.CalledOnValidThread()); 47 observers_.RemoveObserver(observer); 48} 49 50void InvalidationNotifier::SetState(const std::string& state) { 51 DCHECK(non_thread_safe_.CalledOnValidThread()); 52 invalidation_state_ = state; 53} 54 55void InvalidationNotifier::UpdateCredentials( 56 const std::string& email, const std::string& token) { 57 DCHECK(non_thread_safe_.CalledOnValidThread()); 58 VLOG(1) << "Updating credentials for " << email; 59 buzz::XmppClientSettings xmpp_client_settings = 60 notifier::MakeXmppClientSettings(notifier_options_, 61 email, token, SYNC_SERVICE_NAME); 62 if (state_ >= CONNECTING) { 63 login_->UpdateXmppSettings(xmpp_client_settings); 64 } else { 65 notifier::ConnectionOptions options; 66 VLOG(1) << "First time updating credentials: connecting"; 67 login_.reset( 68 new notifier::Login(this, 69 xmpp_client_settings, 70 notifier::ConnectionOptions(), 71 notifier_options_.request_context_getter, 72 notifier::GetServerList(notifier_options_), 73 notifier_options_.try_ssltcp_first, 74 notifier_options_.auth_mechanism)); 75 login_->StartConnection(); 76 state_ = CONNECTING; 77 } 78} 79 80void InvalidationNotifier::UpdateEnabledTypes( 81 const syncable::ModelTypeSet& types) { 82 DCHECK(non_thread_safe_.CalledOnValidThread()); 83 invalidation_client_.RegisterTypes(types); 84} 85 86void InvalidationNotifier::SendNotification() { 87 DCHECK(non_thread_safe_.CalledOnValidThread()); 88} 89 90void InvalidationNotifier::OnConnect( 91 base::WeakPtr<talk_base::Task> base_task) { 92 DCHECK(non_thread_safe_.CalledOnValidThread()); 93 VLOG(1) << "OnConnect"; 94 if (state_ >= STARTED) { 95 invalidation_client_.ChangeBaseTask(base_task); 96 } else { 97 VLOG(1) << "First time connecting: starting invalidation client"; 98 // TODO(akalin): Make cache_guid() part of the client ID. If we 99 // do so and we somehow propagate it up to the server somehow, we 100 // can make it so that we won't receive any notifications that 101 // were generated from our own changes. 102 const std::string kClientId = "invalidation_notifier"; 103 invalidation_client_.Start( 104 kClientId, client_info_, invalidation_state_, this, this, base_task); 105 invalidation_state_.clear(); 106 state_ = STARTED; 107 } 108} 109 110void InvalidationNotifier::OnDisconnect() { 111 DCHECK(non_thread_safe_.CalledOnValidThread()); 112 VLOG(1) << "OnDisconnect"; 113} 114 115void InvalidationNotifier::OnInvalidate( 116 const syncable::ModelTypePayloadMap& type_payloads) { 117 DCHECK(non_thread_safe_.CalledOnValidThread()); 118 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, 119 OnIncomingNotification(type_payloads)); 120} 121 122void InvalidationNotifier::OnSessionStatusChanged(bool has_session) { 123 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, 124 OnNotificationStateChange(has_session)); 125} 126 127void InvalidationNotifier::WriteState(const std::string& state) { 128 DCHECK(non_thread_safe_.CalledOnValidThread()); 129 VLOG(1) << "WriteState"; 130 FOR_EACH_OBSERVER(SyncNotifierObserver, observers_, StoreState(state)); 131} 132 133} // namespace sync_notifier 134