Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: components/offline_pages/downloads/download_ui_adapter.cc

Issue 2176013002: Add support for OfflinePagesDownloadBridge. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR feedback and tests. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "components/offline_pages/downloads/download_ui_adapter.h"
6
7 #include "base/bind.h"
8 #include "base/guid.h"
9 #include "base/logging.h"
10 #include "base/memory/ptr_util.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "components/offline_pages/client_namespace_constants.h"
13 #include "components/offline_pages/downloads/download_ui_item.h"
14 #include "components/offline_pages/offline_page_model.h"
15
16 namespace offline_pages {
17
18 DownloadUIAdapter::DownloadUIAdapter(OfflinePageModel* model)
19 : model_(model),
20 is_loaded_(false),
21 weak_ptr_factory_(this) {
22 }
23
24 DownloadUIAdapter::~DownloadUIAdapter() { }
25
26 void DownloadUIAdapter::AddObserver(Observer* observer) {
27 DCHECK(observer);
28 if (!observers_.might_have_observers())
29 LoadCache();
30 observers_.AddObserver(observer);
31 // If the items are already loaded, post the notification right away.
32 // Don't just invoke it from here to avoid reentrancy in the client.
33 if (is_loaded_) {
34 base::ThreadTaskRunnerHandle::Get()->PostTask(
35 FROM_HERE, base::Bind(&DownloadUIAdapter::NotifyItemsLoaded,
36 weak_ptr_factory_.GetWeakPtr(),
37 base::Unretained(observer)));
38 }
39 }
40
41 void DownloadUIAdapter::RemoveObserver(Observer* observer) {
42 observers_.RemoveObserver(observer);
43 // Once the last observer is gone, clear cached data.
44 if (!observers_.might_have_observers())
45 ClearCache();
46 }
47
48 void DownloadUIAdapter::OfflinePageModelLoaded(OfflinePageModel* model) {
49 // This signal is not used here.
50 }
51
52 void DownloadUIAdapter::OfflinePageModelChanged(OfflinePageModel* model) {
53 DCHECK(model == model_);
54 model_->GetAllPages(
55 base::Bind(&DownloadUIAdapter::OnOfflinePagesChanged,
56 weak_ptr_factory_.GetWeakPtr()));
57 }
58
59 void DownloadUIAdapter::OfflinePageDeleted(
60 int64_t offline_id, const ClientId& client_id) {
61 for(const auto& item : items_) {
62 if (item.second->guid == client_id.id) {
63 items_.erase(item.first);
64 FOR_EACH_OBSERVER(Observer, observers_, ItemDeleted(client_id.id));
65 return;
66 }
67 }
68 }
69
70 const DownloadUIItemsMap& DownloadUIAdapter::GetAllItems() const {
71 return items_;
72 }
73
74 const DownloadUIItem*
75 DownloadUIAdapter::GetItem(const std::string& guid) const {
76 DownloadUIItemsMap::const_iterator it = items_.find(guid);
77 if (it == items_.end())
78 return nullptr;
79 return (*it).second.get();
80 }
81
82 void DownloadUIAdapter::LoadCache() {
83 DCHECK(!is_loaded_);
84 // TODO(dimich): Add fetching from RequestQueue as well.
85 model_->AddObserver(this);
86 model_->GetAllPages(
87 base::Bind(&DownloadUIAdapter::OnOfflinePagesLoaded,
88 weak_ptr_factory_.GetWeakPtr()));
89 }
90
91 void DownloadUIAdapter::ClearCache() {
92 model_->RemoveObserver(this);
93 items_.clear();
94 is_loaded_ = false;
95 }
96
97 void DownloadUIAdapter::OnOfflinePagesLoaded(
98 const MultipleOfflinePageItemResult& pages) {
99 for (const auto& page : pages) {
100 if (IsVisibleInUI(page)) {
101 std::unique_ptr<DownloadUIItem> new_item(new DownloadUIItem(page));
102 DCHECK(items_.find(new_item->guid) == items_.end());
fgorski 2016/07/26 16:25:21 I like the idea below: const std::string& guid = p
Dmitry Titov 2016/07/26 19:56:48 Done.
103 items_[new_item->guid] = std::move(new_item);
104 }
105 }
106 is_loaded_ = true;
107 FOR_EACH_OBSERVER(Observer, observers_, ItemsLoaded());
108 }
109
110 void DownloadUIAdapter::NotifyItemsLoaded(Observer* observer) {
111 if (observer && observers_.HasObserver(observer))
112 observer->ItemsLoaded();
113 }
114
115 // This method is only called by OPM when a single item added.
116 // TODO(dimich): change OPM to have real OnPageAdded/OnPageUpdated and
117 // simplify this code.
118 void DownloadUIAdapter::OnOfflinePagesChanged(
119 const MultipleOfflinePageItemResult& pages) {
120 std::vector<std::string> added_guids;
121 for (const auto& page : pages) {
122 if (!IsVisibleInUI(page)) // Item should be filtered out.
123 continue;
124 const std::string& guid = page.client_id.id;
125 if (items_.find(guid) != items_.end()) // Item already exists.
126 continue;
127 std::unique_ptr<DownloadUIItem> item(new DownloadUIItem(page));
128 added_guids.push_back(guid);
fgorski 2016/07/26 16:25:21 nit: Can you move this line up or down? It feels l
Dmitry Titov 2016/07/26 19:56:48 Done.
129 items_[guid] = std::move(item);
130 }
131 // Only one added page
fgorski 2016/07/26 16:25:21 Interesting. Do we even need the update to be in t
Dmitry Titov 2016/07/26 19:56:48 I'd have it in interface. We will need it soon (in
132 CHECK(added_guids.size() <= 1);
133 for (auto& guid : added_guids) {
134 const DownloadUIItem& item = *(items_.find(guid)->second.get());
135 FOR_EACH_OBSERVER(Observer, observers_, ItemAdded(item));
136 }
137 }
138
139 bool DownloadUIAdapter::IsVisibleInUI(const OfflinePageItem& page) {
140 // TODO(dimich): set up the right filter here.
141 return page.client_id.name_space == kAsyncNamespace &&
142 base::IsValidGUID(page.client_id.id);
143 }
144
145 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698