blob: fe7d137d58c5171f987ebce2080752ce7facd9c6 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sync/glue/typed_url_data_type_controller.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/history/history_db_task.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/glue/typed_url_change_processor.h"
#include "chrome/browser/sync/profile_sync_components_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
namespace browser_sync {
using content::BrowserThread;
namespace {
// The history service exposes a special non-standard task API which calls back
// once a task has been dispatched, so we have to build a special wrapper around
// the tasks we want to run.
class RunTaskOnHistoryThread : public history::HistoryDBTask {
public:
explicit RunTaskOnHistoryThread(const base::Closure& task,
TypedUrlDataTypeController* dtc)
: task_(new base::Closure(task)),
dtc_(dtc) {
}
virtual bool RunOnDBThread(history::HistoryBackend* backend,
history::HistoryDatabase* db) OVERRIDE {
// Set the backend, then release our reference before executing the task.
dtc_->SetBackend(backend);
dtc_ = NULL;
// Invoke the task, then free it immediately so we don't keep a reference
// around all the way until DoneRunOnMainThread() is invoked back on the
// main thread - we want to release references as soon as possible to avoid
// keeping them around too long during shutdown.
task_->Run();
task_.reset();
return true;
}
virtual void DoneRunOnMainThread() OVERRIDE {}
protected:
virtual ~RunTaskOnHistoryThread() {}
scoped_ptr<base::Closure> task_;
scoped_refptr<TypedUrlDataTypeController> dtc_;
};
} // namespace
TypedUrlDataTypeController::TypedUrlDataTypeController(
ProfileSyncComponentsFactory* profile_sync_factory,
Profile* profile,
ProfileSyncService* sync_service)
: NonFrontendDataTypeController(profile_sync_factory,
profile,
sync_service),
backend_(NULL) {
pref_registrar_.Init(profile->GetPrefs());
pref_registrar_.Add(
prefs::kSavingBrowserHistoryDisabled,
base::Bind(
&TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged,
base::Unretained(this)));
}
syncer::ModelType TypedUrlDataTypeController::type() const {
return syncer::TYPED_URLS;
}
syncer::ModelSafeGroup TypedUrlDataTypeController::model_safe_group()
const {
return syncer::GROUP_HISTORY;
}
void TypedUrlDataTypeController::SetBackend(history::HistoryBackend* backend) {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
backend_ = backend;
}
void TypedUrlDataTypeController::OnSavingBrowserHistoryDisabledChanged() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (profile()->GetPrefs()->GetBoolean(
prefs::kSavingBrowserHistoryDisabled)) {
// We've turned off history persistence, so if we are running,
// generate an unrecoverable error. This can be fixed by restarting
// Chrome (on restart, typed urls will not be a registered type).
if (state() != NOT_RUNNING && state() != STOPPING) {
profile_sync_service()->DisableBrokenDatatype(
syncer::TYPED_URLS,
FROM_HERE,
"History saving is now disabled by policy.");
}
}
}
bool TypedUrlDataTypeController::PostTaskOnBackendThread(
const tracked_objects::Location& from_here,
const base::Closure& task) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
HistoryService* history = HistoryServiceFactory::GetForProfile(
profile(), Profile::IMPLICIT_ACCESS);
if (history) {
history->ScheduleDBTask(new RunTaskOnHistoryThread(task, this),
&cancelable_consumer_);
return true;
} else {
// History must be disabled - don't start.
LOG(WARNING) << "Cannot access history service - disabling typed url sync";
return false;
}
}
ProfileSyncComponentsFactory::SyncComponents
TypedUrlDataTypeController::CreateSyncComponents() {
DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK_EQ(state(), ASSOCIATING);
DCHECK(backend_);
return profile_sync_factory()->CreateTypedUrlSyncComponents(
profile_sync_service(),
backend_,
this);
}
void TypedUrlDataTypeController::DisconnectProcessor(
ChangeProcessor* processor) {
static_cast<TypedUrlChangeProcessor*>(processor)->Disconnect();
}
TypedUrlDataTypeController::~TypedUrlDataTypeController() {}
} // namespace browser_sync