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_DOM_DISTILLER_SERVICE_H_
6#define COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_SERVICE_H_
7
8#include <string>
9#include <vector>
10
11#include "base/callback.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/scoped_vector.h"
14#include "base/memory/weak_ptr.h"
15#include "components/dom_distiller/core/article_entry.h"
16#include "components/dom_distiller/core/distilled_page_prefs.h"
17#include "components/dom_distiller/core/distiller_page.h"
18
19class GURL;
20
21namespace syncer {
22class SyncableService;
23}
24
25namespace dom_distiller {
26
27class DistilledArticleProto;
28class DistilledContentStore;
29class DistillerFactory;
30class DistillerPageFactory;
31class DomDistillerObserver;
32class DomDistillerStoreInterface;
33class TaskTracker;
34class ViewerHandle;
35class ViewRequestDelegate;
36
37// Service for interacting with the Dom Distiller.
38// Construction, destruction, and usage of this service must happen on the same
39// thread. Callbacks will be called on that same thread.
40class DomDistillerServiceInterface {
41 public:
42  typedef base::Callback<void(bool)> ArticleAvailableCallback;
43  virtual ~DomDistillerServiceInterface() {}
44
45  virtual syncer::SyncableService* GetSyncableService() const = 0;
46
47  // Distill the article at |url| and add the resulting entry to the DOM
48  // distiller list. |article_cb| is always invoked, and the bool argument to it
49  // represents whether the article is available offline.
50  // Use CreateDefaultDistillerPage() to create a default |distiller_page|.
51  // The provided |distiller_page| is only used if there is not already a
52  // distillation task in progress for the given |url|.
53  virtual const std::string AddToList(
54      const GURL& url,
55      scoped_ptr<DistillerPage> distiller_page,
56      const ArticleAvailableCallback& article_cb) = 0;
57
58  // Returns whether an article stored has the given entry id.
59  virtual bool HasEntry(const std::string& entry_id) = 0;
60
61  // Returns the source URL given an entry ID. If the entry ID article has
62  // multiple pages, this will return the URL of the first page. Returns an
63  // empty string if there is no entry associated with the given entry ID.
64  virtual std::string GetUrlForEntry(const std::string& entry_id) = 0;
65
66  // Gets the full list of entries.
67  virtual std::vector<ArticleEntry> GetEntries() const = 0;
68
69  // Removes the specified entry from the dom distiller store.
70  virtual scoped_ptr<ArticleEntry> RemoveEntry(const std::string& entry_id) = 0;
71
72  // Request to view an article by entry id. Returns a null pointer if no entry
73  // with |entry_id| exists. The ViewerHandle should be destroyed before the
74  // ViewRequestDelegate. The request will be cancelled when the handle is
75  // destroyed (or when this service is destroyed), which also ensures that
76  // the |delegate| is not called after that.
77  // Use CreateDefaultDistillerPage() to create a default |distiller_page|.
78  // The provided |distiller_page| is only used if there is not already a
79  // distillation task in progress for the given |entry_id|.
80  virtual scoped_ptr<ViewerHandle> ViewEntry(
81      ViewRequestDelegate* delegate,
82      scoped_ptr<DistillerPage> distiller_page,
83      const std::string& entry_id) = 0;
84
85  // Request to view an article by url.
86  // Use CreateDefaultDistillerPage() to create a default |distiller_page|.
87  // The provided |distiller_page| is only used if there is not already a
88  // distillation task in progress for the given |url|.
89  virtual scoped_ptr<ViewerHandle> ViewUrl(
90      ViewRequestDelegate* delegate,
91      scoped_ptr<DistillerPage> distiller_page,
92      const GURL& url) = 0;
93
94  // Creates a default DistillerPage.
95  virtual scoped_ptr<DistillerPage> CreateDefaultDistillerPage(
96      const gfx::Size& render_view_size) = 0;
97  virtual scoped_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle(
98      scoped_ptr<SourcePageHandle> handle) = 0;
99
100  virtual void AddObserver(DomDistillerObserver* observer) = 0;
101  virtual void RemoveObserver(DomDistillerObserver* observer) = 0;
102
103  // Returns the DistilledPagePrefs owned by the instance of
104  // DomDistillerService.
105  virtual DistilledPagePrefs* GetDistilledPagePrefs() = 0;
106
107 protected:
108  DomDistillerServiceInterface() {}
109
110 private:
111  DISALLOW_COPY_AND_ASSIGN(DomDistillerServiceInterface);
112};
113
114// Provide a view of the article list and ways of interacting with it.
115class DomDistillerService : public DomDistillerServiceInterface {
116 public:
117  DomDistillerService(scoped_ptr<DomDistillerStoreInterface> store,
118                      scoped_ptr<DistillerFactory> distiller_factory,
119                      scoped_ptr<DistillerPageFactory> distiller_page_factory,
120                      scoped_ptr<DistilledPagePrefs> distilled_page_prefs);
121  virtual ~DomDistillerService();
122
123  // DomDistillerServiceInterface implementation.
124  virtual syncer::SyncableService* GetSyncableService() const OVERRIDE;
125  virtual const std::string AddToList(
126      const GURL& url,
127      scoped_ptr<DistillerPage> distiller_page,
128      const ArticleAvailableCallback& article_cb) OVERRIDE;
129  virtual bool HasEntry(const std::string& entry_id) OVERRIDE;
130  virtual std::string GetUrlForEntry(const std::string& entry_id) OVERRIDE;
131  virtual std::vector<ArticleEntry> GetEntries() const OVERRIDE;
132  virtual scoped_ptr<ArticleEntry> RemoveEntry(
133      const std::string& entry_id) OVERRIDE;
134  virtual scoped_ptr<ViewerHandle> ViewEntry(
135      ViewRequestDelegate* delegate,
136      scoped_ptr<DistillerPage> distiller_page,
137      const std::string& entry_id) OVERRIDE;
138  virtual scoped_ptr<ViewerHandle> ViewUrl(
139      ViewRequestDelegate* delegate,
140      scoped_ptr<DistillerPage> distiller_page,
141      const GURL& url) OVERRIDE;
142  virtual scoped_ptr<DistillerPage> CreateDefaultDistillerPage(
143      const gfx::Size& render_view_size) OVERRIDE;
144  virtual scoped_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle(
145      scoped_ptr<SourcePageHandle> handle) OVERRIDE;
146  virtual void AddObserver(DomDistillerObserver* observer) OVERRIDE;
147  virtual void RemoveObserver(DomDistillerObserver* observer) OVERRIDE;
148  virtual DistilledPagePrefs* GetDistilledPagePrefs() OVERRIDE;
149
150 private:
151  void CancelTask(TaskTracker* task);
152  void AddDistilledPageToList(const ArticleEntry& entry,
153                              const DistilledArticleProto* article_proto,
154                              bool distillation_succeeded);
155
156  TaskTracker* CreateTaskTracker(const ArticleEntry& entry);
157
158  TaskTracker* GetTaskTrackerForEntry(const ArticleEntry& entry) const;
159
160  // Gets the task tracker for the given |url| or |entry|. If no appropriate
161  // tracker exists, this will create one, initialize it, and add it to
162  // |tasks_|.
163  TaskTracker* GetOrCreateTaskTrackerForUrl(const GURL& url);
164  TaskTracker* GetOrCreateTaskTrackerForEntry(const ArticleEntry& entry);
165
166  scoped_ptr<DomDistillerStoreInterface> store_;
167  scoped_ptr<DistilledContentStore> content_store_;
168  scoped_ptr<DistillerFactory> distiller_factory_;
169  scoped_ptr<DistillerPageFactory> distiller_page_factory_;
170  scoped_ptr<DistilledPagePrefs> distilled_page_prefs_;
171
172  typedef ScopedVector<TaskTracker> TaskList;
173  TaskList tasks_;
174
175  DISALLOW_COPY_AND_ASSIGN(DomDistillerService);
176};
177
178}  // namespace dom_distiller
179
180#endif  // COMPONENTS_DOM_DISTILLER_CORE_DOM_DISTILLER_SERVICE_H_
181