Home | History | Annotate | Download | only in notifier
      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 
     20 namespace sync_notifier {
     21 
     22 InvalidationNotifier::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 
     36 InvalidationNotifier::~InvalidationNotifier() {
     37   DCHECK(non_thread_safe_.CalledOnValidThread());
     38 }
     39 
     40 void InvalidationNotifier::AddObserver(SyncNotifierObserver* observer) {
     41   DCHECK(non_thread_safe_.CalledOnValidThread());
     42   observers_.AddObserver(observer);
     43 }
     44 
     45 void InvalidationNotifier::RemoveObserver(SyncNotifierObserver* observer) {
     46   DCHECK(non_thread_safe_.CalledOnValidThread());
     47   observers_.RemoveObserver(observer);
     48 }
     49 
     50 void InvalidationNotifier::SetState(const std::string& state) {
     51   DCHECK(non_thread_safe_.CalledOnValidThread());
     52   invalidation_state_ = state;
     53 }
     54 
     55 void 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 
     80 void InvalidationNotifier::UpdateEnabledTypes(
     81     const syncable::ModelTypeSet& types) {
     82   DCHECK(non_thread_safe_.CalledOnValidThread());
     83   invalidation_client_.RegisterTypes(types);
     84 }
     85 
     86 void InvalidationNotifier::SendNotification() {
     87   DCHECK(non_thread_safe_.CalledOnValidThread());
     88 }
     89 
     90 void 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 
    110 void InvalidationNotifier::OnDisconnect() {
    111   DCHECK(non_thread_safe_.CalledOnValidThread());
    112   VLOG(1) << "OnDisconnect";
    113 }
    114 
    115 void 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 
    122 void InvalidationNotifier::OnSessionStatusChanged(bool has_session) {
    123   FOR_EACH_OBSERVER(SyncNotifierObserver, observers_,
    124                     OnNotificationStateChange(has_session));
    125 }
    126 
    127 void 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