Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / typed_url_data_type_controller.cc
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.
4
5 #include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/metrics/histogram.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/history/history_db_task.h"
13 #include "chrome/browser/history/history_service.h"
14 #include "chrome/browser/history/history_service_factory.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
17 #include "chrome/browser/sync/glue/typed_url_change_processor.h"
18 #include "chrome/browser/sync/profile_sync_components_factory.h"
19 #include "chrome/browser/sync/profile_sync_service.h"
20 #include "chrome/common/pref_names.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_details.h"
23
24 namespace browser_sync {
25
26 using content::BrowserThread;
27
28 namespace {
29
30 // The history service exposes a special non-standard task API which calls back
31 // once a task has been dispatched, so we have to build a special wrapper around
32 // the tasks we want to run.
33 class RunTaskOnHistoryThread : public history::HistoryDBTask {
34  public:
35   explicit RunTaskOnHistoryThread(const base::Closure& task,
36                                   TypedUrlDataTypeController* dtc)
37       : task_(new base::Closure(task)),
38         dtc_(dtc) {
39   }
40
41   virtual bool RunOnDBThread(history::HistoryBackend* backend,
42                              history::HistoryDatabase* db) OVERRIDE {
43     // Set the backend, then release our reference before executing the task.
44     dtc_->SetBackend(backend);
45     dtc_ = NULL;
46
47     // Invoke the task, then free it immediately so we don't keep a reference
48     // around all the way until DoneRunOnMainThread() is invoked back on the
49     // main thread - we want to release references as soon as possible to avoid
50     // keeping them around too long during shutdown.
51     task_->Run();
52     task_.reset();
53     return true;
54   }
55
56   virtual void DoneRunOnMainThread() OVERRIDE {}
57
58  protected:
59   virtual ~RunTaskOnHistoryThread() {}
60
61   scoped_ptr<base::Closure> task_;
62   scoped_refptr<TypedUrlDataTypeController> dtc_;
63 };
64
65 }  // namespace
66
67 TypedUrlDataTypeController::TypedUrlDataTypeController(
68     ProfileSyncComponentsFactory* profile_sync_factory,
69     Profile* profile,
70     ProfileSyncService* sync_service)
71     : NonFrontendDataTypeController(
72           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
73           base::Bind(&ChromeReportUnrecoverableError),
74           profile_sync_factory,
75           profile,
76           sync_service),
77       backend_(NULL) {
78   pref_registrar_.Init(profile->GetPrefs());
79   pref_registrar_.Add(
80       prefs::kSavingBrowserHistoryDisabled,
81       base::Bind(
82           &TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged,
83           base::Unretained(this)));
84 }
85
86 syncer::ModelType TypedUrlDataTypeController::type() const {
87   return syncer::TYPED_URLS;
88 }
89
90 syncer::ModelSafeGroup TypedUrlDataTypeController::model_safe_group()
91     const {
92   return syncer::GROUP_HISTORY;
93 }
94
95 void TypedUrlDataTypeController::LoadModels(
96     const ModelLoadCallback& model_load_callback) {
97   if (profile()->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled)) {
98     model_load_callback.Run(
99         type(),
100         syncer::SyncError(FROM_HERE,
101                           syncer::SyncError::DATATYPE_ERROR,
102                           "History sync disabled by policy.",
103                           type()));
104     return;
105   }
106
107   set_state(MODEL_LOADED);
108   model_load_callback.Run(type(), syncer::SyncError());
109 }
110
111 void TypedUrlDataTypeController::SetBackend(history::HistoryBackend* backend) {
112   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
113   backend_ = backend;
114 }
115
116 void TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged() {
117   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118   if (profile()->GetPrefs()->GetBoolean(
119           prefs::kSavingBrowserHistoryDisabled)) {
120     // We've turned off history persistence, so if we are running,
121     // generate an unrecoverable error. This can be fixed by restarting
122     // Chrome (on restart, typed urls will not be a registered type).
123     if (state() != NOT_RUNNING && state() != STOPPING) {
124       syncer::SyncError error(
125           FROM_HERE,
126           syncer::SyncError::DATATYPE_POLICY_ERROR,
127           "History saving is now disabled by policy.",
128           syncer::TYPED_URLS);
129       OnSingleDataTypeUnrecoverableError(error);
130     }
131   }
132 }
133
134 bool TypedUrlDataTypeController::PostTaskOnBackendThread(
135     const tracked_objects::Location& from_here,
136     const base::Closure& task) {
137   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
138   HistoryService* history = HistoryServiceFactory::GetForProfile(
139       profile(), Profile::IMPLICIT_ACCESS);
140   if (history) {
141     history->ScheduleDBTask(
142         scoped_ptr<history::HistoryDBTask>(
143             new RunTaskOnHistoryThread(task, this)),
144         &task_tracker_);
145     return true;
146   } else {
147     // History must be disabled - don't start.
148     LOG(WARNING) << "Cannot access history service - disabling typed url sync";
149     return false;
150   }
151 }
152
153 ProfileSyncComponentsFactory::SyncComponents
154 TypedUrlDataTypeController::CreateSyncComponents() {
155   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
156   DCHECK_EQ(state(), ASSOCIATING);
157   DCHECK(backend_);
158   return profile_sync_factory()->CreateTypedUrlSyncComponents(
159       profile_sync_service(),
160       backend_,
161       this);
162 }
163
164 void TypedUrlDataTypeController::DisconnectProcessor(
165     sync_driver::ChangeProcessor* processor) {
166   static_cast<TypedUrlChangeProcessor*>(processor)->Disconnect();
167 }
168
169 TypedUrlDataTypeController::~TypedUrlDataTypeController() {}
170
171 }  // namespace browser_sync