| Index: chrome/browser/privacy_blacklist/blacklist_manager.cc
|
| diff --git a/chrome/browser/privacy_blacklist/blacklist_manager.cc b/chrome/browser/privacy_blacklist/blacklist_manager.cc
|
| index 4cad97bf33eaff8c8145c261ac6dada2da21c0fd..f7c93115dee4ada2ae7dddac0c3efb78b54dc887 100644
|
| --- a/chrome/browser/privacy_blacklist/blacklist_manager.cc
|
| +++ b/chrome/browser/privacy_blacklist/blacklist_manager.cc
|
| @@ -5,12 +5,14 @@
|
| #include "chrome/browser/privacy_blacklist/blacklist_manager.h"
|
|
|
| #include "base/message_loop.h"
|
| +#include "base/string_util.h"
|
| #include "base/task.h"
|
| #include "base/thread.h"
|
| #include "chrome/browser/privacy_blacklist/blacklist.h"
|
| #include "chrome/browser/privacy_blacklist/blacklist_io.h"
|
| #include "chrome/browser/profile.h"
|
| #include "chrome/common/chrome_constants.h"
|
| +#include "chrome/common/notification_service.h"
|
| #include "chrome/common/notification_source.h"
|
| #include "chrome/common/notification_type.h"
|
|
|
| @@ -21,8 +23,8 @@
|
| class BlacklistManagerTask : public Task {
|
| public:
|
| explicit BlacklistManagerTask(BlacklistManager* manager)
|
| - : manager_(manager),
|
| - original_loop_(MessageLoop::current()) {
|
| + : original_loop_(MessageLoop::current()),
|
| + manager_(manager) {
|
| DCHECK(original_loop_);
|
| manager->AddRef();
|
| }
|
| @@ -33,12 +35,12 @@ class BlacklistManagerTask : public Task {
|
|
|
| protected:
|
| BlacklistManager* blacklist_manager() const { return manager_; }
|
| +
|
| + MessageLoop* original_loop_;
|
|
|
| private:
|
| BlacklistManager* manager_;
|
|
|
| - MessageLoop* original_loop_;
|
| -
|
| DISALLOW_COPY_AND_ASSIGN(BlacklistManagerTask);
|
| };
|
|
|
| @@ -56,12 +58,14 @@ class BlacklistManager::CompileBlacklistTask : public BlacklistManagerTask {
|
| }
|
|
|
| virtual void Run() {
|
| - BlacklistIO io;
|
| bool success = true;
|
| +
|
| + Blacklist blacklist;
|
| + std::string error_string;
|
|
|
| for (std::vector<FilePath>::const_iterator i = source_blacklists_.begin();
|
| i != source_blacklists_.end(); ++i) {
|
| - if (!io.Read(*i)) {
|
| + if (!BlacklistIO::ReadText(&blacklist, *i, &error_string)) {
|
| success = false;
|
| break;
|
| }
|
| @@ -70,9 +74,13 @@ class BlacklistManager::CompileBlacklistTask : public BlacklistManagerTask {
|
| // Only overwrite the current compiled blacklist if we read all source
|
| // files successfully.
|
| if (success)
|
| - success = io.Write(destination_blacklist_);
|
| + success = BlacklistIO::WriteBinary(&blacklist, destination_blacklist_);
|
|
|
| - blacklist_manager()->OnBlacklistCompilationFinished(success);
|
| + original_loop_->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(blacklist_manager(),
|
| + &BlacklistManager::OnBlacklistCompilationFinished,
|
| + success));
|
| }
|
|
|
| private:
|
| @@ -85,98 +93,125 @@ class BlacklistManager::CompileBlacklistTask : public BlacklistManagerTask {
|
|
|
| class BlacklistManager::ReadBlacklistTask : public BlacklistManagerTask {
|
| public:
|
| - ReadBlacklistTask(BlacklistManager* manager, const FilePath& blacklist_path)
|
| + ReadBlacklistTask(BlacklistManager* manager,
|
| + const FilePath& compiled_blacklist,
|
| + const std::vector<FilePath>& transient_blacklists)
|
| : BlacklistManagerTask(manager),
|
| - blacklist_path_(blacklist_path) {
|
| + compiled_blacklist_(compiled_blacklist),
|
| + transient_blacklists_(transient_blacklists) {
|
| }
|
|
|
| virtual void Run() {
|
| - Blacklist* blacklist = new Blacklist(blacklist_path_);
|
| - blacklist_manager()->OnBlacklistReadFinished(blacklist);
|
| + scoped_ptr<Blacklist> blacklist(new Blacklist);
|
| + if (!BlacklistIO::ReadBinary(blacklist.get(), compiled_blacklist_)) {
|
| + ReportReadResult(NULL);
|
| + return;
|
| + }
|
| +
|
| + std::string error_string;
|
| + std::vector<FilePath>::const_iterator i;
|
| + for (i = transient_blacklists_.begin();
|
| + i != transient_blacklists_.end(); ++i) {
|
| + if (!BlacklistIO::ReadText(blacklist.get(), *i, &error_string)) {
|
| + ReportReadResult(NULL);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + ReportReadResult(blacklist.release());
|
| }
|
|
|
| private:
|
| - FilePath blacklist_path_;
|
| + void ReportReadResult(Blacklist* blacklist) {
|
| + original_loop_->PostTask(
|
| + FROM_HERE, NewRunnableMethod(blacklist_manager(),
|
| + &BlacklistManager::OnBlacklistReadFinished,
|
| + blacklist));
|
| + }
|
| +
|
| + FilePath compiled_blacklist_;
|
| + std::vector<FilePath> transient_blacklists_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ReadBlacklistTask);
|
| };
|
|
|
| BlacklistManager::BlacklistManager(Profile* profile,
|
| + BlacklistPathProvider* path_provider,
|
| base::Thread* backend_thread)
|
| - : compiled_blacklist_path_(
|
| + : first_read_finished_(false),
|
| + profile_(profile),
|
| + compiled_blacklist_path_(
|
| profile->GetPath().Append(chrome::kPrivacyBlacklistFileName)),
|
| - compiling_blacklist_(false),
|
| + path_provider_(path_provider),
|
| backend_thread_(backend_thread) {
|
| registrar_.Add(this,
|
| - NotificationType::PRIVACY_BLACKLIST_PATH_PROVIDER_UPDATED,
|
| + NotificationType::BLACKLIST_PATH_PROVIDER_UPDATED,
|
| Source<Profile>(profile));
|
| ReadBlacklist();
|
| }
|
|
|
| -void BlacklistManager::RegisterBlacklistPathProvider(
|
| - BlacklistPathProvider* provider) {
|
| - DCHECK(providers_.find(provider) == providers_.end());
|
| - providers_.insert(provider);
|
| -}
|
| -
|
| -void BlacklistManager::UnregisterBlacklistPathProvider(
|
| - BlacklistPathProvider* provider) {
|
| - DCHECK(providers_.find(provider) != providers_.end());
|
| - providers_.erase(provider);
|
| -}
|
| -
|
| void BlacklistManager::Observe(NotificationType type,
|
| const NotificationSource& source,
|
| const NotificationDetails& details) {
|
| - DCHECK(type == NotificationType::PRIVACY_BLACKLIST_PATH_PROVIDER_UPDATED);
|
| + DCHECK(type == NotificationType::BLACKLIST_PATH_PROVIDER_UPDATED);
|
| CompileBlacklist();
|
| }
|
|
|
| void BlacklistManager::CompileBlacklist() {
|
| - if (compiling_blacklist_) {
|
| - // If we end up here, that means that initial compile succeeded,
|
| - // but then we couldn't read back the resulting Blacklist. Return early
|
| - // to avoid a potential infinite loop.
|
| - // TODO(phajdan.jr): Report the error.
|
| - compiling_blacklist_ = false;
|
| - return;
|
| - }
|
| -
|
| - compiling_blacklist_ = true;
|
| -
|
| - std::vector<FilePath> source_blacklists;
|
| + DCHECK(CalledOnValidThread());
|
|
|
| - for (ProvidersSet::iterator provider = providers_.begin();
|
| - provider != providers_.end(); ++provider) {
|
| - std::vector<FilePath> provided_paths((*provider)->GetBlacklistPaths());
|
| - source_blacklists.insert(source_blacklists.end(),
|
| - provided_paths.begin(), provided_paths.end());
|
| - }
|
| -
|
| - RunTaskOnBackendThread(new CompileBlacklistTask(this, compiled_blacklist_path_,
|
| - source_blacklists));
|
| + RunTaskOnBackendThread(new CompileBlacklistTask(
|
| + this, compiled_blacklist_path_,
|
| + path_provider_->GetPersistentBlacklistPaths()));
|
| }
|
|
|
| void BlacklistManager::ReadBlacklist() {
|
| - RunTaskOnBackendThread(new ReadBlacklistTask(this, compiled_blacklist_path_));
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| + RunTaskOnBackendThread(new ReadBlacklistTask(
|
| + this, compiled_blacklist_path_,
|
| + path_provider_->GetTransientBlacklistPaths()));
|
| }
|
|
|
| void BlacklistManager::OnBlacklistCompilationFinished(bool success) {
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| if (success) {
|
| ReadBlacklist();
|
| } else {
|
| - // TODO(phajdan.jr): Report the error.
|
| + string16 error_message(ASCIIToUTF16("Blacklist compilation failed."));
|
| + NotificationService::current()->Notify(
|
| + NotificationType::BLACKLIST_MANAGER_ERROR,
|
| + Source<Profile>(profile_),
|
| + Details<string16>(&error_message));
|
| }
|
| }
|
|
|
| void BlacklistManager::OnBlacklistReadFinished(Blacklist* blacklist) {
|
| - if (blacklist->is_good()) {
|
| - compiled_blacklist_.reset(blacklist);
|
| - compiling_blacklist_ = false;
|
| - } else {
|
| - delete blacklist;
|
| - CompileBlacklist();
|
| + DCHECK(CalledOnValidThread());
|
| +
|
| + if (!blacklist) {
|
| + if (!first_read_finished_) {
|
| + // If we're loading for the first time, the compiled blacklist could
|
| + // just not exist. Try compiling it once.
|
| + first_read_finished_ = true;
|
| + CompileBlacklist();
|
| + } else {
|
| + string16 error_message(ASCIIToUTF16("Blacklist read failed."));
|
| + NotificationService::current()->Notify(
|
| + NotificationType::BLACKLIST_MANAGER_ERROR,
|
| + Source<Profile>(profile_),
|
| + Details<string16>(&error_message));
|
| + }
|
| + return;
|
| }
|
| + first_read_finished_ = true;
|
| + compiled_blacklist_.reset(blacklist);
|
| +
|
| + NotificationService::current()->Notify(
|
| + NotificationType::BLACKLIST_MANAGER_BLACKLIST_READ_FINISHED,
|
| + Source<Profile>(profile_),
|
| + Details<Blacklist>(blacklist));
|
| }
|
|
|
| void BlacklistManager::RunTaskOnBackendThread(Task* task) {
|
|
|