Home | History | Annotate | Download | only in core
      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