| // Copyright 2013 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. |
| |
| #ifndef COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ |
| #define COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/memory/weak_ptr.h" |
| #include "components/dom_distiller/core/article_distillation_update.h" |
| #include "components/dom_distiller/core/article_entry.h" |
| #include "components/dom_distiller/core/distiller.h" |
| #include "components/dom_distiller/core/proto/distilled_page.pb.h" |
| |
| class GURL; |
| |
| namespace dom_distiller { |
| |
| class DistilledArticleProto; |
| class DistilledContentStore; |
| |
| // A handle to a request to view a DOM distiller entry or URL. The request will |
| // be cancelled when the handle is destroyed. |
| class ViewerHandle { |
| public: |
| typedef base::Callback<void()> CancelCallback; |
| explicit ViewerHandle(CancelCallback callback); |
| ~ViewerHandle(); |
| |
| private: |
| CancelCallback cancel_callback_; |
| DISALLOW_COPY_AND_ASSIGN(ViewerHandle); |
| }; |
| |
| // Interface for a DOM distiller entry viewer. Implement this to make a view |
| // request and receive the data for an entry when it becomes available. |
| class ViewRequestDelegate { |
| public: |
| virtual ~ViewRequestDelegate() {} |
| // Called when the distilled article contents are available. The |
| // DistilledArticleProto is owned by a TaskTracker instance and is invalidated |
| // when the corresponding ViewerHandle is destroyed (or when the |
| // DomDistillerService is destroyed). |
| virtual void OnArticleReady(const DistilledArticleProto* article_proto) = 0; |
| |
| // Called when an article that is currently under distillation is updated. |
| virtual void OnArticleUpdated(ArticleDistillationUpdate article_update) = 0; |
| }; |
| |
| // A TaskTracker manages the various tasks related to viewing, saving, |
| // distilling, and fetching an article's distilled content. |
| // |
| // There are two sources of distilled content, a Distiller and the BlobFetcher. |
| // At any time, at most one of each of these will be in-progress (if one |
| // finishes, the other will be cancelled). |
| // |
| // There are also two consumers of that content, a view request and a save |
| // request. There is at most one save request (i.e. we are either adding this to |
| // the reading list or we aren't), and may be multiple view requests. When |
| // the distilled content is ready, each of these requests will be notified. |
| // |
| // A view request is cancelled by deleting the corresponding ViewerHandle. Once |
| // all view requests are cancelled (and the save callback has been called if |
| // appropriate) the cancel callback will be called. |
| // |
| // After creating a TaskTracker, a consumer of distilled content should be added |
| // and at least one of the sources should be started. |
| class TaskTracker { |
| public: |
| typedef base::Callback<void(TaskTracker*)> CancelCallback; |
| typedef base::Callback< |
| void(const ArticleEntry&, const DistilledArticleProto*, bool)> |
| SaveCallback; |
| |
| TaskTracker(const ArticleEntry& entry, |
| CancelCallback callback, |
| DistilledContentStore* content_store); |
| ~TaskTracker(); |
| |
| // |factory| will not be stored after this call. |
| void StartDistiller(DistillerFactory* factory, |
| scoped_ptr<DistillerPage> distiller_page); |
| void StartBlobFetcher(); |
| |
| void AddSaveCallback(const SaveCallback& callback); |
| |
| void CancelSaveCallbacks(); |
| |
| // The ViewerHandle should be destroyed before the ViewRequestDelegate. |
| scoped_ptr<ViewerHandle> AddViewer(ViewRequestDelegate* delegate); |
| |
| const std::string& GetEntryId() const; |
| bool HasEntryId(const std::string& entry_id) const; |
| bool HasUrl(const GURL& url) const; |
| |
| private: |
| void OnArticleDistillationUpdated( |
| const ArticleDistillationUpdate& article_update); |
| |
| void OnDistillerFinished(scoped_ptr<DistilledArticleProto> distilled_article); |
| void OnBlobFetched(bool success, |
| scoped_ptr<DistilledArticleProto> distilled_article); |
| |
| void RemoveViewer(ViewRequestDelegate* delegate); |
| |
| void DistilledArticleReady( |
| scoped_ptr<DistilledArticleProto> distilled_article); |
| |
| // Posts a task to run DoSaveCallbacks with |distillation_succeeded|. |
| void ScheduleSaveCallbacks(bool distillation_succeeded); |
| |
| // Runs all callbacks passing |distillation_succeeded| and clears them. |
| void DoSaveCallbacks(bool distillation_succeeded); |
| |
| void AddDistilledContentToStore(const DistilledArticleProto& content); |
| |
| void NotifyViewersAndCallbacks(); |
| void NotifyViewer(ViewRequestDelegate* delegate); |
| |
| bool IsAnySourceRunning() const; |
| void ContentSourceFinished(); |
| |
| void CancelPendingSources(); |
| void MaybeCancel(); |
| |
| CancelCallback cancel_callback_; |
| |
| DistilledContentStore* content_store_; |
| |
| std::vector<SaveCallback> save_callbacks_; |
| // A ViewRequestDelegate will be added to this list when a view request is |
| // made and removed when the corresponding ViewerHandle is destroyed. |
| std::vector<ViewRequestDelegate*> viewers_; |
| |
| scoped_ptr<Distiller> distiller_; |
| bool blob_fetcher_running_; |
| |
| ArticleEntry entry_; |
| scoped_ptr<DistilledArticleProto> distilled_article_; |
| |
| bool content_ready_; |
| |
| bool destruction_allowed_; |
| |
| // Note: This should remain the last member so it'll be destroyed and |
| // invalidate its weak pointers before any other members are destroyed. |
| base::WeakPtrFactory<TaskTracker> weak_ptr_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TaskTracker); |
| }; |
| |
| } // namespace dom_distiller |
| |
| #endif // COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ |