Index: components/previews/previews_black_list.cc |
diff --git a/components/previews/previews_black_list.cc b/components/previews/previews_black_list.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f4a70171da92e8eed293e0b721adb5a1483a3ff7 |
--- /dev/null |
+++ b/components/previews/previews_black_list.cc |
@@ -0,0 +1,108 @@ |
+// Copyright 2016 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 "components/previews/previews_black_list.h" |
+ |
+#include "base/bind.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/time/time.h" |
+#include "components/previews/previews_black_list_item.h" |
+#include "components/previews/previews_experiments.h" |
+#include "url/gurl.h" |
+ |
+namespace previews { |
+ |
+PreviewsBlackList::PreviewsBlackList( |
+ std::unique_ptr<PreviewsOptOutStore> opt_out_store) |
+ : loaded_(false), |
+ opt_out_store_(std::move(opt_out_store)), |
+ weak_factory_(this) { |
+ if (opt_out_store_) { |
+ opt_out_store_->LoadBlackList(base::Bind( |
+ &PreviewsBlackList::LoadBlackListDone, weak_factory_.GetWeakPtr())); |
+ } else { |
+ LoadBlackListDone(base::MakeUnique<BlackListItemMap>()); |
+ } |
+} |
+ |
+PreviewsBlackList::~PreviewsBlackList() {} |
+ |
+void PreviewsBlackList::AddPreviewNavigation(const GURL& url, |
+ bool opt_out, |
+ PreviewsType type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(url.has_host()); |
+ // If the |black_list_item_map_| has been loaded from |opt_out_store_|, |
+ // synchronous operations will be accurate. Otherwise, queue the task to run |
+ // asynchronously. |
+ if (loaded_) { |
+ AddPreviewNavigationSync(url, opt_out, type); |
+ } else { |
+ QueuePendingTask(base::Bind(&PreviewsBlackList::AddPreviewNavigationSync, |
+ base::Unretained(this), url, opt_out, type)); |
+ } |
+} |
+ |
+void PreviewsBlackList::AddPreviewNavigationSync(const GURL& url, |
+ bool opt_out, |
+ PreviewsType type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(url.has_host()); |
+ std::string host_name = url.host(); |
+ base::Time now = base::Time::Now(); |
+ GetBlackListItem(host_name, true)->AddPreviewNavigation(opt_out, now); |
+ if (!opt_out_store_) |
+ return; |
+ opt_out_store_->AddPreviewNavigation(opt_out, host_name, type, now); |
+} |
+ |
+bool PreviewsBlackList::IsLoadedAndAllowed(const GURL& url, PreviewsType type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(url.has_host()); |
+ std::string host_name = url.host(); |
+ if (!loaded_ || !previews::params::BlackListParamsAreValid()) |
+ return false; |
+ PreviewsBlackListItem* black_list_item = GetBlackListItem(host_name, false); |
+ return !black_list_item || !black_list_item->IsBlackListed(base::Time::Now()); |
+} |
+ |
+void PreviewsBlackList::QueuePendingTask(QueueClosure callback) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DCHECK(!callback.is_null()); |
+ pending_callbacks_.emplace(callback); |
+} |
+ |
+void PreviewsBlackList::LoadBlackListDone( |
+ std::unique_ptr<BlackListItemMap> black_list_item_map) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ loaded_ = true; |
+ black_list_item_map_ = std::move(black_list_item_map); |
+ |
+ // Run all pending tasks. |loaded_| may change if ClearBlackListIs queued. |
+ while (pending_callbacks_.size() > 0 && loaded_) { |
+ pending_callbacks_.front().Run(); |
+ pending_callbacks_.pop(); |
+ } |
+} |
+ |
+PreviewsBlackListItem* PreviewsBlackList::GetBlackListItem( |
+ const std::string& host_name, |
+ bool create_if_needed) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ BlackListItemMap::iterator iter = black_list_item_map_->find(host_name); |
+ if (iter != black_list_item_map_->end()) { |
+ return iter->second.get(); |
+ } |
+ if (!create_if_needed) |
+ return nullptr; |
+ // Create the item if it doesn't exist yet. |
+ PreviewsBlackListItem* black_list_item = new PreviewsBlackListItem( |
+ params::StoredHistoryLengthForBlackList(), |
+ params::BlackListOptOutThreshold(), params::BlackListDuration()); |
+ black_list_item_map_->operator[](host_name) = |
+ base::WrapUnique(black_list_item); |
+ return black_list_item; |
+} |
+ |
+} // namespace previews |