app_data_type_controller.cc revision bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync/glue/app_data_type_controller.h"
6
7#include "base/histogram.h"
8#include "base/logging.h"
9#include "base/time.h"
10#include "chrome/browser/chrome_thread.h"
11#include "chrome/browser/profile.h"
12#include "chrome/browser/sync/profile_sync_service.h"
13#include "chrome/browser/sync/profile_sync_factory.h"
14#include "chrome/browser/sync/unrecoverable_error_handler.h"
15
16namespace browser_sync {
17
18AppDataTypeController::AppDataTypeController(
19    ProfileSyncFactory* profile_sync_factory,
20    Profile* profile,
21    ProfileSyncService* sync_service)
22    : profile_sync_factory_(profile_sync_factory),
23      profile_(profile),
24      sync_service_(sync_service),
25      state_(NOT_RUNNING) {
26  DCHECK(profile_sync_factory);
27  DCHECK(sync_service);
28}
29
30AppDataTypeController::~AppDataTypeController() {
31}
32
33void AppDataTypeController::Start(StartCallback* start_callback) {
34  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
35  DCHECK(start_callback);
36  if (state_ != NOT_RUNNING) {
37    start_callback->Run(BUSY);
38    delete start_callback;
39    return;
40  }
41
42  start_callback_.reset(start_callback);
43
44  profile_->InitExtensions();
45  ProfileSyncFactory::SyncComponents sync_components =
46      profile_sync_factory_->CreateAppSyncComponents(sync_service_,
47                                                     this);
48  model_associator_.reset(sync_components.model_associator);
49  change_processor_.reset(sync_components.change_processor);
50
51  bool sync_has_nodes = false;
52  if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) {
53    StartFailed(UNRECOVERABLE_ERROR);
54    return;
55  }
56
57  base::TimeTicks start_time = base::TimeTicks::Now();
58  bool merge_success = model_associator_->AssociateModels();
59  UMA_HISTOGRAM_TIMES("Sync.AppAssociationTime",
60                      base::TimeTicks::Now() - start_time);
61  if (!merge_success) {
62    StartFailed(ASSOCIATION_FAILED);
63    return;
64  }
65
66  sync_service_->ActivateDataType(this, change_processor_.get());
67  state_ = RUNNING;
68  FinishStart(!sync_has_nodes ? OK_FIRST_RUN : OK);
69}
70
71void AppDataTypeController::Stop() {
72  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
73
74  if (change_processor_ != NULL)
75    sync_service_->DeactivateDataType(this, change_processor_.get());
76
77  if (model_associator_ != NULL)
78    model_associator_->DisassociateModels();
79
80  change_processor_.reset();
81  model_associator_.reset();
82  start_callback_.reset();
83
84  state_ = NOT_RUNNING;
85}
86
87void AppDataTypeController::OnUnrecoverableError(
88    const tracked_objects::Location& from_here,
89    const std::string& message) {
90  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
91  UMA_HISTOGRAM_COUNTS("Sync.AppRunFailures", 1);
92  sync_service_->OnUnrecoverableError(from_here, message);
93}
94
95void AppDataTypeController::FinishStart(StartResult result) {
96  start_callback_->Run(result);
97  start_callback_.reset();
98}
99
100void AppDataTypeController::StartFailed(StartResult result) {
101  model_associator_.reset();
102  change_processor_.reset();
103  start_callback_->Run(result);
104  start_callback_.reset();
105  UMA_HISTOGRAM_ENUMERATION("Sync.AppStartFailures",
106                            result,
107                            MAX_START_RESULT);
108}
109
110}  // namespace browser_sync
111