This source file includes following definitions.
- weak_ptr_factory_
- StartDistiller
- StartBlobFetcher
- AddSaveCallback
- AddViewer
- GetEntryId
- HasEntryId
- HasUrl
- RemoveViewer
- MaybeCancel
- CancelSaveCallbacks
- ScheduleSaveCallbacks
- DoSaveCallbacks
- NotifyViewer
- OnDistillerFinished
- OnDistilledArticleReady
- OnArticleDistillationUpdated
#include "components/dom_distiller/core/task_tracker.h"
#include "base/auto_reset.h"
#include "base/message_loop/message_loop.h"
#include "components/dom_distiller/core/proto/distilled_article.pb.h"
#include "components/dom_distiller/core/proto/distilled_page.pb.h"
namespace dom_distiller {
ViewerHandle::ViewerHandle(CancelCallback callback)
: cancel_callback_(callback) {}
ViewerHandle::~ViewerHandle() {
if (!cancel_callback_.is_null()) {
cancel_callback_.Run();
}
}
TaskTracker::TaskTracker(const ArticleEntry& entry, CancelCallback callback)
: cancel_callback_(callback),
entry_(entry),
distilled_article_(),
content_ready_(false),
destruction_allowed_(true),
weak_ptr_factory_(this) {}
TaskTracker::~TaskTracker() {
DCHECK(destruction_allowed_);
DCHECK(viewers_.empty());
}
void TaskTracker::StartDistiller(DistillerFactory* factory) {
if (distiller_) {
return;
}
if (entry_.pages_size() == 0) {
return;
}
GURL url(entry_.pages(0).url());
DCHECK(url.is_valid());
distiller_ = factory->CreateDistiller();
distiller_->DistillPage(url,
base::Bind(&TaskTracker::OnDistillerFinished,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&TaskTracker::OnArticleDistillationUpdated,
weak_ptr_factory_.GetWeakPtr()));
}
void TaskTracker::StartBlobFetcher() {
}
void TaskTracker::AddSaveCallback(const SaveCallback& callback) {
DCHECK(!callback.is_null());
save_callbacks_.push_back(callback);
if (content_ready_) {
ScheduleSaveCallbacks(true);
}
}
scoped_ptr<ViewerHandle> TaskTracker::AddViewer(ViewRequestDelegate* delegate) {
viewers_.push_back(delegate);
if (content_ready_) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&TaskTracker::NotifyViewer,
weak_ptr_factory_.GetWeakPtr(),
delegate));
}
return scoped_ptr<ViewerHandle>(new ViewerHandle(base::Bind(
&TaskTracker::RemoveViewer, weak_ptr_factory_.GetWeakPtr(), delegate)));
}
const std::string& TaskTracker::GetEntryId() const { return entry_.entry_id(); }
bool TaskTracker::HasEntryId(const std::string& entry_id) const {
return entry_.entry_id() == entry_id;
}
bool TaskTracker::HasUrl(const GURL& url) const {
for (int i = 0; i < entry_.pages_size(); ++i) {
if (entry_.pages(i).url() == url.spec()) {
return true;
}
}
return false;
}
void TaskTracker::RemoveViewer(ViewRequestDelegate* delegate) {
viewers_.erase(std::remove(viewers_.begin(), viewers_.end(), delegate));
if (viewers_.empty()) {
MaybeCancel();
}
}
void TaskTracker::MaybeCancel() {
if (!save_callbacks_.empty() || !viewers_.empty()) {
return;
}
base::AutoReset<bool> dont_delete_this_in_callback(&destruction_allowed_,
false);
cancel_callback_.Run(this);
}
void TaskTracker::CancelSaveCallbacks() { ScheduleSaveCallbacks(false); }
void TaskTracker::ScheduleSaveCallbacks(bool distillation_succeeded) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&TaskTracker::DoSaveCallbacks,
weak_ptr_factory_.GetWeakPtr(),
distillation_succeeded));
}
void TaskTracker::DoSaveCallbacks(bool distillation_succeeded) {
if (!save_callbacks_.empty()) {
for (size_t i = 0; i < save_callbacks_.size(); ++i) {
DCHECK(!save_callbacks_[i].is_null());
save_callbacks_[i].Run(
entry_, distilled_article_.get(), distillation_succeeded);
}
save_callbacks_.clear();
MaybeCancel();
}
}
void TaskTracker::NotifyViewer(ViewRequestDelegate* delegate) {
DCHECK(content_ready_);
delegate->OnArticleReady(distilled_article_.get());
}
void TaskTracker::OnDistillerFinished(
scoped_ptr<DistilledArticleProto> distilled_article) {
OnDistilledArticleReady(distilled_article.Pass());
}
void TaskTracker::OnDistilledArticleReady(
scoped_ptr<DistilledArticleProto> distilled_article) {
distilled_article_ = distilled_article.Pass();
bool distillation_successful = false;
if (distilled_article_->pages_size() > 0) {
distillation_successful = true;
entry_.set_title(distilled_article_->title());
entry_.clear_pages();
for (int i = 0; i < distilled_article_->pages_size(); ++i) {
sync_pb::ArticlePage* page = entry_.add_pages();
page->set_url(distilled_article_->pages(i).url());
}
}
content_ready_ = true;
for (size_t i = 0; i < viewers_.size(); ++i) {
NotifyViewer(viewers_[i]);
}
DoSaveCallbacks(distillation_successful);
}
void TaskTracker::OnArticleDistillationUpdated(
const ArticleDistillationUpdate& article_update) {
for (size_t i = 0; i < viewers_.size(); ++i) {
viewers_[i]->OnArticleUpdated(article_update);
}
}
}