Upstream version 5.34.104.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::SetBackend(history::HistoryBackend* backend) {
96   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
97   backend_ = backend;
98 }
99
100 void TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged() {
101   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102   if (profile()->GetPrefs()->GetBoolean(
103           prefs::kSavingBrowserHistoryDisabled)) {
104     // We've turned off history persistence, so if we are running,
105     // generate an unrecoverable error. This can be fixed by restarting
106     // Chrome (on restart, typed urls will not be a registered type).
107     if (state() != NOT_RUNNING && state() != STOPPING) {
108       profile_sync_service()->DisableBrokenDatatype(
109           syncer::TYPED_URLS,
110           FROM_HERE,
111           "History saving is now disabled by policy.");
112     }
113   }
114 }
115
116 bool TypedUrlDataTypeController::PostTaskOnBackendThread(
117     const tracked_objects::Location& from_here,
118     const base::Closure& task) {
119   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120   HistoryService* history = HistoryServiceFactory::GetForProfile(
121       profile(), Profile::IMPLICIT_ACCESS);
122   if (history) {
123     history->ScheduleDBTask(new RunTaskOnHistoryThread(task, this),
124                             &cancelable_consumer_);
125     return true;
126   } else {
127     // History must be disabled - don't start.
128     LOG(WARNING) << "Cannot access history service - disabling typed url sync";
129     return false;
130   }
131 }
132
133 ProfileSyncComponentsFactory::SyncComponents
134 TypedUrlDataTypeController::CreateSyncComponents() {
135   DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
136   DCHECK_EQ(state(), ASSOCIATING);
137   DCHECK(backend_);
138   return profile_sync_factory()->CreateTypedUrlSyncComponents(
139       profile_sync_service(),
140       backend_,
141       this);
142 }
143
144 void TypedUrlDataTypeController::DisconnectProcessor(
145     ChangeProcessor* processor) {
146   static_cast<TypedUrlChangeProcessor*>(processor)->Disconnect();
147 }
148
149 TypedUrlDataTypeController::~TypedUrlDataTypeController() {}
150
151 }  // namespace browser_sync