1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync/test_profile_sync_service.h"
7 #include "chrome/browser/chrome_notification_types.h"
8 #include "chrome/browser/signin/signin_manager.h"
9 #include "chrome/browser/signin/signin_manager_factory.h"
10 #include "chrome/browser/sync/glue/sync_backend_host.h"
11 #include "chrome/browser/sync/profile_sync_components_factory.h"
12 #include "chrome/browser/sync/test/test_http_bridge_factory.h"
13 #include "sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h"
14 #include "sync/internal_api/public/user_share.h"
15 #include "sync/js/js_reply_handler.h"
16 #include "sync/protocol/encryption.pb.h"
18 using syncer::InternalComponentsFactory;
19 using syncer::ModelSafeRoutingInfo;
20 using syncer::TestInternalComponentsFactory;
21 using syncer::UserShare;
23 namespace browser_sync {
25 SyncBackendHostForProfileSyncTest::SyncBackendHostForProfileSyncTest(
27 const base::WeakPtr<SyncPrefs>& sync_prefs,
28 base::Closure& callback,
29 bool set_initial_sync_ended_on_init,
30 bool synchronous_init,
31 bool fail_initial_download,
32 syncer::StorageOption storage_option)
33 : browser_sync::SyncBackendHost(
34 profile->GetDebugName(), profile, sync_prefs),
36 fail_initial_download_(fail_initial_download),
37 set_initial_sync_ended_on_init_(set_initial_sync_ended_on_init),
38 synchronous_init_(synchronous_init),
39 storage_option_(storage_option),
40 weak_ptr_factory_(this) {}
42 SyncBackendHostForProfileSyncTest::~SyncBackendHostForProfileSyncTest() {}
46 scoped_ptr<syncer::HttpPostProviderFactory> MakeTestHttpBridgeFactory() {
47 return scoped_ptr<syncer::HttpPostProviderFactory>(
48 new browser_sync::TestHttpBridgeFactory());
53 void SyncBackendHostForProfileSyncTest::InitCore(
54 scoped_ptr<DoInitializeOptions> options) {
55 options->http_bridge_factory = MakeTestHttpBridgeFactory();
56 options->sync_manager_factory.reset(
57 new syncer::SyncManagerFactoryForProfileSyncTest(
59 set_initial_sync_ended_on_init_));
60 options->credentials.email = "testuser@gmail.com";
61 options->credentials.sync_token = "token";
62 options->restored_key_for_bootstrapping = "";
63 syncer::StorageOption storage = storage_option_;
65 // It'd be nice if we avoided creating the InternalComponentsFactory in the
66 // first place, but SyncBackendHost will have created one by now so we must
67 // free it. Grab the switches to pass on first.
68 InternalComponentsFactory::Switches factory_switches =
69 options->internal_components_factory->GetSwitches();
70 options->internal_components_factory.reset(
71 new TestInternalComponentsFactory(factory_switches, storage));
73 SyncBackendHost::InitCore(options.Pass());
74 if (synchronous_init_ && !base::MessageLoop::current()->is_running()) {
75 // The SyncBackend posts a task to the current loop when
76 // initialization completes.
77 base::MessageLoop::current()->Run();
81 void SyncBackendHostForProfileSyncTest::UpdateCredentials(
82 const syncer::SyncCredentials& credentials) {
83 // If we had failed the initial download, complete initialization now.
84 if (!initial_download_closure_.is_null()) {
85 initial_download_closure_.Run();
86 initial_download_closure_.Reset();
90 void SyncBackendHostForProfileSyncTest::RequestConfigureSyncer(
91 syncer::ConfigureReason reason,
92 syncer::ModelTypeSet to_download,
93 syncer::ModelTypeSet to_purge,
94 syncer::ModelTypeSet to_journal,
95 syncer::ModelTypeSet to_unapply,
96 syncer::ModelTypeSet to_ignore,
97 const syncer::ModelSafeRoutingInfo& routing_info,
98 const base::Callback<void(syncer::ModelTypeSet,
99 syncer::ModelTypeSet)>& ready_task,
100 const base::Closure& retry_callback) {
101 syncer::ModelTypeSet failed_configuration_types;
102 if (fail_initial_download_)
103 failed_configuration_types = to_download;
105 // The first parameter there should be the set of enabled types. That's not
106 // something we have access to from this strange test harness. We'll just
107 // send back the list of newly configured types instead and hope it doesn't
109 FinishConfigureDataTypesOnFrontendLoop(
110 syncer::Difference(to_download, failed_configuration_types),
111 syncer::Difference(to_download, failed_configuration_types),
112 failed_configuration_types,
117 SyncBackendHostForProfileSyncTest::HandleInitializationSuccessOnFrontendLoop(
118 const syncer::WeakHandle<syncer::JsBackend> js_backend,
119 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>
120 debug_info_listener) {
121 if (fail_initial_download_) {
122 // We interrupt this successful init to bring you a simulated failure.
123 initial_download_closure_ = base::Bind(
124 &SyncBackendHostForProfileSyncTest::
125 HandleInitializationSuccessOnFrontendLoop,
126 weak_ptr_factory_.GetWeakPtr(),
128 debug_info_listener);
129 HandleControlTypesDownloadRetry();
130 if (synchronous_init_)
131 base::MessageLoop::current()->Quit();
133 SyncBackendHost::HandleInitializationSuccessOnFrontendLoop(
135 debug_info_listener);
139 } // namespace browser_sync
141 syncer::TestIdFactory* TestProfileSyncService::id_factory() {
145 browser_sync::SyncBackendHostForProfileSyncTest*
146 TestProfileSyncService::GetBackendForTest() {
147 return static_cast<browser_sync::SyncBackendHostForProfileSyncTest*>(
148 ProfileSyncService::GetBackendForTest());
151 syncer::WeakHandle<syncer::JsEventHandler>
152 TestProfileSyncService::GetJsEventHandler() {
153 return syncer::WeakHandle<syncer::JsEventHandler>();
156 TestProfileSyncService::TestProfileSyncService(
157 ProfileSyncComponentsFactory* factory,
159 SigninManagerBase* signin,
160 ProfileOAuth2TokenService* oauth2_token_service,
161 ProfileSyncService::StartBehavior behavior,
162 bool synchronous_backend_initialization)
163 : ProfileSyncService(factory,
166 oauth2_token_service,
168 synchronous_backend_initialization_(
169 synchronous_backend_initialization),
170 synchronous_sync_configuration_(false),
171 set_initial_sync_ended_on_init_(true),
172 fail_initial_download_(false),
173 storage_option_(syncer::STORAGE_IN_MEMORY) {
174 SetSyncSetupCompleted();
177 TestProfileSyncService::~TestProfileSyncService() {
181 BrowserContextKeyedService* TestProfileSyncService::BuildAutoStartAsyncInit(
182 content::BrowserContext* context) {
183 Profile* profile = static_cast<Profile*>(context);
184 SigninManagerBase* signin =
185 SigninManagerFactory::GetForProfile(profile);
186 ProfileOAuth2TokenService* oauth2_token_service =
187 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
188 ProfileSyncComponentsFactoryMock* factory =
189 new ProfileSyncComponentsFactoryMock();
190 return new TestProfileSyncService(factory,
193 oauth2_token_service,
194 ProfileSyncService::AUTO_START,
198 ProfileSyncComponentsFactoryMock*
199 TestProfileSyncService::components_factory_mock() {
200 // We always create a mock factory, see Build* routines.
201 return static_cast<ProfileSyncComponentsFactoryMock*>(factory());
204 void TestProfileSyncService::RequestAccessToken() {
205 ProfileSyncService::RequestAccessToken();
206 if (synchronous_backend_initialization_) {
207 base::MessageLoop::current()->Run();
211 void TestProfileSyncService::OnGetTokenFailure(
212 const OAuth2TokenService::Request* request,
213 const GoogleServiceAuthError& error) {
214 ProfileSyncService::OnGetTokenFailure(request, error);
215 if (synchronous_backend_initialization_) {
216 base::MessageLoop::current()->Quit();
221 void TestProfileSyncService::OnBackendInitialized(
222 const syncer::WeakHandle<syncer::JsBackend>& backend,
223 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
226 ProfileSyncService::OnBackendInitialized(backend,
230 // TODO(akalin): Figure out a better way to do this.
231 if (synchronous_backend_initialization_) {
232 base::MessageLoop::current()->Quit();
236 void TestProfileSyncService::OnConfigureDone(
237 const browser_sync::DataTypeManager::ConfigureResult& result) {
238 ProfileSyncService::OnConfigureDone(result);
239 if (!synchronous_sync_configuration_)
240 base::MessageLoop::current()->Quit();
243 UserShare* TestProfileSyncService::GetUserShare() const {
244 return backend_->GetUserShare();
247 void TestProfileSyncService::dont_set_initial_sync_ended_on_init() {
248 set_initial_sync_ended_on_init_ = false;
250 void TestProfileSyncService::set_synchronous_sync_configuration() {
251 synchronous_sync_configuration_ = true;
253 void TestProfileSyncService::fail_initial_download() {
254 fail_initial_download_ = true;
256 void TestProfileSyncService::set_storage_option(
257 syncer::StorageOption storage_option) {
258 storage_option_ = storage_option;
261 void TestProfileSyncService::CreateBackend() {
262 backend_.reset(new browser_sync::SyncBackendHostForProfileSyncTest(
264 sync_prefs_.AsWeakPtr(),
266 set_initial_sync_ended_on_init_,
267 synchronous_backend_initialization_,
268 fail_initial_download_,
272 void FakeOAuth2TokenService::FetchOAuth2Token(
273 OAuth2TokenService::RequestImpl* request,
274 const std::string& account_id,
275 net::URLRequestContextGetter* getter,
276 const std::string& client_id,
277 const std::string& client_secret,
278 const OAuth2TokenService::ScopeSet& scopes) {
279 // Request will succeed without network IO.
280 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
281 &RequestImpl::InformConsumer,
282 request->AsWeakPtr(),
283 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
288 BrowserContextKeyedService* FakeOAuth2TokenService::BuildTokenService(
289 content::BrowserContext* context) {
290 Profile* profile = static_cast<Profile*>(context);
292 FakeOAuth2TokenService* service = new FakeOAuth2TokenService();
293 service->Initialize(profile);
297 void FakeOAuth2TokenService::PersistCredentials(
298 const std::string& account_id,
299 const std::string& refresh_token) {
300 // Disabling the token persistence.
303 void FakeOAuth2TokenService::ClearPersistedCredentials(
304 const std::string& account_id) {
305 // Disabling the token persistence.