15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/frontend_data_type_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_components_factory.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/sync_driver/change_processor.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/model_associator.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/model_type.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/util/data_type_histogram.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// TODO(tim): Legacy controllers are being left behind in componentization 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// effort for now, hence passing null DisableTypeCallback and still having 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// a dependency on ProfileSyncService. That dep can probably be removed 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// without too much work. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FrontendDataTypeController::FrontendDataTypeController( 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> ui_thread, 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& error_callback, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service) 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : DataTypeController(ui_thread, error_callback), 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_sync_factory_(profile_sync_factory), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(profile), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_service_(sync_service), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(NOT_RUNNING) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_sync_factory); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(sync_service); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::LoadModels( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ModelLoadCallback& model_load_callback) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci model_load_callback_ = model_load_callback; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state_ != NOT_RUNNING) { 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch model_load_callback.Run(type(), 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError(FROM_HERE, 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Model already running", 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type())); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = MODEL_STARTING; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StartModels()) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are waiting for some external service to load before associating 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or we failed to start the models, we exit early. state_ will control 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // what we perform next. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnModelLoaded(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::OnModelLoaded() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, MODEL_STARTING); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = MODEL_LOADED; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci model_load_callback_.Run(type(), syncer::SyncError()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::StartAssociating( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StartCallback& start_callback) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!start_callback.is_null()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, MODEL_LOADED); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_callback_ = start_callback; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = ASSOCIATING; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Associate()) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // It's possible StartDone(..) resulted in a Stop() call, or that 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // association failed, so we just verify that the state has moved forward. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(state_, ASSOCIATING); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, RUNNING); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::Stop() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (state_ == NOT_RUNNING) 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State prev_state = state_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = STOPPING; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If Stop() is called while Start() is waiting for the datatype model to 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load, abort the start. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prev_state == MODEL_STARTING) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AbortModelLoad(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can just return here since we haven't performed association if we're 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still in MODEL_STARTING. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanUpState(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_service_->DeactivateDataType(type()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (model_associator()) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError error; // Not used. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error = model_associator()->DisassociateModels(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_model_associator(NULL); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_processor_.reset(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = NOT_RUNNING; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::ModelSafeGroup FrontendDataTypeController::model_safe_group() 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::GROUP_UI; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string FrontendDataTypeController::name() const { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For logging only. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::ModelTypeToString(type()); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)sync_driver::DataTypeController::State FrontendDataTypeController::state() 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void FrontendDataTypeController::OnSingleDataTypeUnrecoverableError( 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const syncer::SyncError& error) { 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_EQ(type(), error.model_type()); 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RecordUnrecoverableError(error.location(), error.message()); 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!model_load_callback_.is_null()) { 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncMergeResult local_merge_result(type()); 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) local_merge_result.set_error(error); 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::MessageLoop::current()->PostTask( 1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(model_load_callback_, type(), error)); 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FrontendDataTypeController::FrontendDataTypeController() 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : DataTypeController(base::MessageLoopProxy::current(), base::Closure()), 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_sync_factory_(NULL), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(NULL), 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_service_(NULL), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_(NOT_RUNNING) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FrontendDataTypeController::~FrontendDataTypeController() { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FrontendDataTypeController::StartModels() { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, MODEL_STARTING); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // By default, no additional services need to be started before we can proceed 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with model association. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void FrontendDataTypeController::RecordUnrecoverableError( 176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const tracked_objects::Location& from_here, 177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& message) { 178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DVLOG(1) << "Datatype Controller failed for type " 179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << ModelTypeToString(type()) << " " 180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << message << " at location " 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << from_here.ToString(); 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ModelTypeToHistogramInt(type()), 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) syncer::MODEL_TYPE_COUNT); 185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!error_callback_.is_null()) 187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_callback_.Run(); 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FrontendDataTypeController::Associate() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(state_, ASSOCIATING); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult local_merge_result(type()); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult syncer_merge_result(type()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSyncComponents(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!model_associator()->CryptoReadyIfNecessary()) { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool sync_has_nodes = false; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError error(FROM_HERE, 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::UNRECOVERABLE_ERROR, 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Failed to load sync nodes", 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(zea): Have AssociateModels fill the local and syncer merge results. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time = base::TimeTicks::Now(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError error; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error = model_associator()->AssociateModels( 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &local_merge_result, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &syncer_merge_result); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(lipalani): crbug.com/122690 - handle abort. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAssociationTime(base::TimeTicks::Now() - start_time); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error.IsSet()) { 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = RUNNING; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FinishStart() invokes the DataTypeManager callback, which can lead to a 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call to Stop() if one of the other data types being started generates an 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error. 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return false if we're not in the RUNNING state (due to Stop() being called 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from FinishStart()). 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(zea/atwilson): Should we maybe move the call to FinishStart() out of 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Associate() and into Start(), so we don't need this logic here? It seems 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cleaner to call FinishStart() from Start(). 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_ == RUNNING; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::CleanUpState() { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing by default. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::CleanUp() { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanUpState(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_model_associator(NULL); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_processor_.reset(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::AbortModelLoad() { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanUp(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_ = NOT_RUNNING; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void FrontendDataTypeController::StartDone( 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ConfigureResult start_result, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!IsSuccessfulResult(start_result)) { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsUnrecoverableResult(start_result)) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordUnrecoverableError(FROM_HERE, "StartFailed"); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CleanUp(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (start_result == ASSOCIATION_FAILED) { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = DISABLED; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = NOT_RUNNING; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordStartFailure(start_result); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) start_callback_.Run(start_result, local_merge_result, syncer_merge_result); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PER_DATA_TYPE_MACRO(type_str) \ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYNC_DATA_TYPE_HISTOGRAM(type()); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PER_DATA_TYPE_MACRO 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ModelTypeToHistogramInt(type()), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::MODEL_TYPE_COUNT); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PER_DATA_TYPE_MACRO(type_str) \ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync." type_str "StartFailure", result, \ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAX_START_RESULT); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYNC_DATA_TYPE_HISTOGRAM(type()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PER_DATA_TYPE_MACRO 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)sync_driver::AssociatorInterface* FrontendDataTypeController::model_associator() 2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return model_associator_.get(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::set_model_associator( 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::AssociatorInterface* model_associator) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model_associator_.reset(model_associator); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)sync_driver::ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return change_processor_.get(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FrontendDataTypeController::set_change_processor( 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_driver::ChangeProcessor* change_processor) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_processor_.reset(change_processor); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 318