| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 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/privacy_blacklist/blacklist_manager.h" |
| 6 |
| 7 #include "base/message_loop.h" |
| 8 #include "base/task.h" |
| 9 #include "base/thread.h" |
| 10 #include "chrome/browser/privacy_blacklist/blacklist.h" |
| 11 #include "chrome/browser/privacy_blacklist/blacklist_io.h" |
| 12 #include "chrome/browser/profile.h" |
| 13 #include "chrome/common/chrome_constants.h" |
| 14 #include "chrome/common/notification_source.h" |
| 15 #include "chrome/common/notification_type.h" |
| 16 |
| 17 // Base class for tasks that use BlacklistManager. It ensures that the |
| 18 // BlacklistManager won't get destroyed while we need it, and that it |
| 19 // will be destroyed always on the same thread. That's why we use |
| 20 // a custom Task instead of just NewRunnableMethod. |
| 21 class BlacklistManagerTask : public Task { |
| 22 public: |
| 23 explicit BlacklistManagerTask(BlacklistManager* manager) |
| 24 : manager_(manager), |
| 25 original_loop_(MessageLoop::current()) { |
| 26 DCHECK(original_loop_); |
| 27 manager->AddRef(); |
| 28 } |
| 29 |
| 30 ~BlacklistManagerTask() { |
| 31 original_loop_->ReleaseSoon(FROM_HERE, manager_); |
| 32 } |
| 33 |
| 34 protected: |
| 35 BlacklistManager* blacklist_manager() const { return manager_; } |
| 36 |
| 37 private: |
| 38 BlacklistManager* manager_; |
| 39 |
| 40 MessageLoop* original_loop_; |
| 41 |
| 42 DISALLOW_COPY_AND_ASSIGN(BlacklistManagerTask); |
| 43 }; |
| 44 |
| 45 BlacklistPathProvider::~BlacklistPathProvider() { |
| 46 } |
| 47 |
| 48 class BlacklistManager::CompileBlacklistTask : public BlacklistManagerTask { |
| 49 public: |
| 50 CompileBlacklistTask(BlacklistManager* manager, |
| 51 const FilePath& destination_blacklist, |
| 52 const std::vector<FilePath>& source_blacklists) |
| 53 : BlacklistManagerTask(manager), |
| 54 destination_blacklist_(destination_blacklist), |
| 55 source_blacklists_(source_blacklists) { |
| 56 } |
| 57 |
| 58 virtual void Run() { |
| 59 BlacklistIO io; |
| 60 bool success = true; |
| 61 |
| 62 for (std::vector<FilePath>::const_iterator i = source_blacklists_.begin(); |
| 63 i != source_blacklists_.end(); ++i) { |
| 64 if (!io.Read(*i)) { |
| 65 success = false; |
| 66 break; |
| 67 } |
| 68 } |
| 69 |
| 70 // Only overwrite the current compiled blacklist if we read all source |
| 71 // files successfully. |
| 72 if (success) |
| 73 success = io.Write(destination_blacklist_); |
| 74 |
| 75 blacklist_manager()->OnBlacklistCompilationFinished(success); |
| 76 } |
| 77 |
| 78 private: |
| 79 FilePath destination_blacklist_; |
| 80 |
| 81 std::vector<FilePath> source_blacklists_; |
| 82 |
| 83 DISALLOW_COPY_AND_ASSIGN(CompileBlacklistTask); |
| 84 }; |
| 85 |
| 86 class BlacklistManager::ReadBlacklistTask : public BlacklistManagerTask { |
| 87 public: |
| 88 ReadBlacklistTask(BlacklistManager* manager, const FilePath& blacklist_path) |
| 89 : BlacklistManagerTask(manager), |
| 90 blacklist_path_(blacklist_path) { |
| 91 } |
| 92 |
| 93 virtual void Run() { |
| 94 Blacklist* blacklist = new Blacklist(blacklist_path_); |
| 95 blacklist_manager()->OnBlacklistReadFinished(blacklist); |
| 96 } |
| 97 |
| 98 private: |
| 99 FilePath blacklist_path_; |
| 100 |
| 101 DISALLOW_COPY_AND_ASSIGN(ReadBlacklistTask); |
| 102 }; |
| 103 |
| 104 BlacklistManager::BlacklistManager(Profile* profile, |
| 105 base::Thread* backend_thread) |
| 106 : compiled_blacklist_path_( |
| 107 profile->GetPath().Append(chrome::kPrivacyBlacklistFileName)), |
| 108 compiling_blacklist_(false), |
| 109 backend_thread_(backend_thread) { |
| 110 registrar_.Add(this, |
| 111 NotificationType::PRIVACY_BLACKLIST_PATH_PROVIDER_UPDATED, |
| 112 Source<Profile>(profile)); |
| 113 ReadBlacklist(); |
| 114 } |
| 115 |
| 116 void BlacklistManager::RegisterBlacklistPathProvider( |
| 117 BlacklistPathProvider* provider) { |
| 118 DCHECK(providers_.find(provider) == providers_.end()); |
| 119 providers_.insert(provider); |
| 120 } |
| 121 |
| 122 void BlacklistManager::UnregisterBlacklistPathProvider( |
| 123 BlacklistPathProvider* provider) { |
| 124 DCHECK(providers_.find(provider) != providers_.end()); |
| 125 providers_.erase(provider); |
| 126 } |
| 127 |
| 128 void BlacklistManager::Observe(NotificationType type, |
| 129 const NotificationSource& source, |
| 130 const NotificationDetails& details) { |
| 131 DCHECK(type == NotificationType::PRIVACY_BLACKLIST_PATH_PROVIDER_UPDATED); |
| 132 CompileBlacklist(); |
| 133 } |
| 134 |
| 135 void BlacklistManager::CompileBlacklist() { |
| 136 if (compiling_blacklist_) { |
| 137 // If we end up here, that means that initial compile succeeded, |
| 138 // but then we couldn't read back the resulting Blacklist. Return early |
| 139 // to avoid a potential infinite loop. |
| 140 // TODO(phajdan.jr): Report the error. |
| 141 compiling_blacklist_ = false; |
| 142 return; |
| 143 } |
| 144 |
| 145 compiling_blacklist_ = true; |
| 146 |
| 147 std::vector<FilePath> source_blacklists; |
| 148 |
| 149 for (ProvidersSet::iterator provider = providers_.begin(); |
| 150 provider != providers_.end(); ++provider) { |
| 151 std::vector<FilePath> provided_paths((*provider)->GetBlacklistPaths()); |
| 152 source_blacklists.insert(source_blacklists.end(), |
| 153 provided_paths.begin(), provided_paths.end()); |
| 154 } |
| 155 |
| 156 RunTaskOnBackendThread(new CompileBlacklistTask(this, compiled_blacklist_path_
, |
| 157 source_blacklists)); |
| 158 } |
| 159 |
| 160 void BlacklistManager::ReadBlacklist() { |
| 161 RunTaskOnBackendThread(new ReadBlacklistTask(this, compiled_blacklist_path_)); |
| 162 } |
| 163 |
| 164 void BlacklistManager::OnBlacklistCompilationFinished(bool success) { |
| 165 if (success) { |
| 166 ReadBlacklist(); |
| 167 } else { |
| 168 // TODO(phajdan.jr): Report the error. |
| 169 } |
| 170 } |
| 171 |
| 172 void BlacklistManager::OnBlacklistReadFinished(Blacklist* blacklist) { |
| 173 if (blacklist->is_good()) { |
| 174 compiled_blacklist_.reset(blacklist); |
| 175 compiling_blacklist_ = false; |
| 176 } else { |
| 177 delete blacklist; |
| 178 CompileBlacklist(); |
| 179 } |
| 180 } |
| 181 |
| 182 void BlacklistManager::RunTaskOnBackendThread(Task* task) { |
| 183 if (backend_thread_) { |
| 184 backend_thread_->message_loop()->PostTask(FROM_HERE, task); |
| 185 } else { |
| 186 task->Run(); |
| 187 delete task; |
| 188 } |
| 189 } |
| OLD | NEW |