summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/engine')
-rw-r--r--chrome/browser/sync/engine/all_status.cc47
-rw-r--r--chrome/browser/sync/engine/all_status.h3
-rw-r--r--chrome/browser/sync/engine/auth_watcher.cc352
-rw-r--r--chrome/browser/sync/engine/auth_watcher.h222
-rw-r--r--chrome/browser/sync/engine/auth_watcher_unittest.cc235
-rw-r--r--chrome/browser/sync/engine/authenticator.cc110
-rw-r--r--chrome/browser/sync/engine/authenticator.h105
-rw-r--r--chrome/browser/sync/engine/net/server_connection_manager.cc13
-rw-r--r--chrome/browser/sync/engine/net/server_connection_manager.h18
-rw-r--r--chrome/browser/sync/engine/net/syncapi_server_connection_manager.h4
-rw-r--r--chrome/browser/sync/engine/syncapi.cc450
-rw-r--r--chrome/browser/sync/engine/syncapi.h63
-rw-r--r--chrome/browser/sync/engine/syncapi_unittest.cc2
-rw-r--r--chrome/browser/sync/engine/syncer_proto_util.cc15
-rw-r--r--chrome/browser/sync/engine/syncer_proto_util.h2
-rw-r--r--chrome/browser/sync/engine/syncer_proto_util_unittest.cc2
-rw-r--r--chrome/browser/sync/engine/syncer_thread.cc38
-rw-r--r--chrome/browser/sync/engine/syncer_thread.h11
-rw-r--r--chrome/browser/sync/engine/syncer_thread_unittest.cc21
-rw-r--r--chrome/browser/sync/engine/syncer_types.h5
-rw-r--r--chrome/browser/sync/engine/syncer_unittest.cc2
21 files changed, 188 insertions, 1532 deletions
diff --git a/chrome/browser/sync/engine/all_status.cc b/chrome/browser/sync/engine/all_status.cc
index 178fe7f..72e1f6d 100644
--- a/chrome/browser/sync/engine/all_status.cc
+++ b/chrome/browser/sync/engine/all_status.cc
@@ -8,7 +8,6 @@
#include "base/logging.h"
#include "base/port.h"
-#include "chrome/browser/sync/engine/auth_watcher.h"
#include "chrome/browser/sync/engine/net/server_connection_manager.h"
#include "chrome/browser/sync/engine/syncer.h"
#include "chrome/browser/sync/engine/syncer_thread.h"
@@ -48,11 +47,6 @@ AllStatus::~AllStatus() {
delete channel_;
}
-void AllStatus::WatchConnectionManager(ServerConnectionManager* conn_mgr) {
- conn_mgr_hookup_.reset(NewEventListenerHookup(conn_mgr->channel(), this,
- &AllStatus::HandleServerConnectionEvent));
-}
-
void AllStatus::WatchSyncerThread(SyncerThread* syncer_thread) {
syncer_thread_hookup_.reset(syncer_thread == NULL ? NULL :
syncer_thread->relay_channel()->AddObserver(this));
@@ -99,10 +93,6 @@ AllStatus::Status AllStatus::CalcSyncing(const SyncerEvent &event) const {
return status;
}
-AllStatus::Status AllStatus::CalcSyncing() const {
- return CreateBlankStatus();
-}
-
int AllStatus::CalcStatusChanges(Status* old_status) {
int what_changed = 0;
@@ -153,34 +143,6 @@ int AllStatus::CalcStatusChanges(Status* old_status) {
return what_changed;
}
-void AllStatus::HandleAuthWatcherEvent(const AuthWatcherEvent& auth_event) {
- ScopedStatusLockWithNotify lock(this);
- switch (auth_event.what_happened) {
- case AuthWatcherEvent::GAIA_AUTH_FAILED:
- case AuthWatcherEvent::SERVICE_AUTH_FAILED:
- case AuthWatcherEvent::SERVICE_CONNECTION_FAILED:
- case AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START:
- status_.authenticated = false;
- break;
- case AuthWatcherEvent::AUTH_SUCCEEDED:
- // If we've already calculated that the server is reachable, since we've
- // successfully authenticated, we can be confident that the server is up.
- if (status_.server_reachable)
- status_.server_up = true;
-
- if (!status_.authenticated) {
- status_.authenticated = true;
- status_ = CalcSyncing();
- } else {
- lock.set_notify_plan(DONT_NOTIFY);
- }
- break;
- default:
- lock.set_notify_plan(DONT_NOTIFY);
- break;
- }
-}
-
void AllStatus::HandleChannelEvent(const SyncerEvent& event) {
ScopedStatusLockWithNotify lock(this);
switch (event.what_happened) {
@@ -222,6 +184,15 @@ void AllStatus::HandleServerConnectionEvent(
ScopedStatusLockWithNotify lock(this);
status_.server_up = IsGoodReplyFromServer(event.connection_code);
status_.server_reachable = event.server_reachable;
+
+ if (event.connection_code == HttpResponse::SERVER_CONNECTION_OK) {
+ if (!status_.authenticated) {
+ status_ = CreateBlankStatus();
+ }
+ status_.authenticated = true;
+ } else {
+ status_.authenticated = false;
+ }
}
}
diff --git a/chrome/browser/sync/engine/all_status.h b/chrome/browser/sync/engine/all_status.h
index 772f40d..b843a1a 100644
--- a/chrome/browser/sync/engine/all_status.h
+++ b/chrome/browser/sync/engine/all_status.h
@@ -89,7 +89,6 @@ class AllStatus : public ChannelEventHandler<SyncerEvent> {
AllStatus();
~AllStatus();
- void WatchConnectionManager(ServerConnectionManager* conn_mgr);
void HandleServerConnectionEvent(const ServerConnectionEvent& event);
void HandleAuthWatcherEvent(const AuthWatcherEvent& event);
@@ -116,7 +115,6 @@ class AllStatus : public ChannelEventHandler<SyncerEvent> {
// Examines syncer to calculate syncing and the unsynced count,
// and returns a Status with new values.
- Status CalcSyncing() const;
Status CalcSyncing(const SyncerEvent& event) const;
Status CreateBlankStatus() const;
@@ -125,7 +123,6 @@ class AllStatus : public ChannelEventHandler<SyncerEvent> {
Status status_;
Channel* const channel_;
- scoped_ptr<EventListenerHookup> conn_mgr_hookup_;
scoped_ptr<ChannelHookup<SyncerEvent> > syncer_thread_hookup_;
scoped_ptr<EventListenerHookup> diskfull_hookup_;
scoped_ptr<EventListenerHookup> talk_mediator_hookup_;
diff --git a/chrome/browser/sync/engine/auth_watcher.cc b/chrome/browser/sync/engine/auth_watcher.cc
deleted file mode 100644
index b414e18..0000000
--- a/chrome/browser/sync/engine/auth_watcher.cc
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/engine/auth_watcher.h"
-
-#include "base/file_util.h"
-#include "base/string_util.h"
-#include "chrome/browser/sync/engine/all_status.h"
-#include "chrome/browser/sync/engine/authenticator.h"
-#include "chrome/browser/sync/engine/net/server_connection_manager.h"
-#include "chrome/browser/sync/syncable/directory_manager.h"
-#include "chrome/browser/sync/syncable/syncable.h"
-#include "chrome/browser/sync/util/user_settings.h"
-#include "chrome/common/deprecated/event_sys-inl.h"
-#include "chrome/common/net/gaia/gaia_authenticator.h"
-
-// How authentication happens:
-//
-// Kick Off:
-// The sync API looks to see if the user's name and
-// password are stored. If so, it calls authwatcher.Authenticate() with
-// them. Otherwise it fires an error event.
-//
-// On failed Gaia Auth:
-// The AuthWatcher attempts to use saved hashes to authenticate
-// locally, and on success opens the share.
-// On failure, fires an error event.
-//
-// On successful Gaia Auth:
-// AuthWatcher launches a thread to open the share and to get the
-// authentication token from the sync server.
-
-using std::pair;
-using std::string;
-using std::vector;
-
-namespace browser_sync {
-
-AuthWatcher::AuthWatcher(DirectoryManager* dirman,
- ServerConnectionManager* scm,
- const string& user_agent,
- const string& service_id,
- const string& gaia_url,
- UserSettings* user_settings,
- gaia::GaiaAuthenticator* gaia_auth)
- : gaia_(gaia_auth),
- dirman_(dirman),
- scm_(scm),
- status_(NOT_AUTHENTICATED),
- user_settings_(user_settings),
- auth_backend_thread_("SyncEngine_AuthWatcherThread"),
- current_attempt_trigger_(AuthWatcherEvent::USER_INITIATED) {
-
- if (!auth_backend_thread_.Start())
- NOTREACHED() << "Couldn't start SyncEngine_AuthWatcherThread";
-
- gaia_->set_message_loop(message_loop());
- loop_proxy_ = auth_backend_thread_.message_loop_proxy();
-
- connmgr_hookup_.reset(
- NewEventListenerHookup(scm->channel(), this,
- &AuthWatcher::HandleServerConnectionEvent));
- AuthWatcherEvent done = { AuthWatcherEvent::AUTHWATCHER_DESTROYED };
- channel_.reset(new Channel(done));
-}
-
-void AuthWatcher::PersistCredentials() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- gaia::GaiaAuthenticator::AuthResults results = gaia_->results();
-
- // We just successfully signed in again, let's clear out any residual cached
- // login data from earlier sessions.
- ClearAuthenticationData();
-
- user_settings_->StoreEmailForSignin(results.email, results.primary_email);
- results.email = results.primary_email;
- gaia_->SetUsernamePassword(results.primary_email, results.password);
- if (!user_settings_->VerifyAgainstStoredHash(results.email, results.password))
- user_settings_->StoreHashedPassword(results.email, results.password);
-
- user_settings_->SetAuthTokenForService(results.email,
- SYNC_SERVICE_NAME,
- gaia_->auth_token());
-}
-
-// TODO(chron): Full integration test suite needed. http://crbug.com/35429
-void AuthWatcher::RenewAuthToken(const std::string& updated_token) {
- message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &AuthWatcher::DoRenewAuthToken, updated_token));
-}
-
-void AuthWatcher::DoRenewAuthToken(const std::string& updated_token) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- // TODO(chron): We should probably only store auth token in one place.
- if (scm_->auth_token() == updated_token) {
- return; // This thread is the only one writing to the SCM's auth token.
- }
- LOG(INFO) << "Updating auth token:" << updated_token;
- scm_->set_auth_token(updated_token);
- gaia_->RenewAuthToken(updated_token); // Must be on AuthWatcher thread
- user_settings_->SetAuthTokenForService(user_settings_->email(),
- SYNC_SERVICE_NAME,
- updated_token);
-
- NotifyAuthChanged(user_settings_->email(), updated_token, true);
-}
-
-void AuthWatcher::AuthenticateWithLsid(const std::string& lsid) {
- message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &AuthWatcher::DoAuthenticateWithLsid, lsid));
-}
-
-void AuthWatcher::DoAuthenticateWithLsid(const std::string& lsid) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
-
- AuthWatcherEvent event = { AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START };
- NotifyListeners(&event);
-
- if (gaia_->AuthenticateWithLsid(lsid)) {
- PersistCredentials();
- DoAuthenticateWithToken(gaia_->email(), gaia_->auth_token());
- } else {
- ProcessGaiaAuthFailure();
- }
-}
-
-const char kAuthWatcher[] = "AuthWatcher";
-
-void AuthWatcher::AuthenticateWithToken(const std::string& gaia_email,
- const std::string& auth_token) {
- message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &AuthWatcher::DoAuthenticateWithToken, gaia_email, auth_token));
-}
-
-void AuthWatcher::DoAuthenticateWithToken(const std::string& gaia_email,
- const std::string& auth_token) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
-
- Authenticator auth(scm_, user_settings_);
- Authenticator::AuthenticationResult result =
- auth.AuthenticateToken(auth_token);
- string email = gaia_email;
- if (auth.display_email() && *auth.display_email()) {
- email = auth.display_email();
- LOG(INFO) << "Auth returned email " << email << " for gaia email " <<
- gaia_email;
- }
-
- AuthWatcherEvent event = {AuthWatcherEvent::ILLEGAL_VALUE , 0};
- gaia_->SetUsername(email);
- gaia_->SetAuthToken(auth_token);
- const bool was_authenticated = NOT_AUTHENTICATED != status_;
- switch (result) {
- case Authenticator::SUCCESS:
- {
- status_ = GAIA_AUTHENTICATED;
- const std::string& share_name = email;
- user_settings_->SwitchUser(email);
- scm_->set_auth_token(auth_token);
-
- if (!was_authenticated) {
- LOG(INFO) << "Opening DB for AuthenticateWithToken ("
- << share_name << ")";
- dirman_->Open(share_name);
- }
- NotifyAuthChanged(email, auth_token, false);
- return;
- }
- case Authenticator::BAD_AUTH_TOKEN:
- event.what_happened = AuthWatcherEvent::SERVICE_AUTH_FAILED;
- break;
- case Authenticator::CORRUPT_SERVER_RESPONSE:
- case Authenticator::SERVICE_DOWN:
- event.what_happened = AuthWatcherEvent::SERVICE_CONNECTION_FAILED;
- break;
- case Authenticator::USER_NOT_ACTIVATED:
- event.what_happened = AuthWatcherEvent::SERVICE_USER_NOT_SIGNED_UP;
- break;
- default:
- LOG(FATAL) << "Illegal return from AuthenticateToken";
- return;
- }
- // Always fall back to local authentication.
- if (was_authenticated || AuthenticateLocally(email)) {
- if (AuthWatcherEvent::SERVICE_CONNECTION_FAILED == event.what_happened)
- return;
- }
- DCHECK_NE(event.what_happened, AuthWatcherEvent::ILLEGAL_VALUE);
- NotifyListeners(&event);
-}
-
-bool AuthWatcher::AuthenticateLocally(string email) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- user_settings_->GetEmailForSignin(&email);
- if (file_util::PathExists(FilePath(dirman_->GetSyncDataDatabasePath()))) {
- gaia_->SetUsername(email);
- status_ = LOCALLY_AUTHENTICATED;
- user_settings_->SwitchUser(email);
- LOG(INFO) << "Opening DB for AuthenticateLocally (" << email << ")";
- dirman_->Open(email);
- NotifyAuthChanged(email, "", false);
- return true;
- } else {
- return false;
- }
-}
-
-bool AuthWatcher::AuthenticateLocally(string email, const string& password) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- user_settings_->GetEmailForSignin(&email);
- return user_settings_->VerifyAgainstStoredHash(email, password)
- && AuthenticateLocally(email);
-}
-
-void AuthWatcher::ProcessGaiaAuthFailure() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- gaia::GaiaAuthenticator::AuthResults results = gaia_->results();
- if (LOCALLY_AUTHENTICATED != status_ &&
- AuthenticateLocally(results.email, results.password)) {
- // TODO(chron): Do we really want a bogus token?
- const string auth_token("bogus");
- user_settings_->SetAuthTokenForService(results.email,
- SYNC_SERVICE_NAME,
- auth_token);
- }
- AuthWatcherEvent myevent = { AuthWatcherEvent::GAIA_AUTH_FAILED, &results };
- NotifyListeners(&myevent);
-}
-
-void AuthWatcher::DoAuthenticate(const AuthRequest& request) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
-
- AuthWatcherEvent event = { AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START };
- NotifyListeners(&event);
-
- current_attempt_trigger_ = request.trigger;
-
- // We let the caller be lazy and try using the last captcha token seen by
- // the gaia authenticator if they haven't provided a token but have sent
- // a challenge response. Of course, if the captcha token is specified,
- // we use that one instead.
- std::string captcha_token(request.captcha_token);
- if (!request.captcha_value.empty() && captcha_token.empty())
- captcha_token = gaia_->captcha_token();
-
- if (!request.password.empty()) {
- bool authenticated = false;
- if (!captcha_token.empty()) {
- authenticated = gaia_->Authenticate(request.email, request.password,
- captcha_token,
- request.captcha_value);
- } else {
- authenticated = gaia_->Authenticate(request.email, request.password);
- }
- if (authenticated) {
- PersistCredentials();
- DoAuthenticateWithToken(gaia_->email(), gaia_->auth_token());
- } else {
- ProcessGaiaAuthFailure();
- }
- } else if (!request.auth_token.empty()) {
- DoAuthenticateWithToken(request.email, request.auth_token);
- } else {
- LOG(ERROR) << "Attempt to authenticate with no credentials.";
- }
-}
-
-void AuthWatcher::NotifyAuthChanged(const string& email,
- const string& auth_token,
- bool renewed) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- LOG(INFO) << "NotifyAuthSucceeded";
- AuthWatcherEvent event = {
- renewed ?
- AuthWatcherEvent::AUTH_RENEWED :
- AuthWatcherEvent::AUTH_SUCCEEDED
- };
- event.user_email = email;
- event.auth_token = auth_token;
-
- NotifyListeners(&event);
-}
-
-void AuthWatcher::HandleServerConnectionEvent(
- const ServerConnectionEvent& event) {
- message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &AuthWatcher::DoHandleServerConnectionEvent, event,
- scm_->auth_token()));
-}
-
-void AuthWatcher::DoHandleServerConnectionEvent(
- const ServerConnectionEvent& event,
- const std::string& auth_token_snapshot) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
- if (event.server_reachable &&
- // If the auth_token at the time of the event differs from the current
- // one, we have authenticated since then and don't need to re-try.
- (auth_token_snapshot == gaia_->auth_token()) &&
- (event.connection_code == HttpResponse::SYNC_AUTH_ERROR ||
- status_ == LOCALLY_AUTHENTICATED)) {
- // We're either online or just got reconnected and want to try to
- // authenticate. If we've got a saved token this should just work. If not
- // the auth failure should trigger UI indications that we're not logged in.
-
- // METRIC: If we get a SYNC_AUTH_ERROR, our token expired.
- gaia::GaiaAuthenticator::AuthResults authresults = gaia_->results();
- AuthRequest request = { authresults.email, authresults.password,
- authresults.auth_token, std::string(),
- std::string(),
- AuthWatcherEvent::EXPIRED_CREDENTIALS };
- DoAuthenticate(request);
- }
-}
-
-AuthWatcher::~AuthWatcher() {
- auth_backend_thread_.Stop();
- // The gaia authenticator takes a const MessageLoop* because it only uses it
- // to ensure all methods are invoked on the given loop. Once our thread has
- // stopped, the current message loop will be NULL, and no methods should be
- // invoked on |gaia_| after this point. We could set it to NULL, but
- // abstaining allows for even more sanity checking that nothing is invoked on
- // it from now on.
-}
-
-void AuthWatcher::Authenticate(const string& email, const string& password,
- const string& captcha_token, const string& captcha_value) {
- LOG(INFO) << "AuthWatcher::Authenticate called";
-
- string empty;
- AuthRequest request = { FormatAsEmailAddress(email), password, empty,
- captcha_token, captcha_value,
- AuthWatcherEvent::USER_INITIATED };
- message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(this,
- &AuthWatcher::DoAuthenticate, request));
-}
-
-void AuthWatcher::ClearAuthenticationData() {
- scm_->set_auth_token(std::string());
- user_settings_->ClearAllServiceTokens();
-}
-
-string AuthWatcher::email() const {
- return gaia_->email();
-}
-
-void AuthWatcher::NotifyListeners(AuthWatcherEvent* event) {
- event->trigger = current_attempt_trigger_;
- channel_->NotifyListeners(*event);
-}
-
-} // namespace browser_sync
diff --git a/chrome/browser/sync/engine/auth_watcher.h b/chrome/browser/sync/engine/auth_watcher.h
deleted file mode 100644
index da90f95..0000000
--- a/chrome/browser/sync/engine/auth_watcher.h
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// AuthWatcher watches authentication events and user open and close
-// events and accordingly opens and closes shares.
-
-#ifndef CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
-#define CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
-#pragma once
-
-#include <string>
-
-#include "base/gtest_prod_util.h"
-#include "base/message_loop_proxy.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "base/thread.h"
-#include "chrome/browser/sync/protocol/service_constants.h"
-#include "chrome/common/deprecated/event_sys.h"
-#include "chrome/common/net/gaia/gaia_authenticator.h"
-
-namespace syncable {
-struct DirectoryManagerEvent;
-class DirectoryManager;
-}
-
-namespace browser_sync {
-
-class AuthWatcher;
-class ServerConnectionManager;
-class URLFactory;
-class UserSettings;
-struct ServerConnectionEvent;
-
-struct AuthWatcherEvent {
- enum WhatHappened {
- AUTHENTICATION_ATTEMPT_START,
- AUTHWATCHER_DESTROYED,
- AUTH_RENEWED, // Currently only used in testing.
- AUTH_SUCCEEDED,
- GAIA_AUTH_FAILED,
- SERVICE_USER_NOT_SIGNED_UP,
- SERVICE_AUTH_FAILED,
- SERVICE_CONNECTION_FAILED,
- // Used in a safety check in AuthWatcher::AuthenticateWithToken()
- ILLEGAL_VALUE,
- };
- WhatHappened what_happened;
- const gaia::GaiaAuthenticator::AuthResults* auth_results;
- // use AuthWatcherEvent as its own traits type in hookups.
- typedef AuthWatcherEvent EventType;
- static inline bool IsChannelShutdownEvent(const AuthWatcherEvent& event) {
- return event.what_happened == AUTHWATCHER_DESTROYED;
- }
-
- // Used for AUTH_SUCCEEDED/AUTH_RENEWED notification.
- std::string user_email;
- // May be empty if we're only locally authenticated.
- std::string auth_token;
-
- // How was this auth attempt initiated?
- enum AuthenticationTrigger {
- USER_INITIATED = 0, // default value.
- EXPIRED_CREDENTIALS,
- };
-
- AuthenticationTrigger trigger;
-};
-
-// The mother-class of Authentication for the sync backend. Handles both gaia
-// and sync service authentication via asynchronous Authenticate* methods,
-// raising AuthWatcherEvents on success/failure. The implementation currently
-// runs its own backend thread for the actual auth processing, which means
-// the AuthWatcherEvents can be raised on a different thread than the one that
-// invoked authentication.
-class AuthWatcher : public base::RefCountedThreadSafe<AuthWatcher> {
- friend class AuthWatcherTest;
- FRIEND_TEST_ALL_PREFIXES(AuthWatcherTest, Construction);
- public:
- // Normal progression is local -> gaia -> token.
- enum Status { LOCALLY_AUTHENTICATED, GAIA_AUTHENTICATED, NOT_AUTHENTICATED };
- typedef syncable::DirectoryManagerEvent DirectoryManagerEvent;
- typedef syncable::DirectoryManager DirectoryManager;
-
- AuthWatcher(DirectoryManager* dirman,
- ServerConnectionManager* scm,
- const std::string& user_agent,
- const std::string& service_id,
- const std::string& gaia_url,
- UserSettings* user_settings,
- gaia::GaiaAuthenticator* gaia_auth);
- ~AuthWatcher();
-
- typedef EventChannel<AuthWatcherEvent, Lock> Channel;
-
- inline Channel* channel() const {
- return channel_.get();
- }
-
- // The following 3 flavors of authentication routines are asynchronous and can
- // be called from any thread.
- // If |captcha_value| is specified but |captcha_token| is not, this will
- // attempt authentication using the last observed captcha token out of
- // convenience in the common case so the token doesn't have to be plumbed
- // everywhere.
- void Authenticate(const std::string& email, const std::string& password,
- const std::string& captcha_token, const std::string& captcha_value);
-
- void Authenticate(const std::string& email, const std::string& password,
- bool persist_creds_to_disk) {
- Authenticate(email, password, "", "");
- }
-
- // Use this to update only the token of the current email address.
- void RenewAuthToken(const std::string& updated_token);
-
- // Use this version when you don't need the gaia authentication step because
- // you already have a valid LSID cookie for |gaia_email|.
- void AuthenticateWithLsid(const std::string& lsid);
-
- // Use this version when you don't need the gaia authentication step because
- // you already have a valid token for |gaia_email|.
- void AuthenticateWithToken(const std::string& gaia_email,
- const std::string& auth_token);
-
- // Joins on the backend thread. The AuthWatcher is useless after this and
- // should be destroyed.
- void Shutdown() { auth_backend_thread_.Stop(); }
-
- std::string email() const;
- syncable::DirectoryManager* dirman() const { return dirman_; }
- ServerConnectionManager* scm() const { return scm_; }
- UserSettings* settings() const { return user_settings_; }
- Status status() const { return (Status)status_; }
-
- private:
- void ClearAuthenticationData();
-
- void NotifyAuthChanged(const std::string& email,
- const std::string& auth_token,
- bool renewed);
- void HandleServerConnectionEvent(const ServerConnectionEvent& event);
-
- void SaveUserSettings(const std::string& username,
- const std::string& auth_token);
-
- MessageLoop* message_loop() { return auth_backend_thread_.message_loop(); }
-
- base::MessageLoopProxy* message_loop_proxy() {
- return loop_proxy_;
- }
-
- void DoRenewAuthToken(const std::string& updated_token);
-
- // These two helpers should only be called from the auth function.
- // Called when authentication with gaia succeeds, to save credential info.
- void PersistCredentials();
- // Called when authentication with gaia fails.
- void ProcessGaiaAuthFailure();
-
- // Just checks that the user has at least one local share cache.
- bool AuthenticateLocally(std::string email);
- // Also checks the user's password against stored password hash.
- bool AuthenticateLocally(std::string email, const std::string& password);
-
- // Sets the trigger member of the event and sends the event on channel_.
- void NotifyListeners(AuthWatcherEvent* event);
-
- inline std::string FormatAsEmailAddress(const std::string& email) const {
- std::string mail(email);
- if (email.find('@') == std::string::npos) {
- mail.push_back('@');
- // TODO(chron): Should this be done only at the UI level?
- mail.append(DEFAULT_SIGNIN_DOMAIN);
- }
- return mail;
- }
-
- // A struct to marshal various data across to the auth_backend_thread_ on
- // Authenticate() and AuthenticateWithToken calls.
- struct AuthRequest {
- std::string email;
- std::string password;
- std::string auth_token;
- std::string captcha_token;
- std::string captcha_value;
- bool persist_creds_to_disk;
- AuthWatcherEvent::AuthenticationTrigger trigger;
- };
-
- // The public interface Authenticate methods are proxies to these, which
- // can only be called from |auth_backend_thread_|.
- void DoAuthenticate(const AuthRequest& request);
- void DoAuthenticateWithLsid(const std::string& lsid);
- void DoAuthenticateWithToken(const std::string& email,
- const std::string& auth_token);
-
- // The public HandleServerConnectionEvent method proxies to this method, which
- // can only be called on |auth_backend_thread_|.
- void DoHandleServerConnectionEvent(
- const ServerConnectionEvent& event,
- const std::string& auth_token_snapshot);
-
- scoped_ptr<gaia::GaiaAuthenticator> const gaia_;
- syncable::DirectoryManager* const dirman_;
- ServerConnectionManager* const scm_;
- scoped_ptr<EventListenerHookup> connmgr_hookup_;
- Status status_;
- UserSettings* const user_settings_;
- scoped_ptr<Channel> channel_;
-
- base::Thread auth_backend_thread_;
- scoped_refptr<base::MessageLoopProxy> loop_proxy_;
-
- AuthWatcherEvent::AuthenticationTrigger current_attempt_trigger_;
- DISALLOW_COPY_AND_ASSIGN(AuthWatcher);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
diff --git a/chrome/browser/sync/engine/auth_watcher_unittest.cc b/chrome/browser/sync/engine/auth_watcher_unittest.cc
deleted file mode 100644
index cc840c7..0000000
--- a/chrome/browser/sync/engine/auth_watcher_unittest.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/scoped_ptr.h"
-#include "base/scoped_temp_dir.h"
-#include "base/test/test_file_util.h"
-#include "base/waitable_event.h"
-#include "chrome/browser/password_manager/encryptor.h"
-#include "chrome/browser/sync/engine/auth_watcher.h"
-#include "chrome/browser/sync/engine/syncer_thread.h"
-#include "chrome/browser/sync/util/user_settings.h"
-#include "chrome/common/deprecated/event_sys-inl.h"
-#include "chrome/common/net/http_return.h"
-#include "chrome/common/net/gaia/gaia_authenticator.h"
-#include "chrome/test/sync/engine/mock_connection_manager.h"
-#include "chrome/test/sync/engine/test_directory_setter_upper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-static FilePath::CharType kUserSettingsDB[] =
- FILE_PATH_LITERAL("Settings.sqlite3");
-static const char* kTestUserAgent = "useragent";
-static const char* kTestServiceId = "serviceid";
-static const char* kTestGaiaURL = "http://gaia_url";
-static const char* kUserDisplayName = "Mr. Auth Watcher";
-static const char* kUserDisplayEmail = "authwatcherdisplay@gmail.com";
-static const char* kTestEmail = "authwatchertest@gmail.com";
-static const char* kWrongPassword = "wrongpassword";
-static const char* kCorrectPassword = "correctpassword";
-static const char* kValidSID = "validSID";
-static const char* kValidLSID = "validLSID";
-static const char* kInvalidAuthToken = "invalidAuthToken";
-static const char* kValidAuthToken = "validAuthToken";
-
-namespace browser_sync {
-
-class GaiaAuthMockForAuthWatcher : public gaia::GaiaAuthenticator {
- public:
- GaiaAuthMockForAuthWatcher() : GaiaAuthenticator(
- kTestUserAgent, kTestServiceId, kTestGaiaURL),
- use_bad_auth_token_(false) {}
- virtual ~GaiaAuthMockForAuthWatcher() {}
-
- virtual int GetBackoffDelaySeconds(
- int current_backoff_delay) {
- return SyncerThread::GetRecommendedDelaySeconds(current_backoff_delay);
- }
-
- void SendBadAuthTokenForNextRequest() { use_bad_auth_token_ = true; }
-
- std::string renewed_token() {
- return renewed_token_;
- }
-
- protected:
- bool PerformGaiaRequest(const AuthParams& params, AuthResults* results) {
- if (params.password == kWrongPassword) {
- results->auth_error = gaia::BadAuthentication;
- return false;
- }
- if (params.password == kCorrectPassword) {
- results->sid = kValidSID;
- results->lsid = kValidLSID;
- results->auth_token = kValidAuthToken;
- }
- if (use_bad_auth_token_) {
- results->auth_token = kInvalidAuthToken;
- use_bad_auth_token_ = false;
- }
- return true;
- }
-
- void RenewAuthToken(const std::string& auth_token) {
- renewed_token_ = auth_token;
- }
-
- private:
- // Whether we should send an invalid auth token on the next request.
- bool use_bad_auth_token_;
- std::string renewed_token_;
-};
-
-class AuthWatcherTest : public testing::Test {
- public:
- AuthWatcherTest() : metadb_(kUserDisplayEmail),
- consumer_ready(false, false),
- event_produced(false, false),
- last_event_reason_(AuthWatcherEvent::ILLEGAL_VALUE) {}
- virtual void SetUp() {
-#if defined(OS_MACOSX)
- // Need to mock the Keychain for unit tests on Mac to avoid possible
- // blocking UI. |SetAuthTokenForService| uses Encryptor.
- Encryptor::UseMockKeychain(true);
-#endif
- metadb_.SetUp();
- connection_.reset(new MockConnectionManager(metadb_.manager(),
- metadb_.name()));
- // Mock out data that would normally be sent back from a server.
- connection()->SetAuthenticationResponseInfo(kValidAuthToken,
- kUserDisplayName, kUserDisplayEmail, "ID");
- user_settings_.reset(new UserSettings());
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- FilePath user_settings_path = temp_dir_.path().Append(kUserSettingsDB);
- user_settings_->Init(user_settings_path);
- gaia_auth_ = new GaiaAuthMockForAuthWatcher();
- auth_watcher_ = new AuthWatcher(metadb_.manager(), connection_.get(),
- kTestUserAgent, kTestServiceId, kTestGaiaURL,
- user_settings_.get(), gaia_auth_);
- authwatcher_hookup_.reset(NewEventListenerHookup(auth_watcher_->channel(),
- this, &AuthWatcherTest::HandleAuthWatcherEvent));
- }
-
- virtual void TearDown() {
- metadb_.TearDown();
- auth_watcher_->Shutdown();
- EXPECT_FALSE(auth_watcher()->message_loop());
- }
-
- void HandleAuthWatcherEvent(const AuthWatcherEvent& event) {
- if (event.what_happened == AuthWatcherEvent::AUTHWATCHER_DESTROYED)
- return;
- consumer_ready.Wait(); // Block progress until the test is ready.
-
- last_event_reason_ = event.what_happened;
- if (event.what_happened == AuthWatcherEvent::AUTH_SUCCEEDED)
- user_email_ = event.user_email;
-
- event_produced.Signal();
- }
-
- AuthWatcherEvent::WhatHappened ConsumeNextEvent() {
- consumer_ready.Signal();
- event_produced.Wait();
- return last_event_reason_;
- }
-
- AuthWatcher* auth_watcher() { return auth_watcher_.get(); }
- MockConnectionManager* connection() { return connection_.get(); }
- GaiaAuthMockForAuthWatcher* gaia_auth() { return gaia_auth_; }
- const std::string& user_email() { return user_email_; }
-
- private:
- // Responsible for creating / deleting a temp dir containing user settings DB.
- ScopedTempDir temp_dir_;
-
- // The event listener hookup registered for HandleAuthWatcherEvent.
- scoped_ptr<EventListenerHookup> authwatcher_hookup_;
-
- // The sync engine pieces necessary to run an AuthWatcher.
- TriggeredOpenTestDirectorySetterUpper metadb_;
- scoped_ptr<MockConnectionManager> connection_;
- scoped_ptr<UserSettings> user_settings_;
- GaiaAuthMockForAuthWatcher* gaia_auth_; // Owned by auth_watcher_.
- scoped_refptr<AuthWatcher> auth_watcher_;
-
- // This is used to block the AuthWatcherThread when it raises events until we
- // are ready to read the event. It is not a manual-reset event, so it goes
- // straight back to non-signaled after one thread (the main thread) is
- // signaled (or "consumes" the signaled state).
- base::WaitableEvent consumer_ready;
-
- // This is signaled by the AuthWatcherThread after it sets last_event_reason_
- // and possibly user_email_ for us to read.
- base::WaitableEvent event_produced;
-
- // The 'WhatHappened' value from the last AuthWatcherEvent we handled.
- AuthWatcherEvent::WhatHappened last_event_reason_;
-
- // Set when we receive an AUTH_SUCCEEDED event.
- std::string user_email_;
-
- DISALLOW_COPY_AND_ASSIGN(AuthWatcherTest);
-};
-
-TEST_F(AuthWatcherTest, Construction) {
- EXPECT_TRUE(auth_watcher()->message_loop());
- EXPECT_EQ("SyncEngine_AuthWatcherThread",
- auth_watcher()->message_loop()->thread_name());
- EXPECT_TRUE(auth_watcher()->auth_backend_thread_.IsRunning());
- EXPECT_EQ(AuthWatcher::NOT_AUTHENTICATED, auth_watcher()->status());
-}
-
-TEST_F(AuthWatcherTest, AuthenticateGaiaAuthFailure) {
- auth_watcher()->Authenticate(kTestEmail, kWrongPassword,
- std::string(), // captcha_token
- std::string()); // captcha_value
-
- EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent());
- EXPECT_EQ(AuthWatcherEvent::GAIA_AUTH_FAILED, ConsumeNextEvent());
-}
-
-TEST_F(AuthWatcherTest, AuthenticateBadAuthToken) {
- gaia_auth()->SendBadAuthTokenForNextRequest();
- auth_watcher()->Authenticate(kTestEmail, kCorrectPassword, std::string(),
- std::string());
- EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent());
- EXPECT_EQ(AuthWatcherEvent::SERVICE_AUTH_FAILED, ConsumeNextEvent());
-}
-
-TEST_F(AuthWatcherTest, AuthenticateSuccess) {
- auth_watcher()->Authenticate(kTestEmail, kCorrectPassword, std::string(),
- std::string());
- EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent());
- EXPECT_EQ(AuthWatcherEvent::AUTH_SUCCEEDED, ConsumeNextEvent());
-
- // The server responds with a different email than what we used in the call
- // to Authenticate, and the AuthWatcher should have told us about.
- EXPECT_EQ(kUserDisplayEmail, user_email());
-}
-
-TEST_F(AuthWatcherTest, AuthenticateWithTokenBadAuthToken) {
- auth_watcher()->AuthenticateWithToken(kTestEmail, kInvalidAuthToken);
- EXPECT_EQ(AuthWatcherEvent::SERVICE_AUTH_FAILED, ConsumeNextEvent());
-}
-
-TEST_F(AuthWatcherTest, AuthenticateWithTokenSuccess) {
- auth_watcher()->AuthenticateWithToken(kTestEmail, kValidAuthToken);
- EXPECT_EQ(AuthWatcherEvent::AUTH_SUCCEEDED, ConsumeNextEvent());
- EXPECT_EQ(kUserDisplayEmail, user_email());
-}
-
-// Just check that the thread task was properly issued.
-TEST_F(AuthWatcherTest, RenewAuthToken) {
- auth_watcher()->Authenticate(kTestEmail, kCorrectPassword, std::string(),
- std::string());
- EXPECT_EQ(AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START, ConsumeNextEvent());
- EXPECT_EQ(AuthWatcherEvent::AUTH_SUCCEEDED, ConsumeNextEvent());
-
- auth_watcher()->RenewAuthToken("updated_token");
- EXPECT_EQ(AuthWatcherEvent::AUTH_RENEWED, ConsumeNextEvent());
- EXPECT_EQ(gaia_auth()->renewed_token(), "updated_token");
- EXPECT_EQ(connection()->auth_token(), "updated_token");
-}
-
-} // namespace browser_sync
diff --git a/chrome/browser/sync/engine/authenticator.cc b/chrome/browser/sync/engine/authenticator.cc
deleted file mode 100644
index eec7af3..0000000
--- a/chrome/browser/sync/engine/authenticator.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/engine/authenticator.h"
-
-#include "chrome/browser/sync/engine/net/server_connection_manager.h"
-#include "chrome/browser/sync/engine/syncproto.h"
-#include "chrome/browser/sync/protocol/sync.pb.h"
-#include "chrome/browser/sync/util/user_settings.h"
-#include "chrome/common/deprecated/event_sys-inl.h"
-#include "chrome/common/net/gaia/gaia_authenticator.h"
-
-namespace browser_sync {
-
-using std::string;
-
-Authenticator::Authenticator(ServerConnectionManager* manager,
- UserSettings* settings)
- : server_connection_manager_(manager), settings_(settings) {
-}
-
-Authenticator::Authenticator(ServerConnectionManager* manager)
- : server_connection_manager_(manager), settings_(NULL) {
-}
-
-Authenticator::AuthenticationResult Authenticator::Authenticate() {
- // TODO(sync): Pull and work with saved credentials.
- return NO_SAVED_CREDENTIALS;
-}
-
-Authenticator::AuthenticationResult Authenticator::Authenticate(
- string username, string password) {
- // TODO(sync): need to figure out if this routine is used anywhere other
- // than the test code.
- gaia::GaiaAuthenticator auth_service("ChromiumBrowser", "chromiumsync",
- "https://www.google.com:443/accounts/ClientLogin");
- auth_service.set_message_loop(MessageLoop::current());
- if (!auth_service.Authenticate(username, password)) {
- return UNSPECIFIC_ERROR_RETURN;
- }
- CHECK(!auth_service.auth_token().empty());
- return AuthenticateToken(auth_service.auth_token());
-}
-
-COMPILE_ASSERT(sync_pb::ClientToServerResponse::ErrorType_MAX == 7,
- client_to_server_response_errors_changed);
-
-Authenticator::AuthenticationResult Authenticator::HandleSuccessfulTokenRequest(
- const sync_pb::UserIdentification* user) {
- display_email_ = user->has_email() ? user->email() : "";
- display_name_ = user->has_display_name() ? user->display_name() : "";
- obfuscated_id_ = user->has_obfuscated_id() ? user->obfuscated_id() : "";
- return SUCCESS;
-}
-
-Authenticator::AuthenticationResult Authenticator::AuthenticateToken(
- string auth_token) {
- ClientToServerMessage client_to_server_message;
- // Used to be required for all requests.
- client_to_server_message.set_share("");
- client_to_server_message.set_message_contents(
- ClientToServerMessage::AUTHENTICATE);
-
- string tx, rx;
- client_to_server_message.SerializeToString(&tx);
- HttpResponse http_response;
-
- ServerConnectionManager::PostBufferParams params =
- { tx, &rx, &http_response };
- ScopedServerStatusWatcher watch(server_connection_manager_, &http_response);
- if (!server_connection_manager_->PostBufferWithAuth(&params, auth_token,
- &watch)) {
- LOG(WARNING) << "Error posting from authenticator:" << http_response;
- return SERVICE_DOWN;
- }
- sync_pb::ClientToServerResponse response;
- if (!response.ParseFromString(rx))
- return CORRUPT_SERVER_RESPONSE;
-
- switch (response.error_code()) {
- case sync_pb::ClientToServerResponse::SUCCESS:
- if (response.has_authenticate() && response.authenticate().has_user())
- return HandleSuccessfulTokenRequest(&response.authenticate().user());
- // TODO:(sync) make this CORRUPT_SERVER_RESPONSE when all servers are
- // returning user identification at login time.
- return SUCCESS;
- case sync_pb::ClientToServerResponse::USER_NOT_ACTIVATED:
- return USER_NOT_ACTIVATED;
- case sync_pb::ClientToServerResponse::AUTH_INVALID:
- case sync_pb::ClientToServerResponse::AUTH_EXPIRED:
- // TODO(tim): This is an egregious layering violation (bug 35060).
- http_response.server_status = HttpResponse::SYNC_AUTH_ERROR;
- return BAD_AUTH_TOKEN;
- // should never happen (no birthday in this request).
- case sync_pb::ClientToServerResponse::NOT_MY_BIRTHDAY:
- // should never happen (auth isn't throttled).
- case sync_pb::ClientToServerResponse::THROTTLED:
- // should never happen (only for stores).
- case sync_pb::ClientToServerResponse::ACCESS_DENIED:
- // should never happen (only sent on get updates / commit)
- case sync_pb::ClientToServerResponse::CLEAR_PENDING:
- default:
- LOG(ERROR) << "Corrupt Server packet received by auth, error code " <<
- response.error_code();
- return CORRUPT_SERVER_RESPONSE;
- }
-}
-
-} // namespace browser_sync
diff --git a/chrome/browser/sync/engine/authenticator.h b/chrome/browser/sync/engine/authenticator.h
deleted file mode 100644
index 1abca3c..0000000
--- a/chrome/browser/sync/engine/authenticator.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// The authenticator is a cross-platform class that handles authentication for
-// the sync client.
-//
-// Current State:
-// The authenticator is currently only used to authenticate tokens using the
-// newer protocol buffer request.
-
-#ifndef CHROME_BROWSER_SYNC_ENGINE_AUTHENTICATOR_H_
-#define CHROME_BROWSER_SYNC_ENGINE_AUTHENTICATOR_H_
-#pragma once
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/port.h"
-
-namespace sync_pb {
-class UserIdentification;
-}
-
-namespace browser_sync {
-
-class ServerConnectionManager;
-class UserSettings;
-
-class Authenticator {
- public:
- // Single return enum.
- enum AuthenticationResult {
- SUCCESS = 0,
- // We couldn't log on because we don't have saved credentials.
- NO_SAVED_CREDENTIALS,
- // We can't reach auth server (i.e. we're offline or server's down).
- NOT_CONNECTED,
- // Server's up, but we're down.
- SERVICE_DOWN,
- // We contacted the server, but the response didn't make sense.
- CORRUPT_SERVER_RESPONSE,
- // Bad username/password.
- BAD_CREDENTIALS,
- // Credentials are fine, but the user hasn't signed up.
- USER_NOT_ACTIVATED,
-
- // Return values for internal use.
-
- // We will never return this to the user unless they call AuthenticateToken
- // directly. Other auth functions retry and then return
- // CORRUPT_SERVER_RESPONSE.
- // TODO(sync): Implement retries.
- BAD_AUTH_TOKEN,
- // We should never return this, it's a placeholder during development.
- // TODO(sync): Remove this
- UNSPECIFIC_ERROR_RETURN,
- };
-
- // Constructor. This class will keep the connection authenticated.
- // TODO(sync): Make it work as described.
- // TODO(sync): Require a UI callback mechanism.
- Authenticator(ServerConnectionManager* manager, UserSettings* settings);
-
- // Constructor for a simple authenticator used for programmatic login from
- // test programs.
- explicit Authenticator(ServerConnectionManager* manager);
-
- // This version of Authenticate tries to use saved credentials, if we have
- // any.
- AuthenticationResult Authenticate();
-
- // We save the username and password in memory (if given) so we
- // can refresh the long-lived auth token if it expires.
- // Also we save a 10-bit hash of the password to allow offline login.
- AuthenticationResult Authenticate(std::string username, std::string password);
-
- // A version of the auth token to authenticate cookie portion of
- // authentication. It uses the new proto buffer based call instead of the HTTP
- // GET based one we currently use.
- // Can return one of SUCCESS, SERVICE_DOWN, CORRUPT_SERVER_RESPONSE,
- // USER_NOT_ACTIVATED or BAD_AUTH_TOKEN. See above for the meaning of these
- // values.
- // TODO(sync): Make this function private when we're done.
- AuthenticationResult AuthenticateToken(std::string auth_token);
-
- const char* display_email() const { return display_email_.c_str(); }
- const char* display_name() const { return display_name_.c_str(); }
- private:
- // Stores the information in the UserIdentification returned from the server.
- AuthenticationResult HandleSuccessfulTokenRequest(
- const sync_pb::UserIdentification* user);
- // The server connection manager that we're looking after.
- ServerConnectionManager* server_connection_manager_;
- // Returns SUCCESS or the value that should be returned to the user.
- std::string display_email_;
- std::string display_name_;
- std::string obfuscated_id_;
- UserSettings* const settings_;
- DISALLOW_COPY_AND_ASSIGN(Authenticator);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_ENGINE_AUTHENTICATOR_H_
diff --git a/chrome/browser/sync/engine/net/server_connection_manager.cc b/chrome/browser/sync/engine/net/server_connection_manager.cc
index 4953836..6d35811 100644
--- a/chrome/browser/sync/engine/net/server_connection_manager.cc
+++ b/chrome/browser/sync/engine/net/server_connection_manager.cc
@@ -135,11 +135,9 @@ ServerConnectionManager::ServerConnectionManager(
const string& server,
int port,
bool use_ssl,
- const string& user_agent,
- const string& client_id)
+ const string& user_agent)
: sync_server_(server),
sync_server_port_(port),
- client_id_(client_id),
user_agent_(user_agent),
use_ssl_(use_ssl),
proto_sync_path_(kSyncServerSyncPath),
@@ -163,7 +161,6 @@ void ServerConnectionManager::NotifyStatusChanged() {
channel_->NotifyListeners(event);
}
-// Uses currently set auth token. Set by AuthWatcher.
bool ServerConnectionManager::PostBufferWithCachedAuth(
const PostBufferParams* params, ScopedServerStatusWatcher* watcher) {
string path =
@@ -171,14 +168,6 @@ bool ServerConnectionManager::PostBufferWithCachedAuth(
return PostBufferToPath(params, path, auth_token(), watcher);
}
-bool ServerConnectionManager::PostBufferWithAuth(const PostBufferParams* params,
- const string& auth_token, ScopedServerStatusWatcher* watcher) {
- string path = MakeSyncServerPath(proto_sync_path(),
- MakeSyncQueryString(client_id_));
-
- return PostBufferToPath(params, path, auth_token, watcher);
-}
-
bool ServerConnectionManager::PostBufferToPath(const PostBufferParams* params,
const string& path, const string& auth_token,
ScopedServerStatusWatcher* watcher) {
diff --git a/chrome/browser/sync/engine/net/server_connection_manager.h b/chrome/browser/sync/engine/net/server_connection_manager.h
index 602116a..526dc8e 100644
--- a/chrome/browser/sync/engine/net/server_connection_manager.h
+++ b/chrome/browser/sync/engine/net/server_connection_manager.h
@@ -213,8 +213,7 @@ class ServerConnectionManager {
ServerConnectionManager(const std::string& server,
int port,
bool use_ssl,
- const std::string& user_agent,
- const std::string& client_id);
+ const std::string& user_agent);
virtual ~ServerConnectionManager();
@@ -225,14 +224,6 @@ class ServerConnectionManager {
virtual bool PostBufferWithCachedAuth(const PostBufferParams* params,
ScopedServerStatusWatcher* watcher);
- // POSTS buffer_in and reads a response into buffer_out. Add a specific auth
- // token to http headers.
- //
- // Returns true if executed successfully.
- virtual bool PostBufferWithAuth(const PostBufferParams* params,
- const std::string& auth_token,
- ScopedServerStatusWatcher* watcher);
-
// Checks the time on the server. Returns false if the request failed. |time|
// is an out parameter that stores the value returned from the server.
virtual bool CheckTime(int32* out_time);
@@ -289,6 +280,11 @@ class ServerConnectionManager {
return NULL; // For testing.
};
+ void set_client_id(const std::string& client_id) {
+ DCHECK(client_id_.empty());
+ client_id_.assign(client_id);
+ }
+
void set_auth_token(const std::string& auth_token) {
// TODO(chron): Consider adding a message loop check here.
AutoLock lock(auth_token_mutex_);
@@ -333,7 +329,7 @@ class ServerConnectionManager {
int sync_server_port_;
// The unique id of the user's client.
- const std::string client_id_;
+ std::string client_id_;
// The user-agent string for HTTP.
std::string user_agent_;
diff --git a/chrome/browser/sync/engine/net/syncapi_server_connection_manager.h b/chrome/browser/sync/engine/net/syncapi_server_connection_manager.h
index 67424b9..4108f9a 100644
--- a/chrome/browser/sync/engine/net/syncapi_server_connection_manager.h
+++ b/chrome/browser/sync/engine/net/syncapi_server_connection_manager.h
@@ -51,10 +51,8 @@ class SyncAPIServerConnectionManager
int port,
bool use_ssl,
const std::string& client_version,
- const std::string& client_id,
HttpPostProviderFactory* factory)
- : ServerConnectionManager(server, port, use_ssl, client_version,
- client_id),
+ : ServerConnectionManager(server, port, use_ssl, client_version),
post_provider_factory_(factory) {
DCHECK(post_provider_factory_.get());
}
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index 00d1c4f..15e0e8d 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -25,7 +25,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/sync/sync_constants.h"
#include "chrome/browser/sync/engine/all_status.h"
-#include "chrome/browser/sync/engine/auth_watcher.h"
#include "chrome/browser/sync/engine/change_reorder_buffer.h"
#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/engine/net/server_connection_manager.h"
@@ -49,7 +48,6 @@
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/syncable/syncable.h"
#include "chrome/browser/sync/util/crypto_helpers.h"
-#include "chrome/browser/sync/util/user_settings.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/deprecated/event_sys.h"
#include "chrome/common/net/gaia/gaia_authenticator.h"
@@ -61,17 +59,15 @@
using browser_sync::AllStatus;
using browser_sync::AllStatusEvent;
-using browser_sync::AuthWatcher;
-using browser_sync::AuthWatcherEvent;
using browser_sync::Cryptographer;
using browser_sync::KeyParams;
using browser_sync::ModelSafeRoutingInfo;
using browser_sync::ModelSafeWorker;
using browser_sync::ModelSafeWorkerRegistrar;
+using browser_sync::ServerConnectionEvent;
using browser_sync::Syncer;
using browser_sync::SyncerEvent;
using browser_sync::SyncerThread;
-using browser_sync::UserSettings;
using browser_sync::kNigoriTag;
using browser_sync::sessions::SyncSessionContext;
using notifier::TalkMediator;
@@ -910,7 +906,6 @@ class SyncManager::SyncInternal
explicit SyncInternal(SyncManager* sync_manager)
: core_message_loop_(NULL),
observer_(NULL),
- auth_problem_(AuthError::NONE),
sync_manager_(sync_manager),
registrar_(NULL),
notification_pending_(false),
@@ -929,40 +924,25 @@ class SyncManager::SyncInternal
bool Init(const FilePath& database_location,
const std::string& sync_server_and_path,
int port,
- const char* gaia_service_id,
- const char* gaia_source,
bool use_ssl,
HttpPostProviderFactory* post_factory,
- HttpPostProviderFactory* auth_post_factory,
ModelSafeWorkerRegistrar* model_safe_worker_registrar,
- bool attempt_last_user_authentication,
- bool invalidate_last_user_auth_token,
- bool invalidate_xmpp_auth_token,
const char* user_agent,
- const std::string& lsid,
+ const SyncCredentials& credentials,
const bool use_chrome_async_socket,
const bool try_ssltcp_first,
browser_sync::NotificationMethod notification_method,
const std::string& restored_key_for_bootstrapping);
- // Tell sync engine to submit credentials to GAIA for verification.
- // Successful GAIA authentication will kick off the following chain of events:
- // 1. Cause sync engine to open the syncer database.
- // 2. Trigger the AuthWatcher to create a Syncer for the directory and call
- // SyncerThread::SyncDirectory; the SyncerThread will block until (4).
- // 3. Tell the ServerConnectionManager to pass the newly received GAIA auth
- // token to a sync server to obtain a sync token.
- // 4. On receipt of this token, the ServerConnectionManager broadcasts
- // a server-reachable event, which will unblock the SyncerThread.
- // 5. When StartSyncing is called, the Syncer will begin the sync process, by
- // downloading from or uploading to the server.
- //
- // If authentication fails, an event will be broadcast all the way up to
- // the SyncManager::Observer. It may, in turn, decide to try again with new
- // credentials. Calling this method again is the appropriate course of action
- // to "retry".
- void Authenticate(const std::string& username, const std::string& password,
- const std::string& captcha);
+
+ // Sign into sync with given credentials.
+ // We do not verify the tokens given. After this call, the tokens are set
+ // and the sync DB is open. True if successful, false if something
+ // went wrong.
+ bool SignIn(const SyncCredentials& credentials);
+
+ // Update tokens that we're using in Sync. Email must stay the same.
+ void UpdateCredentials(const SyncCredentials& credentials);
// Tell the sync engine to start the syncing process.
void StartSyncing();
@@ -987,20 +967,17 @@ class SyncManager::SyncInternal
// This listener is called by the syncer channel for all syncer events.
virtual void HandleChannelEvent(const SyncerEvent& event);
- // We have a direct hookup to the authwatcher to be notified for auth failures
- // on startup, to serve our UI needs.
- void HandleAuthWatcherEvent(const AuthWatcherEvent& event);
+ // Listens for notifications from the ServerConnectionManager
+ void HandleServerConnectionEvent(const ServerConnectionEvent& event);
- // Listen here for directory opened events.
- void HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event);
+ // Open the directory named with username_for_share
+ bool OpenDirectory();
// Login to the talk mediator with the given credentials.
void TalkMediatorLogin(
const std::string& email, const std::string& token);
// TalkMediator::Delegate implementation.
-
virtual void OnNotificationStateChange(
bool notifications_enabled);
@@ -1016,14 +993,13 @@ class SyncManager::SyncInternal
}
SyncerThread* syncer_thread() { return syncer_thread_.get(); }
TalkMediator* talk_mediator() { return talk_mediator_.get(); }
- AuthWatcher* auth_watcher() { return auth_watcher_.get(); }
void set_observer(SyncManager::Observer* observer) { observer_ = observer; }
UserShare* GetUserShare() { return &share_; }
// Return the currently active (validated) username for use with syncable
// types.
const std::string& username_for_share() const {
- return share_.authenticated_name;
+ return share_.name;
}
// Note about SyncManager::Status implementation: Status is a trimmed
@@ -1078,21 +1054,6 @@ class SyncManager::SyncInternal
}
private:
- // Try to authenticate using a LSID cookie.
- void AuthenticateWithLsid(const std::string& lsid);
-
- // Try to authenticate using persisted credentials from a previous successful
- // authentication. If no such credentials exist, calls OnAuthError on the
- // client to collect credentials. Otherwise, there exist local credentials
- // that were once used for a successful auth, so we'll try to re-use these.
- // Failure of that attempt will be communicated as normal using OnAuthError.
- // Since this entry point will bypass normal GAIA authentication and try to
- // authenticate directly with the sync service using a cached token,
- // authentication failure will generally occur due to expired credentials, or
- // possibly because of a password change.
- bool AuthenticateForUser(const std::string& username,
- const std::string& auth_token);
-
// Helper to call OnAuthError when no authentication credentials are
// available.
void RaiseAuthNeededEvent();
@@ -1171,10 +1132,6 @@ class SyncManager::SyncInternal
// constructing any transaction type.
UserShare share_;
- // A wrapper around a sqlite store used for caching authentication data,
- // last user information, current sync-related URLs, and more.
- scoped_ptr<UserSettings> user_settings_;
-
MessageLoop* core_message_loop_;
// Observer registered via SetObserver/RemoveObserver.
@@ -1195,13 +1152,6 @@ class SyncManager::SyncInternal
// sync components.
AllStatus allstatus_;
- // AuthWatcher kicks off the authentication process and follows it through
- // phase 1 (GAIA) to phase 2 (sync engine). As part of this work it determines
- // the initial connectivity and causes the server connection event to be
- // broadcast, which signals the syncer thread to start syncing.
- // It has a heavy duty constructor requiring boilerplate so we heap allocate.
- scoped_refptr<AuthWatcher> auth_watcher_;
-
// Each element of this array is a store of change records produced by
// HandleChangeEvent during the CALCULATE_CHANGES step. The changes are
// segregated by model type, and are stored here to be processed and
@@ -1213,20 +1163,12 @@ class SyncManager::SyncInternal
scoped_ptr<browser_sync::ChannelHookup<syncable::DirectoryChangeEvent> >
dir_change_hookup_;
+ // Event listener hookup for the ServerConnectionManager.
+ scoped_ptr<EventListenerHookup> connection_manager_hookup_;
+
// The event listener hookup registered for HandleSyncerEvent.
scoped_ptr<browser_sync::ChannelHookup<SyncerEvent> > syncer_event_;
- // The event listener hookup registered for HandleAuthWatcherEvent.
- scoped_ptr<EventListenerHookup> authwatcher_hookup_;
-
- // The event listener hookup registered for the DirectoryManager (OPENED).
- scoped_ptr<EventListenerHookup> directory_manager_hookup_;
-
- // Our cache of a recent authentication problem. If no authentication problem
- // occurred, or if the last problem encountered has been cleared (by a
- // subsequent AuthWatcherEvent), this is set to NONE.
- AuthError::State auth_problem_;
-
// The sync dir_manager to which we belong.
SyncManager* const sync_manager_;
@@ -1261,17 +1203,11 @@ SyncManager::SyncManager() {
bool SyncManager::Init(const FilePath& database_location,
const char* sync_server_and_path,
int sync_server_port,
- const char* gaia_service_id,
- const char* gaia_source,
bool use_ssl,
HttpPostProviderFactory* post_factory,
- HttpPostProviderFactory* auth_post_factory,
ModelSafeWorkerRegistrar* registrar,
- bool attempt_last_user_authentication,
- bool invalidate_last_user_auth_token,
- bool invalidate_xmpp_auth_token,
const char* user_agent,
- const char* lsid,
+ const SyncCredentials& credentials,
bool use_chrome_async_socket,
bool try_ssltcp_first,
browser_sync::NotificationMethod notification_method,
@@ -1282,29 +1218,22 @@ bool SyncManager::Init(const FilePath& database_location,
return data_->Init(database_location,
server_string,
sync_server_port,
- gaia_service_id,
- gaia_source,
use_ssl,
post_factory,
- auth_post_factory,
registrar,
- attempt_last_user_authentication,
- invalidate_last_user_auth_token,
- invalidate_xmpp_auth_token,
user_agent,
- lsid,
+ credentials,
use_chrome_async_socket,
try_ssltcp_first,
notification_method,
restored_key_for_bootstrapping);
}
-void SyncManager::Authenticate(const char* username, const char* password,
- const char* captcha) {
- data_->Authenticate(std::string(username), std::string(password),
- std::string(captcha));
+void SyncManager::UpdateCredentials(const SyncCredentials& credentials) {
+ data_->UpdateCredentials(credentials);
}
+
bool SyncManager::InitialSyncEndedForAllEnabledTypes() {
return data_->InitialSyncEndedForAllEnabledTypes();
}
@@ -1329,6 +1258,7 @@ void SyncManager::RequestNudge() {
data_->syncer_thread()->NudgeSyncer(0, SyncerThread::kLocal);
}
+// TODO(chron): Don't need to plumb this so deep.
const std::string& SyncManager::GetAuthenticatedUsername() {
DCHECK(data_);
return data_->username_for_share();
@@ -1338,17 +1268,11 @@ bool SyncManager::SyncInternal::Init(
const FilePath& database_location,
const std::string& sync_server_and_path,
int port,
- const char* gaia_service_id,
- const char* gaia_source,
bool use_ssl,
HttpPostProviderFactory* post_factory,
- HttpPostProviderFactory* auth_post_factory,
ModelSafeWorkerRegistrar* model_safe_worker_registrar,
- bool attempt_last_user_authentication,
- bool invalidate_last_user_auth_token,
- bool invalidate_xmpp_auth_token,
const char* user_agent,
- const std::string& lsid,
+ const SyncCredentials& credentials,
bool use_chrome_async_socket,
bool try_ssltcp_first,
browser_sync::NotificationMethod notification_method,
@@ -1359,32 +1283,16 @@ bool SyncManager::SyncInternal::Init(
core_message_loop_ = MessageLoop::current();
DCHECK(core_message_loop_);
notification_method_ = notification_method;
- // Set up UserSettings, creating the db if necessary. We need this to
- // instantiate a URLFactory to give to the Syncer.
- FilePath settings_db_file =
- database_location.Append(FilePath(kBookmarkSyncUserSettingsDatabase));
- user_settings_.reset(new UserSettings());
- if (!user_settings_->Init(settings_db_file))
- return false;
-
registrar_ = model_safe_worker_registrar;
- LOG(INFO) << "Initialized sync user settings. Starting DirectoryManager.";
-
share_.dir_manager.reset(new DirectoryManager(database_location));
- directory_manager_hookup_.reset(NewEventListenerHookup(
- share_.dir_manager->channel(), this,
- &SyncInternal::HandleDirectoryManagerEvent));
- share_.dir_manager->cryptographer()->Bootstrap(
- restored_key_for_bootstrapping);
- string client_id = user_settings_->GetClientId();
connection_manager_.reset(new SyncAPIServerConnectionManager(
- sync_server_and_path, port, use_ssl, user_agent, client_id,
- post_factory));
+ sync_server_and_path, port, use_ssl, user_agent, post_factory));
- // Watch various objects for aggregated status.
- allstatus_.WatchConnectionManager(connection_manager());
+ connection_manager_hookup_.reset(
+ NewEventListenerHookup(connection_manager()->channel(), this,
+ &SyncManager::SyncInternal::HandleServerConnectionEvent));
net::NetworkChangeNotifier::AddObserver(this);
// TODO(akalin): CheckServerReachable() can block, which may cause jank if we
@@ -1404,7 +1312,7 @@ bool SyncManager::SyncInternal::Init(
const bool kInitializeSsl = true;
const bool kConnectImmediately = false;
talk_mediator_.reset(new TalkMediatorImpl(mediator_thread, kInitializeSsl,
- kConnectImmediately, invalidate_xmpp_auth_token));
+ kConnectImmediately, false));
if (notification_method != browser_sync::NOTIFICATION_LEGACY &&
notification_method != browser_sync::NOTIFICATION_SERVER) {
if (notification_method == browser_sync::NOTIFICATION_TRANSITIONAL) {
@@ -1417,30 +1325,11 @@ bool SyncManager::SyncInternal::Init(
// Listen to TalkMediator events ourselves
talk_mediator_->SetDelegate(this);
- std::string gaia_url = gaia::kGaiaUrl;
- const char* service_id = gaia_service_id ?
- gaia_service_id : SYNC_SERVICE_NAME;
-
- BridgedGaiaAuthenticator* gaia_auth = new BridgedGaiaAuthenticator(
- gaia_source, service_id, gaia_url, auth_post_factory);
-
- LOG(INFO) << "Sync is bringing up authwatcher and SyncSessionContext.";
-
- auth_watcher_ = new AuthWatcher(dir_manager(),
- connection_manager(),
- gaia_source,
- service_id,
- gaia_url,
- user_settings_.get(),
- gaia_auth);
-
- authwatcher_hookup_.reset(NewEventListenerHookup(auth_watcher_->channel(),
- this, &SyncInternal::HandleAuthWatcherEvent));
+ LOG(INFO) << "Sync is bringing up SyncSessionContext.";
// Build a SyncSessionContext and store the worker in it.
SyncSessionContext* context = new SyncSessionContext(
- connection_manager_.get(), auth_watcher(),
- dir_manager(), model_safe_worker_registrar);
+ connection_manager_.get(), dir_manager(), model_safe_worker_registrar);
// The SyncerThread takes ownership of |context|.
syncer_thread_ = new SyncerThread(context);
@@ -1449,22 +1338,7 @@ bool SyncManager::SyncInternal::Init(
// Subscribe to the syncer thread's channel.
syncer_event_.reset(syncer_thread()->relay_channel()->AddObserver(this));
- bool attempting_auth = false;
- std::string username, auth_token;
- if (attempt_last_user_authentication &&
- auth_watcher()->settings()->GetLastUserAndServiceToken(
- SYNC_SERVICE_NAME, &username, &auth_token)) {
- if (invalidate_last_user_auth_token) {
- auth_token += "bogus";
- }
- attempting_auth = AuthenticateForUser(username, auth_token);
- } else if (!lsid.empty()) {
- attempting_auth = true;
- AuthenticateWithLsid(lsid);
- }
- if (attempt_last_user_authentication && !attempting_auth)
- RaiseAuthNeededEvent();
- return true;
+ return SignIn(credentials);
}
void SyncManager::SyncInternal::StartSyncing() {
@@ -1536,53 +1410,62 @@ void SyncManager::SyncInternal::SendPendingXMPPNotification(
}
}
-void SyncManager::SyncInternal::Authenticate(const std::string& username,
- const std::string& password,
- const std::string& captcha) {
- DCHECK(username_for_share().empty() || username == username_for_share())
- << "Username change from valid username detected";
- if (allstatus_.status().authenticated)
- return;
- if (password.empty()) {
- // TODO(timsteele): Seems like this shouldn't be needed, but auth_watcher
- // currently drops blank password attempts on the floor and doesn't update
- // state; it only LOGs an error in this case. We want to make sure we set
- // our GoogleServiceAuthError state to denote an error.
- RaiseAuthNeededEvent();
+bool SyncManager::SyncInternal::OpenDirectory() {
+ DCHECK(!initialized()) << "Should only happen once";
+
+ bool share_opened = dir_manager()->Open(username_for_share());
+ DCHECK(share_opened);
+ if (!share_opened) {
+ if (observer_) {
+ observer_->OnStopSyncingPermanently();
+ }
+
+ LOG(ERROR) << "Could not open share for:" << username_for_share();
+ return false;
+ }
+
+ // Database has to be initialized for the guid to be available.
+ syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
+ if (!lookup.good()) {
+ NOTREACHED();
+ return false;
}
- auth_watcher()->Authenticate(username, password, std::string(),
- captcha);
-}
-void SyncManager::SyncInternal::AuthenticateWithLsid(const string& lsid) {
- DCHECK(!lsid.empty());
- auth_watcher()->AuthenticateWithLsid(lsid);
+ connection_manager()->set_client_id(lookup->cache_guid());
+ syncer_thread()->CreateSyncer(username_for_share());
+ MarkAndNotifyInitializationComplete();
+ dir_change_hookup_.reset(lookup->AddChangeObserver(this));
+ return true;
}
-bool SyncManager::SyncInternal::AuthenticateForUser(
- const std::string& username, const std::string& auth_token) {
- share_.authenticated_name = username;
+bool SyncManager::SyncInternal::SignIn(const SyncCredentials& credentials) {
+ DCHECK_EQ(MessageLoop::current(), core_message_loop_);
+ DCHECK(share_.name.empty());
+ share_.name = credentials.email;
- // We optimize by opening the directory before the "fresh" authentication
- // attempt completes so that we can immediately begin processing changes.
- if (!dir_manager()->Open(username_for_share())) {
- if (observer_)
- observer_->OnStopSyncingPermanently();
+ LOG(INFO) << "Signing in user: " << username_for_share();
+ if (!OpenDirectory()) {
return false;
}
- // Load the last-known good auth token into the connection manager and send
- // it off to the AuthWatcher for validation. The result of the validation
- // will update the connection manager if necessary.
- connection_manager()->set_auth_token(auth_token);
- auth_watcher()->AuthenticateWithToken(username, auth_token);
+ UpdateCredentials(credentials);
return true;
}
+void SyncManager::SyncInternal::UpdateCredentials(
+ const SyncCredentials& credentials) {
+ DCHECK_EQ(MessageLoop::current(), core_message_loop_);
+ DCHECK(share_.name == credentials.email);
+ connection_manager()->set_auth_token(credentials.sync_token);
+ TalkMediatorLogin(credentials.email, credentials.sync_token);
+ CheckServerReachable();
+ sync_manager_->RequestNudge();
+}
+
void SyncManager::SyncInternal::RaiseAuthNeededEvent() {
- auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS;
- if (observer_)
- observer_->OnAuthError(AuthError(auth_problem_));
+ if (observer_) {
+ observer_->OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS));
+ }
}
void SyncManager::SyncInternal::SetPassphrase(
@@ -1642,15 +1525,6 @@ void SyncManager::SyncInternal::Shutdown() {
// TODO(akalin): NULL the other member variables defensively, too.
scoped_ptr<TalkMediator> talk_mediator(talk_mediator_.release());
- // First reset the AuthWatcher in case an auth attempt is in progress so that
- // it terminates gracefully before we shutdown and close other components.
- // Otherwise the attempt can complete after we've closed the directory, for
- // example, and cause initialization to continue, which is bad.
- if (auth_watcher_) {
- auth_watcher_->Shutdown();
- authwatcher_hookup_.reset();
- }
-
if (syncer_thread()) {
if (!syncer_thread()->Stop(kThreadExitTimeoutMsec)) {
LOG(FATAL) << "Unable to stop the syncer, it won't be happy...";
@@ -1659,15 +1533,6 @@ void SyncManager::SyncInternal::Shutdown() {
syncer_thread_ = NULL;
}
- // TODO(chron): Since the auth_watcher_ is held by the sync session state,
- // we release the ref here after the syncer is deallocated.
- // In reality the SyncerSessionState's pointer to the
- // authwatcher should be ref counted, but for M6 we use this
- // lower risk fix so it's deallocated on the original thread.
- if (auth_watcher_) {
- auth_watcher_ = NULL;
- }
-
// Shutdown the xmpp buzz connection.
if (talk_mediator.get()) {
LOG(INFO) << "P2P: Mediator logout started.";
@@ -1679,7 +1544,7 @@ void SyncManager::SyncInternal::Shutdown() {
// Pump any messages the auth watcher, syncer thread, or talk
// mediator posted before they shut down. (See HandleSyncerEvent(),
- // HandleAuthWatcherEvent(), and HandleTalkMediatorEvent() for the
+ // and HandleTalkMediatorEvent() for the
// events that may be posted.)
{
CHECK(core_message_loop_);
@@ -1691,6 +1556,8 @@ void SyncManager::SyncInternal::Shutdown() {
net::NetworkChangeNotifier::RemoveObserver(this);
+ connection_manager_hookup_.reset();
+
if (dir_manager()) {
dir_manager()->FinalSaveChangesForAll();
dir_manager()->Close(username_for_share());
@@ -1699,7 +1566,6 @@ void SyncManager::SyncInternal::Shutdown() {
// Reset the DirectoryManager and UserSettings so they relinquish sqlite
// handles to backing files.
share_.dir_manager.reset();
- user_settings_.reset();
// We don't want to process any more events.
dir_change_hookup_.reset();
@@ -1712,22 +1578,7 @@ void SyncManager::SyncInternal::OnIPAddressChanged() {
// TODO(akalin): CheckServerReachable() can block, which may cause
// jank if we try to shut down sync. Fix this.
connection_manager()->CheckServerReachable();
-}
-
-void SyncManager::SyncInternal::HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event) {
- LOG(INFO) << "Sync internal handling a directory manager event";
- if (syncable::DirectoryManagerEvent::OPENED == event.what_happened) {
- DCHECK(!initialized()) << "Should only happen once";
- if (username_for_share().empty()) {
- share_.authenticated_name = event.dirname;
- }
- DCHECK(LowerCaseEqualsASCII(username_for_share(),
- StringToLowerASCII(event.dirname).c_str()))
- << "username_for_share= " << username_for_share()
- << ", event.dirname= " << event.dirname;
- MarkAndNotifyInitializationComplete();
- }
+ sync_manager_->RequestNudge();
}
// Listen to model changes, filter out ones initiated by the sync API, and
@@ -1750,6 +1601,25 @@ void SyncManager::SyncInternal::HandleChannelEvent(
}
}
+void SyncManager::SyncInternal::HandleServerConnectionEvent(
+ const ServerConnectionEvent& event) {
+ allstatus_.HandleServerConnectionEvent(event);
+ if (event.what_happened == ServerConnectionEvent::STATUS_CHANGED) {
+ if (event.connection_code ==
+ browser_sync::HttpResponse::SERVER_CONNECTION_OK) {
+ if (observer_) {
+ observer_->OnAuthError(AuthError(AuthError::None()));
+ }
+ }
+
+ if (event.connection_code == browser_sync::HttpResponse::SYNC_AUTH_ERROR) {
+ if (observer_) {
+ observer_->OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS));
+ }
+ }
+ }
+}
+
void SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
const syncable::DirectoryChangeEvent& event) {
// This notification happens immediately before a syncable WriteTransaction
@@ -1981,105 +1851,11 @@ void SyncManager::SyncInternal::HandleChannelEvent(const SyncerEvent& event) {
observer_->OnStopSyncingPermanently();
return;
}
-}
-void SyncManager::SyncInternal::HandleAuthWatcherEvent(
- const AuthWatcherEvent& event) {
- allstatus_.HandleAuthWatcherEvent(event);
- // We don't care about an authentication attempt starting event, and we
- // don't want to reset our state to GoogleServiceAuthError::NONE because the
- // fact that an _attempt_ is starting doesn't change the fact that we have an
- // auth problem.
- if (event.what_happened == AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START)
+ if (event.what_happened == SyncerEvent::UPDATED_TOKEN) {
+ observer_->OnUpdatedToken(event.updated_token);
return;
- // We clear our last auth problem cache on new auth watcher events, and only
- // set it to indicate a problem state for certain AuthWatcherEvent types.
- auth_problem_ = AuthError::NONE;
- switch (event.what_happened) {
- case AuthWatcherEvent::AUTH_SUCCEEDED:
- DCHECK(!event.user_email.empty());
- // We now know the supplied username and password were valid. If this
- // wasn't the first sync, authenticated_name should already be assigned.
- if (username_for_share().empty()) {
- share_.authenticated_name = event.user_email;
- }
-
- DCHECK(LowerCaseEqualsASCII(username_for_share(),
- StringToLowerASCII(event.user_email).c_str()))
- << "username_for_share= " << username_for_share()
- << ", event.user_email= " << event.user_email;
-
- if (observer_)
- observer_->OnAuthError(AuthError::None());
-
- // Hook up the DirectoryChangeEvent listener, HandleChangeEvent.
- {
- syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
- if (!lookup.good()) {
- DCHECK(false) << "ScopedDirLookup creation failed; unable to hook "
- << "up directory change event listener!";
- return;
- }
-
- // Note that we can end up here multiple times, for example if the
- // user had to re-login and we got a second AUTH_SUCCEEDED event. Take
- // care not to add ourselves as an observer a second time.
- if (!dir_change_hookup_.get())
- dir_change_hookup_.reset(lookup->AddChangeObserver(this));
- }
-
- if (!event.auth_token.empty()) {
- core_message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- this, &SyncManager::SyncInternal::TalkMediatorLogin,
- event.user_email, event.auth_token));
- }
- return;
- case AuthWatcherEvent::AUTH_RENEWED:
- DCHECK(!event.user_email.empty());
- DCHECK(!event.auth_token.empty());
- core_message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- this, &SyncManager::SyncInternal::TalkMediatorLogin,
- event.user_email, event.auth_token));
- return;
- // Authentication failures translate to GoogleServiceAuthError events.
- case AuthWatcherEvent::GAIA_AUTH_FAILED: // Invalid GAIA credentials.
- if (event.auth_results->auth_error == gaia::CaptchaRequired) {
- auth_problem_ = AuthError::CAPTCHA_REQUIRED;
- std::string url_string("https://www.google.com/accounts/");
- url_string += event.auth_results->captcha_url;
- GURL captcha(url_string);
- observer_->OnAuthError(AuthError::FromCaptchaChallenge(
- event.auth_results->captcha_token, captcha,
- GURL(event.auth_results->auth_error_url)));
- return;
- } else if (event.auth_results->auth_error ==
- gaia::ConnectionUnavailable) {
- auth_problem_ = AuthError::CONNECTION_FAILED;
- } else {
- auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS;
- }
- break;
- case AuthWatcherEvent::SERVICE_AUTH_FAILED: // Expired GAIA credentials.
- auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS;
- break;
- case AuthWatcherEvent::SERVICE_USER_NOT_SIGNED_UP:
- auth_problem_ = AuthError::USER_NOT_SIGNED_UP;
- break;
- case AuthWatcherEvent::SERVICE_CONNECTION_FAILED:
- auth_problem_ = AuthError::CONNECTION_FAILED;
- break;
- default: // We don't care about the many other AuthWatcherEvent types.
- return;
}
-
-
- // Fire notification that the status changed due to an authentication error.
- if (observer_)
- observer_->OnAuthError(AuthError(auth_problem_));
}
void SyncManager::SyncInternal::OnNotificationStateChange(
@@ -2121,8 +1897,8 @@ void SyncManager::SyncInternal::TalkMediatorLogin(
<< "(talk_mediator_ is NULL)";
return;
}
- // TODO(akalin): Make talk_mediator automatically login on
- // auth token change.
+ LOG(INFO) << "P2P: Trying talk mediator login.";
+
talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME);
talk_mediator_->Login();
}
@@ -2184,7 +1960,7 @@ void SyncManager::SetupForTestMode(const std::wstring& test_username) {
void SyncManager::SyncInternal::SetupForTestMode(
const std::wstring& test_username) {
- share_.authenticated_name = WideToUTF8(test_username);
+ share_.name = WideToUTF8(test_username);
// Some tests are targeting only local db operations & integrity, and don't
// want syncer thread interference.
@@ -2192,18 +1968,8 @@ void SyncManager::SyncInternal::SetupForTestMode(
allstatus_.WatchSyncerThread(NULL);
syncer_thread_ = NULL;
- if (!dir_manager()->Open(username_for_share()))
+ if (!dir_manager()->Open(username_for_share())) {
DCHECK(false) << "Could not open directory when running in test mode";
-
- // Hook up the DirectoryChangeEvent listener, HandleChangeEvent.
- {
- syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
- if (!lookup.good()) {
- DCHECK(false) << "ScopedDirLookup creation failed; unable to hook "
- << "up directory change event listener!";
- return;
- }
- dir_change_hookup_.reset(lookup->AddChangeObserver(this));
}
}
@@ -2213,7 +1979,7 @@ BaseTransaction::BaseTransaction(UserShare* share)
: lookup_(NULL) {
DCHECK(share && share->dir_manager.get());
lookup_ = new syncable::ScopedDirLookup(share->dir_manager.get(),
- share->authenticated_name);
+ share->name);
cryptographer_ = share->dir_manager->cryptographer();
if (!(lookup_->good()))
DCHECK(false) << "ScopedDirLookup failed on valid DirManager.";
diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h
index e4e8510..16f8bd9 100644
--- a/chrome/browser/sync/engine/syncapi.h
+++ b/chrome/browser/sync/engine/syncapi.h
@@ -107,12 +107,14 @@ struct UserShare {
// be shared across multiple threads (unlike Directory).
scoped_ptr<syncable::DirectoryManager> dir_manager;
- // The username of the sync user. This is empty until we have performed at
- // least one successful GAIA authentication with this username, which means
- // on first-run it is empty until an AUTH_SUCCEEDED event and on future runs
- // it is set as soon as the client instructs us to authenticate for the last
- // known valid user (AuthenticateForLastKnownUser()).
- std::string authenticated_name;
+ // The username of the sync user.
+ std::string name;
+};
+
+// Contains everything needed to talk to and identify a user account.
+struct SyncCredentials {
+ std::string email;
+ std::string sync_token;
};
// A valid BaseNode will never have an ID of zero.
@@ -669,6 +671,9 @@ class SyncManager {
// Called when user interaction may be required due to an auth problem.
virtual void OnAuthError(const GoogleServiceAuthError& auth_error) = 0;
+ // Called when a new auth token is provided by the sync server.
+ virtual void OnUpdatedToken(const std::string& token) = 0;
+
// Called when user interaction is required to obtain a valid passphrase.
virtual void OnPassphraseRequired() = 0;
@@ -715,52 +720,22 @@ class SyncManager {
// |sync_server_and_path| and |sync_server_port| represent the Chrome sync
// server to use, and |use_ssl| specifies whether to communicate securely;
// the default is false.
- // |gaia_service_id| is the service id used for GAIA authentication. If it's
- // null then default will be used.
// |post_factory| will be owned internally and used to create
// instances of an HttpPostProvider.
- // |auth_post_factory| will be owned internally and used to create
- // instances of an HttpPostProvider for communicating with GAIA.
- // TODO(timsteele): It seems like one factory should suffice, but for now to
- // avoid having to deal with threading issues since the auth code and syncer
- // code live on separate threads that run simultaneously, we just dedicate
- // one to each component. Long term we may want to reconsider the HttpBridge
- // API to take all the params in one chunk in a threadsafe manner.. which is
- // still suboptimal as there will be high contention between the two threads
- // on startup; so maybe what we have now is the best solution- it does mirror
- // the CURL implementation as each thread creates their own internet handle.
- // Investigate.
// |model_safe_worker| ownership is given to the SyncManager.
// |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent
// HTTP header. Used internally when collecting stats to classify clients.
- // As a fallback when no cached auth information is available, try to
- // bootstrap authentication using |lsid|, if it isn't empty.
- //
- // |invalidate_last_user_auth_token| makes it so that any auth token
- // read from user settings is invalidated. This is used for testing
- // code paths related to authentication failures.
- //
- // |invalidate_xmpp_auth_token| makes it so that any auth token
- // used to log into XMPP is invalidated. This is used for testing
- // code paths related to authentication failures for XMPP only.
- //
// |try_ssltcp_first| indicates that the SSLTCP port (443) is tried before the
// the XMPP port (5222) during login. It is used by the sync tests that are
// run on the chromium builders because port 5222 is blocked.
bool Init(const FilePath& database_location,
const char* sync_server_and_path,
int sync_server_port,
- const char* gaia_service_id,
- const char* gaia_source,
bool use_ssl,
HttpPostProviderFactory* post_factory,
- HttpPostProviderFactory* auth_post_factory,
browser_sync::ModelSafeWorkerRegistrar* registrar,
- bool attempt_last_user_authentication,
- bool invalidate_last_user_auth_token,
- bool invalidate_xmpp_auth_token,
const char* user_agent,
- const char* lsid,
+ const SyncCredentials& credentials,
bool use_chrome_async_socket,
bool try_ssltcp_first,
browser_sync::NotificationMethod notification_method,
@@ -776,15 +751,11 @@ class SyncManager {
// called.
bool InitialSyncEndedForAllEnabledTypes();
- // Submit credentials to GAIA for verification. On success, both |username|
- // and the obtained auth token are persisted on disk for future re-use.
- // If authentication fails, OnAuthProblem is called on our Observer.
- // The Observer may, in turn, decide to try again with new
- // credentials. Calling this method again is the appropriate course of action
- // to "retry".
- // |username|, |password|, and |captcha| are owned by the caller.
- void Authenticate(const char* username, const char* password,
- const char* captcha);
+ // Migrate tokens from user settings DB to the token service.
+ void MigrateTokens();
+
+ // Update tokens that we're using in Sync. Email must stay the same.
+ void UpdateCredentials(const SyncCredentials& credentials);
// Start the SyncerThread.
void StartSyncing();
diff --git a/chrome/browser/sync/engine/syncapi_unittest.cc b/chrome/browser/sync/engine/syncapi_unittest.cc
index a77134b..b83c501 100644
--- a/chrome/browser/sync/engine/syncapi_unittest.cc
+++ b/chrome/browser/sync/engine/syncapi_unittest.cc
@@ -25,7 +25,7 @@ class SyncApiTest : public testing::Test {
virtual void SetUp() {
setter_upper_.SetUp();
share_.dir_manager.reset(setter_upper_.manager());
- share_.authenticated_name = setter_upper_.name();
+ share_.name = setter_upper_.name();
}
virtual void TearDown() {
diff --git a/chrome/browser/sync/engine/syncer_proto_util.cc b/chrome/browser/sync/engine/syncer_proto_util.cc
index 17de218..2cc2300 100644
--- a/chrome/browser/sync/engine/syncer_proto_util.cc
+++ b/chrome/browser/sync/engine/syncer_proto_util.cc
@@ -6,9 +6,9 @@
#include "base/format_macros.h"
#include "base/string_util.h"
-#include "chrome/browser/sync/engine/auth_watcher.h"
#include "chrome/browser/sync/engine/net/server_connection_manager.h"
#include "chrome/browser/sync/engine/syncer.h"
+#include "chrome/browser/sync/engine/syncer_types.h"
#include "chrome/browser/sync/engine/syncer_util.h"
#include "chrome/browser/sync/protocol/service_constants.h"
#include "chrome/browser/sync/sessions/sync_session.h"
@@ -124,7 +124,7 @@ void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir,
// static
bool SyncerProtoUtil::PostAndProcessHeaders(ServerConnectionManager* scm,
- AuthWatcher* auth_watcher,
+ sessions::SyncSession* session,
const ClientToServerMessage& msg,
ClientToServerResponse* response) {
@@ -144,12 +144,9 @@ bool SyncerProtoUtil::PostAndProcessHeaders(ServerConnectionManager* scm,
std::string new_token =
http_response.update_client_auth_header;
if (!new_token.empty()) {
- // We could also do this in the SCM's PostBufferWithAuth.
- // But then we could be in the middle of authentication, which seems
- // like a bad time to update the token. A consequence of this is that
- // we can't reset the cookie in response to auth attempts, but this
- // should be OK.
- auth_watcher->RenewAuthToken(new_token);
+ SyncerEvent event(SyncerEvent::UPDATED_TOKEN);
+ event.updated_token = new_token;
+ session->context()->syncer_event_channel()->Notify(event);
}
if (response->ParseFromString(rx)) {
@@ -189,7 +186,7 @@ bool SyncerProtoUtil::PostClientToServerMessage(
}
if (!PostAndProcessHeaders(session->context()->connection_manager(),
- session->context()->auth_watcher(),
+ session,
msg,
response)) {
return false;
diff --git a/chrome/browser/sync/engine/syncer_proto_util.h b/chrome/browser/sync/engine/syncer_proto_util.h
index 39fcc5c..ca68ec3 100644
--- a/chrome/browser/sync/engine/syncer_proto_util.h
+++ b/chrome/browser/sync/engine/syncer_proto_util.h
@@ -105,7 +105,7 @@ class SyncerProtoUtil {
// Post the message using the scm, and do some processing on the returned
// headers. Decode the server response.
static bool PostAndProcessHeaders(browser_sync::ServerConnectionManager* scm,
- browser_sync::AuthWatcher* authwatcher,
+ sessions::SyncSession* session,
const ClientToServerMessage& msg,
sync_pb::ClientToServerResponse* response);
diff --git a/chrome/browser/sync/engine/syncer_proto_util_unittest.cc b/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
index e6eb68b..57cae0a 100644
--- a/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_proto_util_unittest.cc
@@ -182,7 +182,7 @@ TEST_F(SyncerProtoUtilTest, AddRequestBirthday) {
class DummyConnectionManager : public browser_sync::ServerConnectionManager {
public:
DummyConnectionManager()
- : ServerConnectionManager("unused", 0, false, "version", "id"),
+ : ServerConnectionManager("unused", 0, false, "version"),
send_error_(false),
access_denied_(false) {}
diff --git a/chrome/browser/sync/engine/syncer_thread.cc b/chrome/browser/sync/engine/syncer_thread.cc
index 800ddddb..9f369ed8 100644
--- a/chrome/browser/sync/engine/syncer_thread.cc
+++ b/chrome/browser/sync/engine/syncer_thread.cc
@@ -17,12 +17,10 @@
#include "base/rand_util.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
-#include "chrome/browser/sync/engine/auth_watcher.h"
#include "chrome/browser/sync/engine/model_safe_worker.h"
#include "chrome/browser/sync/engine/net/server_connection_manager.h"
#include "chrome/browser/sync/engine/syncer.h"
#include "chrome/browser/sync/sessions/session_state.h"
-#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/common/chrome_switches.h"
#include "jingle/notifier/listener/notification_constants.h"
@@ -75,19 +73,12 @@ SyncerThread::SyncerThread(sessions::SyncSessionContext* context)
syncer_long_poll_interval_seconds_(kDefaultLongPollIntervalSeconds),
syncer_polling_interval_(kDefaultShortPollIntervalSeconds),
syncer_max_interval_(kDefaultMaxPollIntervalMs),
- directory_manager_hookup_(NULL),
syncer_events_(NULL),
session_context_(context),
disable_idle_detection_(false) {
DCHECK(context);
syncer_event_relay_channel_.reset(new SyncerEventChannel());
- if (context->directory_manager()) {
- directory_manager_hookup_.reset(NewEventListenerHookup(
- context->directory_manager()->channel(), this,
- &SyncerThread::HandleDirectoryManagerEvent));
- }
-
if (context->connection_manager())
WatchConnectionManager(context->connection_manager());
@@ -98,7 +89,6 @@ SyncerThread::~SyncerThread() {
syncer_event_relay_channel_->Notify(SyncerEvent(
SyncerEvent::SHUTDOWN_USE_WITH_CARE));
syncer_event_relay_channel_.reset();
- directory_manager_hookup_.reset();
syncer_events_.reset();
delete vault_.syncer_;
CHECK(!thread_.IsRunning());
@@ -587,22 +577,18 @@ void SyncerThread::HandleChannelEvent(const SyncerEvent& event) {
NudgeSyncImpl(event.nudge_delay_milliseconds, kUnknown);
}
-void SyncerThread::HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event) {
- LOG(INFO) << "Handling a directory manager event";
- if (syncable::DirectoryManagerEvent::OPENED == event.what_happened) {
- AutoLock lock(lock_);
- LOG(INFO) << "Syncer starting up for: " << event.dirname;
- // The underlying database structure is ready, and we should create
- // the syncer.
- CHECK(vault_.syncer_ == NULL);
- session_context_->set_account_name(event.dirname);
- vault_.syncer_ = new Syncer(session_context_.get());
-
- syncer_events_.reset(
- session_context_->syncer_event_channel()->AddObserver(this));
- vault_field_changed_.Broadcast();
- }
+void SyncerThread::CreateSyncer(const std::string& dirname) {
+ AutoLock lock(lock_);
+ LOG(INFO) << "Creating syncer up for: " << dirname;
+ // The underlying database structure is ready, and we should create
+ // the syncer.
+ CHECK(vault_.syncer_ == NULL);
+ session_context_->set_account_name(dirname);
+ vault_.syncer_ = new Syncer(session_context_.get());
+
+ syncer_events_.reset(
+ session_context_->syncer_event_channel()->AddObserver(this));
+ vault_field_changed_.Broadcast();
}
// Sets |*connected| to false if it is currently true but |code| suggests that
diff --git a/chrome/browser/sync/engine/syncer_thread.h b/chrome/browser/sync/engine/syncer_thread.h
index 8c71db4..158d759 100644
--- a/chrome/browser/sync/engine/syncer_thread.h
+++ b/chrome/browser/sync/engine/syncer_thread.h
@@ -29,11 +29,6 @@
class EventListenerHookup;
-namespace syncable {
-class DirectoryManager;
-struct DirectoryManagerEvent;
-}
-
namespace browser_sync {
class ModelSafeWorker;
@@ -138,6 +133,9 @@ class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>,
virtual SyncerEventChannel* relay_channel();
+ // Call this when a directory is opened
+ void CreateSyncer(const std::string& dirname);
+
// DDOS avoidance function. The argument and return value is in seconds
static int GetRecommendedDelaySeconds(int base_delay_seconds);
@@ -230,8 +228,6 @@ class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>,
friend void* RunSyncerThread(void* syncer_thread);
void* Run();
- void HandleDirectoryManagerEvent(
- const syncable::DirectoryManagerEvent& event);
void HandleChannelEvent(const SyncerEvent& event);
// SyncSession::Delegate implementation.
@@ -323,7 +319,6 @@ class SyncerThread : public base::RefCountedThreadSafe<SyncerThread>,
// this is called.
void NudgeSyncImpl(int milliseconds_from_now, NudgeSource source);
- scoped_ptr<EventListenerHookup> directory_manager_hookup_;
scoped_ptr<ChannelHookup<SyncerEvent> > syncer_events_;
#if defined(OS_LINUX)
diff --git a/chrome/browser/sync/engine/syncer_thread_unittest.cc b/chrome/browser/sync/engine/syncer_thread_unittest.cc
index 16328bd..ded07f0 100644
--- a/chrome/browser/sync/engine/syncer_thread_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_thread_unittest.cc
@@ -66,7 +66,7 @@ class SyncerThreadWithSyncerTest : public testing::Test,
metadb_.name()));
worker_ = new ModelSafeWorker();
SyncSessionContext* context = new SyncSessionContext(connection_.get(),
- NULL, metadb_.manager(), this);
+ metadb_.manager(), this);
syncer_thread_ = new SyncerThread(context);
syncer_event_hookup_.reset(
syncer_thread_->relay_channel()->AddObserver(this));
@@ -217,12 +217,12 @@ class SyncShareIntercept
};
TEST_F(SyncerThreadTest, Construction) {
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, NULL);
+ SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL);
scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
}
TEST_F(SyncerThreadTest, StartStop) {
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, NULL);
+ SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL);
scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
EXPECT_TRUE(syncer_thread->Start());
EXPECT_TRUE(syncer_thread->Stop(2000));
@@ -247,7 +247,7 @@ TEST(SyncerThread, GetRecommendedDelay) {
}
TEST_F(SyncerThreadTest, CalculateSyncWaitTime) {
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, NULL);
+ SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL);
scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
syncer_thread->DisableIdleDetection();
@@ -307,7 +307,7 @@ TEST_F(SyncerThreadTest, CalculateSyncWaitTime) {
TEST_F(SyncerThreadTest, CalculatePollingWaitTime) {
// Set up the environment.
int user_idle_milliseconds_param = 0;
- SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL, NULL);
+ SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL);
scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context));
syncer_thread->DisableIdleDetection();
// Hold the lock to appease asserts in code.
@@ -639,8 +639,8 @@ TEST_F(SyncerThreadWithSyncerTest, Polling) {
syncer_thread()->SetSyncerShortPollInterval(poll_interval);
EXPECT_TRUE(syncer_thread()->Start());
- // Calling Open() should cause the SyncerThread to create a Syncer.
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
TimeDelta two_polls = poll_interval + poll_interval;
// We could theoretically return immediately from the wait if the interceptor
@@ -673,6 +673,7 @@ TEST_F(SyncerThreadWithSyncerTest, Nudge) {
PreventThreadFromPolling();
EXPECT_TRUE(syncer_thread()->Start());
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
const TimeDelta poll_interval = TimeDelta::FromMinutes(5);
interceptor.WaitForSyncShare(1, poll_interval + poll_interval);
@@ -697,6 +698,7 @@ TEST_F(SyncerThreadWithSyncerTest, Throttling) {
EXPECT_TRUE(syncer_thread()->Start());
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
// Wait for some healthy syncing.
interceptor.WaitForSyncShare(4, poll_interval + poll_interval);
@@ -750,6 +752,7 @@ TEST_F(SyncerThreadWithSyncerTest, StopSyncPermanently) {
EXPECT_TRUE(syncer_thread()->Start());
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
connection()->set_store_birthday("NotYourLuckyDay");
@@ -765,6 +768,7 @@ TEST_F(SyncerThreadWithSyncerTest, AuthInvalid) {
syncer_thread()->SetSyncerShortPollInterval(poll_interval);
EXPECT_TRUE(syncer_thread()->Start());
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
// Wait for some healthy syncing.
interceptor.WaitForSyncShare(2, TimeDelta::FromSeconds(10));
@@ -826,6 +830,7 @@ TEST_F(SyncerThreadWithSyncerTest, FLAKY_Pause) {
Field(&SyncerEvent::what_happened, SyncerEvent::SYNCER_THREAD_EXITING)));
ASSERT_TRUE(syncer_thread()->Start());
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
// Request a pause.
@@ -869,6 +874,7 @@ TEST_F(SyncerThreadWithSyncerTest, StartWhenNotConnected) {
connection()->SetServerNotReachable();
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
// Syncer thread will always go through once cycle at the start,
// then it will wait for a connection.
@@ -923,6 +929,8 @@ TEST_F(SyncerThreadWithSyncerTest, DISABLED_PauseWhenNotConnected) {
Field(&SyncerEvent::what_happened, SyncerEvent::WAITING_FOR_CONNECTION))).
WillOnce(SignalEvent(&event));
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
+
ASSERT_TRUE(syncer_thread()->Start());
ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_));
ASSERT_TRUE(event.TimedWait(max_wait_time_));
@@ -994,6 +1002,7 @@ TEST_F(SyncerThreadWithSyncerTest, PauseResumeWhenNotRunning) {
// Pause the thread then start the syncer.
ASSERT_TRUE(Pause(&listener));
metadb()->Open();
+ syncer_thread()->CreateSyncer(metadb()->name());
ASSERT_TRUE(syncer_thread()->Start());
// Resume and let the syncer cycle.
diff --git a/chrome/browser/sync/engine/syncer_types.h b/chrome/browser/sync/engine/syncer_types.h
index 19be54e..0805c89 100644
--- a/chrome/browser/sync/engine/syncer_types.h
+++ b/chrome/browser/sync/engine/syncer_types.h
@@ -78,6 +78,8 @@ struct SyncerEvent {
STATUS_CHANGED,
+ UPDATED_TOKEN, // new token in updated_token
+
// Take care not to wait in shutdown handlers for the syncer to stop as it
// causes a race in the event system. Use SyncerShutdownEvent instead.
SHUTDOWN_USE_WITH_CARE,
@@ -143,6 +145,9 @@ struct SyncerEvent {
// How many milliseconds later should the syncer kick in? For
// REQUEST_SYNC_NUDGE only.
int nudge_delay_milliseconds;
+
+ // Update-Client-Auth returns a new token for sync use.
+ std::string updated_token;
};
struct SyncerShutdownEvent {
diff --git a/chrome/browser/sync/engine/syncer_unittest.cc b/chrome/browser/sync/engine/syncer_unittest.cc
index 0d9ab8e..74e5122 100644
--- a/chrome/browser/sync/engine/syncer_unittest.cc
+++ b/chrome/browser/sync/engine/syncer_unittest.cc
@@ -168,7 +168,7 @@ class SyncerTest : public testing::Test,
new MockConnectionManager(syncdb_.manager(), syncdb_.name()));
EnableDatatype(syncable::BOOKMARKS);
worker_ = new ModelSafeWorker();
- context_.reset(new SyncSessionContext(mock_server_.get(), NULL,
+ context_.reset(new SyncSessionContext(mock_server_.get(),
syncdb_.manager(), this));
context_->set_account_name(syncdb_.name());
ASSERT_FALSE(context_->syncer_event_channel());