1 // Copyright 2013 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 #ifndef COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ 6 #define COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/bind.h" 12 #include "base/callback.h" 13 #include "base/memory/weak_ptr.h" 14 #include "components/dom_distiller/core/article_distillation_update.h" 15 #include "components/dom_distiller/core/article_entry.h" 16 #include "components/dom_distiller/core/distiller.h" 17 #include "components/dom_distiller/core/proto/distilled_page.pb.h" 18 19 class GURL; 20 21 namespace dom_distiller { 22 23 class DistilledArticleProto; 24 class DistilledContentStore; 25 26 // A handle to a request to view a DOM distiller entry or URL. The request will 27 // be cancelled when the handle is destroyed. 28 class ViewerHandle { 29 public: 30 typedef base::Callback<void()> CancelCallback; 31 explicit ViewerHandle(CancelCallback callback); 32 ~ViewerHandle(); 33 34 private: 35 CancelCallback cancel_callback_; 36 DISALLOW_COPY_AND_ASSIGN(ViewerHandle); 37 }; 38 39 // Interface for a DOM distiller entry viewer. Implement this to make a view 40 // request and receive the data for an entry when it becomes available. 41 class ViewRequestDelegate { 42 public: 43 virtual ~ViewRequestDelegate() {} 44 // Called when the distilled article contents are available. The 45 // DistilledArticleProto is owned by a TaskTracker instance and is invalidated 46 // when the corresponding ViewerHandle is destroyed (or when the 47 // DomDistillerService is destroyed). 48 virtual void OnArticleReady(const DistilledArticleProto* article_proto) = 0; 49 50 // Called when an article that is currently under distillation is updated. 51 virtual void OnArticleUpdated(ArticleDistillationUpdate article_update) = 0; 52 }; 53 54 // A TaskTracker manages the various tasks related to viewing, saving, 55 // distilling, and fetching an article's distilled content. 56 // 57 // There are two sources of distilled content, a Distiller and the BlobFetcher. 58 // At any time, at most one of each of these will be in-progress (if one 59 // finishes, the other will be cancelled). 60 // 61 // There are also two consumers of that content, a view request and a save 62 // request. There is at most one save request (i.e. we are either adding this to 63 // the reading list or we aren't), and may be multiple view requests. When 64 // the distilled content is ready, each of these requests will be notified. 65 // 66 // A view request is cancelled by deleting the corresponding ViewerHandle. Once 67 // all view requests are cancelled (and the save callback has been called if 68 // appropriate) the cancel callback will be called. 69 // 70 // After creating a TaskTracker, a consumer of distilled content should be added 71 // and at least one of the sources should be started. 72 class TaskTracker { 73 public: 74 typedef base::Callback<void(TaskTracker*)> CancelCallback; 75 typedef base::Callback< 76 void(const ArticleEntry&, const DistilledArticleProto*, bool)> 77 SaveCallback; 78 79 TaskTracker(const ArticleEntry& entry, 80 CancelCallback callback, 81 DistilledContentStore* content_store); 82 ~TaskTracker(); 83 84 // |factory| will not be stored after this call. 85 void StartDistiller(DistillerFactory* factory, 86 scoped_ptr<DistillerPage> distiller_page); 87 void StartBlobFetcher(); 88 89 void AddSaveCallback(const SaveCallback& callback); 90 91 void CancelSaveCallbacks(); 92 93 // The ViewerHandle should be destroyed before the ViewRequestDelegate. 94 scoped_ptr<ViewerHandle> AddViewer(ViewRequestDelegate* delegate); 95 96 const std::string& GetEntryId() const; 97 bool HasEntryId(const std::string& entry_id) const; 98 bool HasUrl(const GURL& url) const; 99 100 private: 101 void OnArticleDistillationUpdated( 102 const ArticleDistillationUpdate& article_update); 103 104 void OnDistillerFinished(scoped_ptr<DistilledArticleProto> distilled_article); 105 void OnBlobFetched(bool success, 106 scoped_ptr<DistilledArticleProto> distilled_article); 107 108 void RemoveViewer(ViewRequestDelegate* delegate); 109 110 void DistilledArticleReady( 111 scoped_ptr<DistilledArticleProto> distilled_article); 112 113 // Posts a task to run DoSaveCallbacks with |distillation_succeeded|. 114 void ScheduleSaveCallbacks(bool distillation_succeeded); 115 116 // Runs all callbacks passing |distillation_succeeded| and clears them. 117 void DoSaveCallbacks(bool distillation_succeeded); 118 119 void AddDistilledContentToStore(const DistilledArticleProto& content); 120 121 void NotifyViewersAndCallbacks(); 122 void NotifyViewer(ViewRequestDelegate* delegate); 123 124 bool IsAnySourceRunning() const; 125 void ContentSourceFinished(); 126 127 void CancelPendingSources(); 128 void MaybeCancel(); 129 130 CancelCallback cancel_callback_; 131 132 DistilledContentStore* content_store_; 133 134 std::vector<SaveCallback> save_callbacks_; 135 // A ViewRequestDelegate will be added to this list when a view request is 136 // made and removed when the corresponding ViewerHandle is destroyed. 137 std::vector<ViewRequestDelegate*> viewers_; 138 139 scoped_ptr<Distiller> distiller_; 140 bool blob_fetcher_running_; 141 142 ArticleEntry entry_; 143 scoped_ptr<DistilledArticleProto> distilled_article_; 144 145 bool content_ready_; 146 147 bool destruction_allowed_; 148 149 // Note: This should remain the last member so it'll be destroyed and 150 // invalidate its weak pointers before any other members are destroyed. 151 base::WeakPtrFactory<TaskTracker> weak_ptr_factory_; 152 153 DISALLOW_COPY_AND_ASSIGN(TaskTracker); 154 }; 155 156 } // namespace dom_distiller 157 158 #endif // COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_ 159