1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/sync_driver/non_ui_data_type_controller.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "components/sync_driver/generic_change_processor_factory.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/sync_driver/shared_change_processor_ref.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/sync_driver/sync_api_component_factory.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/sync_error.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/api/syncable_service.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/internal_api/public/base/model_type.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/util/data_type_histogram.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace sync_driver { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuSharedChangeProcessor* 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuNonUIDataTypeController::CreateSharedChangeProcessor() { 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return new SharedChangeProcessor(); 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NonUIDataTypeController::NonUIDataTypeController( 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> ui_thread, 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& error_callback, 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SyncApiComponentFactory* sync_factory) 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : DataTypeController(ui_thread, error_callback), 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sync_factory_(sync_factory), 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) state_(NOT_RUNNING), 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ui_thread_(ui_thread) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::LoadModels( 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ModelLoadCallback& model_load_callback) { 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci model_load_callback_ = model_load_callback; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state() != NOT_RUNNING) { 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch model_load_callback.Run(type(), 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError(FROM_HERE, 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Model already running", 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type())); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = MODEL_STARTING; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since we can't be called multiple times before Stop() is called, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |shared_change_processor_| must be NULL here. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!shared_change_processor_.get()); 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu shared_change_processor_ = CreateSharedChangeProcessor(); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(shared_change_processor_.get()); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!StartModels()) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we are waiting for some external service to load before associating 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // or we failed to start the models, we exit early. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnModelLoaded(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::OnModelLoaded() { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(state_, MODEL_STARTING); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = MODEL_LOADED; 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci model_load_callback_.Run(type(), syncer::SyncError()); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NonUIDataTypeController::StartModels() { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(state_, MODEL_STARTING); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // By default, no additional services need to be started before we can proceed 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with model association. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StopModels() { 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StartAssociating( 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StartCallback& start_callback) { 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!start_callback.is_null()); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(state_, MODEL_LOADED); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = ASSOCIATING; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_callback_ = start_callback; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!StartAssociationAsync()) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncError error( 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FROM_HERE, 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Failed to post StartAssociation", 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type()); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult local_merge_result(type()); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDoneImpl(ASSOCIATION_FAILED, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOT_RUNNING, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult(type())); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartDoneImpl should have called ClearSharedChangeProcessor(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!shared_change_processor_.get()); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::Stop() { 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (state() == NOT_RUNNING) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Disconnect the change processor. At this point, the 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // syncer::SyncableService can no longer interact with the Syncer, even if 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it hasn't finished MergeDataAndStartSyncing. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearSharedChangeProcessor(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we haven't finished starting, we need to abort the start. 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state()) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case MODEL_STARTING: 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = STOPPING; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AbortModelLoad(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // The datatype was never activated, we're done. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ASSOCIATING: 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = STOPPING; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We continue on to deactivate the datatype and stop the local service. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case MODEL_LOADED: 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DISABLED: 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If DTC is loaded or disabled, we never attempted or succeeded 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // associating and never activated the datatype. We would have already 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // stopped the local service in StartDoneImpl(..). 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = NOT_RUNNING; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopModels(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Datatype was fully started. Need to deactivate and stop the local 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // service. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(state(), RUNNING); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = STOPPING; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopModels(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop the local service and release our references to it and the 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // shared change processor (posts a task to the datatype's thread). 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopLocalServiceAsync(); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = NOT_RUNNING; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string NonUIDataTypeController::name() const { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For logging only. 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return syncer::ModelTypeToString(type()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DataTypeController::State NonUIDataTypeController::state() const { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return state_; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NonUIDataTypeController::OnSingleDataTypeUnrecoverableError( 1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const syncer::SyncError& error) { 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ui_thread_->BelongsToCurrentThread()); 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(tim): We double-upload some errors. See bug 383480. 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!error_callback_.is_null()) 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_callback_.Run(); 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ui_thread_->PostTask(error.location(), 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&NonUIDataTypeController::DisableImpl, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) error)); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NonUIDataTypeController::NonUIDataTypeController() 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : DataTypeController(base::MessageLoopProxy::current(), base::Closure()), 174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sync_factory_(NULL) {} 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NonUIDataTypeController::~NonUIDataTypeController() {} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StartDone( 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DataTypeController::ConfigureResult start_result, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result) { 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ui_thread_->BelongsToCurrentThread()); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::State new_state; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsSuccessfulResult(start_result)) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_state = RUNNING; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ui_thread_->PostTask(FROM_HERE, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&NonUIDataTypeController::StartDoneImpl, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_result, 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_state, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result)); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StartDoneImpl( 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DataTypeController::ConfigureResult start_result, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DataTypeController::State new_state, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& local_merge_result, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const syncer::SyncMergeResult& syncer_merge_result) { 205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we failed to start up, and we haven't been stopped yet, we need to 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ensure we clean up the local service and shared change processor properly. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClearSharedChangeProcessor(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopLocalServiceAsync(); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's possible to have StartDoneImpl called first from the UI thread 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (due to Stop being called) and then posted from the non-UI thread. In 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this case, we drop the second call because we've already been stopped. 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state_ == NOT_RUNNING) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = new_state; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state_ != RUNNING) { 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start failed. 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopModels(); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordStartFailure(start_result); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) start_callback_.Run(start_result, local_merge_result, syncer_merge_result); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::RecordAssociationTime(base::TimeDelta time) { 232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ui_thread_->BelongsToCurrentThread()); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PER_DATA_TYPE_MACRO(type_str) \ 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_DATA_TYPE_HISTOGRAM(type()); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef PER_DATA_TYPE_MACRO 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) { 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ModelTypeToHistogramInt(type()), 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::MODEL_TYPE_COUNT); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PER_DATA_TYPE_MACRO(type_str) \ 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync." type_str "StartFailure", result, \ 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MAX_START_RESULT); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_DATA_TYPE_HISTOGRAM(type()); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef PER_DATA_TYPE_MACRO 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::AbortModelLoad() { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) state_ = NOT_RUNNING; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopModels(); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::DisableImpl( 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const syncer::SyncError& error) { 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ModelTypeToHistogramInt(type()), 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::MODEL_TYPE_COUNT); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!model_load_callback_.is_null()) { 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncMergeResult local_merge_result(type()); 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) local_merge_result.set_error(error); 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci model_load_callback_.Run(type(), error); 2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NonUIDataTypeController::StartAssociationAsync() { 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(state(), ASSOCIATING); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PostTaskOnBackendThread( 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &NonUIDataTypeController::StartAssociationWithSharedChangeProcessor, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_change_processor_)); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const { 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(state_, RUNNING); 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return shared_change_processor_->generic_change_processor(); 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This method can execute after we've already stopped (and possibly even 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// destroyed) both the Syncer and the SyncableService. As a result, all actions 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// must either have no side effects outside of the DTC or must be protected 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// by |shared_change_processor|, which is guaranteed to have been Disconnected 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if the syncer shut down. 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController:: 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartAssociationWithSharedChangeProcessor( 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ui_thread_->BelongsToCurrentThread()); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(shared_change_processor.get()); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult local_merge_result(type()); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult syncer_merge_result(type()); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtrFactory<syncer::SyncMergeResult> weak_ptr_factory( 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &syncer_merge_result); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Connect |shared_change_processor| to the syncer and get the 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // syncer::SyncableService associated with type(). 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note that it's possible the shared_change_processor has already been 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // disconnected at this point, so all our accesses to the syncer from this 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // point on are through it. 305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GenericChangeProcessorFactory factory; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_service_ = shared_change_processor->Connect( 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sync_factory_, 308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &factory, 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) user_share(), 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type(), 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory.GetWeakPtr()); 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!local_service_.get()) { 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError error(FROM_HERE, 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Failed to connect to syncer.", 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type()); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(ASSOCIATION_FAILED, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shared_change_processor->CryptoReadyIfNecessary()) { 3266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncError error(FROM_HERE, 3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncError::CRYPTO_ERROR, 3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "", 3296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) type()); 3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) local_merge_result.set_error(error); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(NEEDS_CRYPTO, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool sync_has_nodes = false; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError error(FROM_HERE, 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::UNRECOVERABLE_ERROR, 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Failed to load sync nodes", 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch type()); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(UNRECOVERABLE_ERROR, 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks start_time = base::TimeTicks::Now(); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncDataList initial_sync_data; 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncError error = 35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) shared_change_processor->GetAllSyncDataReturnError( 35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) type(), &initial_sync_data); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error.IsSet()) { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result.set_error(error); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(ASSOCIATION_FAILED, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string datatype_context; 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (shared_change_processor->GetDataTypeContext(&datatype_context)) { 365a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch local_service_->UpdateDataTypeContext( 366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch type(), syncer::SyncChangeProcessor::NO_REFRESH, datatype_context); 367a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result.set_num_items_before_association( 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) initial_sync_data.size()); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Passes a reference to |shared_change_processor|. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result = 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_service_->MergeDataAndStartSyncing( 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type(), 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) initial_sync_data, 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor>( 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SharedChangeProcessorRef(shared_change_processor)), 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory>( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SharedChangeProcessorRef(shared_change_processor))); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RecordAssociationTime(base::TimeTicks::Now() - start_time); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (local_merge_result.error().IsSet()) { 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(ASSOCIATION_FAILED, 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result.set_num_items_after_association( 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_change_processor->GetSyncCount()); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_merge_result, 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer_merge_result); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::ClearSharedChangeProcessor() { 397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |shared_change_processor_| can already be NULL if Stop() is 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called after StartDoneImpl(_, DISABLED, _). 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (shared_change_processor_.get()) { 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_change_processor_->Disconnect(); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_change_processor_ = NULL; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StopLocalServiceAsync() { 407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(ui_thread_->BelongsToCurrentThread()); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostTaskOnBackendThread( 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&NonUIDataTypeController::StopLocalService, this)); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NonUIDataTypeController::StopLocalService() { 414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!ui_thread_->BelongsToCurrentThread()); 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (local_service_.get()) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_service_->StopSyncing(type()); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_service_.reset(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace sync_driver 421