• 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/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 
InvalidationNotifier(const notifier::NotifierOptions & notifier_options,const std::string & client_info)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 
~InvalidationNotifier()36 InvalidationNotifier::~InvalidationNotifier() {
37   DCHECK(non_thread_safe_.CalledOnValidThread());
38 }
39 
AddObserver(SyncNotifierObserver * observer)40 void InvalidationNotifier::AddObserver(SyncNotifierObserver* observer) {
41   DCHECK(non_thread_safe_.CalledOnValidThread());
42   observers_.AddObserver(observer);
43 }
44 
RemoveObserver(SyncNotifierObserver * observer)45 void InvalidationNotifier::RemoveObserver(SyncNotifierObserver* observer) {
46   DCHECK(non_thread_safe_.CalledOnValidThread());
47   observers_.RemoveObserver(observer);
48 }
49 
SetState(const std::string & state)50 void InvalidationNotifier::SetState(const std::string& state) {
51   DCHECK(non_thread_safe_.CalledOnValidThread());
52   invalidation_state_ = state;
53 }
54 
UpdateCredentials(const std::string & email,const std::string & token)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 
UpdateEnabledTypes(const syncable::ModelTypeSet & types)80 void InvalidationNotifier::UpdateEnabledTypes(
81     const syncable::ModelTypeSet& types) {
82   DCHECK(non_thread_safe_.CalledOnValidThread());
83   invalidation_client_.RegisterTypes(types);
84 }
85 
SendNotification()86 void InvalidationNotifier::SendNotification() {
87   DCHECK(non_thread_safe_.CalledOnValidThread());
88 }
89 
OnConnect(base::WeakPtr<talk_base::Task> base_task)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 
OnDisconnect()110 void InvalidationNotifier::OnDisconnect() {
111   DCHECK(non_thread_safe_.CalledOnValidThread());
112   VLOG(1) << "OnDisconnect";
113 }
114 
OnInvalidate(const syncable::ModelTypePayloadMap & type_payloads)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 
OnSessionStatusChanged(bool has_session)122 void InvalidationNotifier::OnSessionStatusChanged(bool has_session) {
123   FOR_EACH_OBSERVER(SyncNotifierObserver, observers_,
124                     OnNotificationStateChange(has_session));
125 }
126 
WriteState(const std::string & state)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