1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// Copyright 2013 The Chromium Authors
// 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/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.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:
using CancelCallback = base::OnceCallback<void()>;
explicit ViewerHandle(CancelCallback callback);
~ViewerHandle();
ViewerHandle(const ViewerHandle&) = delete;
ViewerHandle& operator=(const ViewerHandle&) = delete;
private:
CancelCallback cancel_callback_;
};
// 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 base::CheckedObserver {
public:
~ViewRequestDelegate() override = default;
// 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:
using CancelCallback = base::OnceCallback<void(TaskTracker*)>;
using SaveCallback = base::OnceCallback<
void(const ArticleEntry&, const DistilledArticleProto*, bool)>;
TaskTracker(const ArticleEntry& entry,
CancelCallback callback,
DistilledContentStore* content_store);
~TaskTracker();
// |factory| will not be stored after this call.
void StartDistiller(DistillerFactory* factory,
std::unique_ptr<DistillerPage> distiller_page);
void StartBlobFetcher();
void AddSaveCallback(SaveCallback callback);
void CancelSaveCallbacks();
// The ViewerHandle should be destroyed before the ViewRequestDelegate.
std::unique_ptr<ViewerHandle> AddViewer(ViewRequestDelegate* delegate);
const std::string& GetEntryId() const;
bool HasEntryId(const std::string& entry_id) const;
bool HasUrl(const GURL& url) const;
TaskTracker(const TaskTracker&) = delete;
TaskTracker& operator=(const TaskTracker&) = delete;
private:
void OnArticleDistillationUpdated(
const ArticleDistillationUpdate& article_update);
void OnDistillerFinished(
std::unique_ptr<DistilledArticleProto> distilled_article);
void OnBlobFetched(bool success,
std::unique_ptr<DistilledArticleProto> distilled_article);
void RemoveViewer(ViewRequestDelegate* delegate);
void DistilledArticleReady(
std::unique_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_;
raw_ptr<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.
base::ObserverList<ViewRequestDelegate> viewers_;
std::unique_ptr<Distiller> distiller_;
bool blob_fetcher_running_;
ArticleEntry entry_;
std::unique_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_{this};
};
} // namespace dom_distiller
#endif // COMPONENTS_DOM_DISTILLER_CORE_TASK_TRACKER_H_
|