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

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

Issue 2489443002: Move all components/offline_pages/ files into component/offline_pages/core (Closed)
Patch Set: rebase Created 4 years 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/client_policy_controller.h"
14 #include "components/offline_pages/downloads/download_ui_item.h"
15 #include "components/offline_pages/offline_page_model.h"
16
17 namespace offline_pages {
18
19 namespace {
20 const char kDownloadUIAdapterKey[] = "download-ui-adapter";
21 }
22
23 DownloadUIAdapter::ItemInfo::ItemInfo(const OfflinePageItem& page)
24 : ui_item(base::MakeUnique<DownloadUIItem>(page)),
25 offline_id(page.offline_id) {}
26
27 DownloadUIAdapter::ItemInfo::~ItemInfo() {}
28
29 DownloadUIAdapter::DownloadUIAdapter(OfflinePageModel* model)
30 : model_(model),
31 state_(State::NOT_LOADED),
32 observers_count_(0),
33 weak_ptr_factory_(this) {
34 }
35
36 DownloadUIAdapter::~DownloadUIAdapter() { }
37
38 // static
39 DownloadUIAdapter* DownloadUIAdapter::FromOfflinePageModel(
40 OfflinePageModel* offline_page_model) {
41 DownloadUIAdapter* adapter = static_cast<DownloadUIAdapter*>(
42 offline_page_model->GetUserData(kDownloadUIAdapterKey));
43 if (!adapter) {
44 adapter = new DownloadUIAdapter(offline_page_model);
45 offline_page_model->SetUserData(kDownloadUIAdapterKey, adapter);
46 }
47 return adapter;
48 }
49
50 void DownloadUIAdapter::AddObserver(Observer* observer) {
51 DCHECK(observer);
52 if (observers_.HasObserver(observer))
53 return;
54 if (observers_count_ == 0)
55 LoadCache();
56 observers_.AddObserver(observer);
57 ++observers_count_;
58 // If the items are already loaded, post the notification right away.
59 // Don't just invoke it from here to avoid reentrancy in the client.
60 if (state_ == State::LOADED) {
61 base::ThreadTaskRunnerHandle::Get()->PostTask(
62 FROM_HERE, base::Bind(&DownloadUIAdapter::NotifyItemsLoaded,
63 weak_ptr_factory_.GetWeakPtr(),
64 base::Unretained(observer)));
65 }
66 }
67
68 void DownloadUIAdapter::RemoveObserver(Observer* observer) {
69 DCHECK(observer);
70 if (!observers_.HasObserver(observer))
71 return;
72 observers_.RemoveObserver(observer);
73 --observers_count_;
74 // Once the last observer is gone, clear cached data.
75 if (observers_count_ == 0)
76 ClearCache();
77 }
78
79 void DownloadUIAdapter::OfflinePageModelLoaded(OfflinePageModel* model) {
80 // This signal is not used here.
81 }
82
83 void DownloadUIAdapter::OfflinePageModelChanged(OfflinePageModel* model) {
84 DCHECK(model == model_);
85 model_->GetAllPages(
86 base::Bind(&DownloadUIAdapter::OnOfflinePagesChanged,
87 weak_ptr_factory_.GetWeakPtr()));
88 }
89
90 void DownloadUIAdapter::OfflinePageDeleted(
91 int64_t offline_id, const ClientId& client_id) {
92 if (!IsVisibleInUI(client_id))
93 return;
94 std::string guid = client_id.id;
95 DownloadUIItems::const_iterator it = items_.find(guid);
96 if (it == items_.end())
97 return;
98 items_.erase(it);
99 for (Observer& observer : observers_)
100 observer.ItemDeleted(guid);
101 }
102
103 std::vector<const DownloadUIItem*> DownloadUIAdapter::GetAllItems() const {
104 std::vector<const DownloadUIItem*> result;
105 for (const auto& item : items_)
106 result.push_back(item.second->ui_item.get());
107 return result;
108 }
109
110 const DownloadUIItem*
111 DownloadUIAdapter::GetItem(const std::string& guid) const {
112 DownloadUIItems::const_iterator it = items_.find(guid);
113 if (it == items_.end())
114 return nullptr;
115 return it->second->ui_item.get();
116 }
117
118 void DownloadUIAdapter::DeleteItem(const std::string& guid) {
119 // TODO(dimich): Also remove pending request from RequestQueue.
120 DownloadUIItems::const_iterator it = items_.find(guid);
121 if (it == items_.end())
122 return;
123
124 std::vector<int64_t> page_ids;
125 page_ids.push_back(it->second->offline_id);
126 model_->DeletePagesByOfflineId(
127 page_ids, base::Bind(&DownloadUIAdapter::OnDeletePagesDone,
128 weak_ptr_factory_.GetWeakPtr()));
129 }
130
131 int64_t DownloadUIAdapter::GetOfflineIdByGuid(
132 const std::string& guid) const {
133 // TODO(dimich): when requests are also in the cache, filter them out.
134 // Requests do not yet have offline ID.
135 DownloadUIItems::const_iterator it = items_.find(guid);
136 if (it != items_.end())
137 return it->second->offline_id;
138 return 0;
139 }
140
141 // Note that several LoadCache calls may be issued before the async GetAllPages
142 // comes back.
143 void DownloadUIAdapter::LoadCache() {
144 // TODO(dimich): Add fetching from RequestQueue as well.
145 state_ = State::LOADING;
146 model_->GetAllPages(
147 base::Bind(&DownloadUIAdapter::OnOfflinePagesLoaded,
148 weak_ptr_factory_.GetWeakPtr()));
149 }
150
151 void DownloadUIAdapter::ClearCache() {
152 // Once loaded, this class starts to observe the model. Only remove observer
153 // if it was added.
154 if (state_ == State::LOADED)
155 model_->RemoveObserver(this);
156 items_.clear();
157 state_ = State::NOT_LOADED;
158 }
159
160 void DownloadUIAdapter::OnOfflinePagesLoaded(
161 const MultipleOfflinePageItemResult& pages) {
162 // If multiple observers register quickly, the cache might be already loaded
163 // by the previous LoadCache call. At the same time, if all observers already
164 // left, there is no reason to populate the cache.
165 if (state_ != State::LOADING)
166 return;
167 for (const auto& page : pages) {
168 if (IsVisibleInUI(page.client_id)) {
169 std::string guid = page.client_id.id;
170 DCHECK(items_.find(guid) == items_.end());
171 items_[guid] = base::MakeUnique<ItemInfo>(page);
172 }
173 }
174 model_->AddObserver(this);
175 state_ = State::LOADED;
176 for (Observer& observer : observers_)
177 observer.ItemsLoaded();
178 }
179
180 void DownloadUIAdapter::NotifyItemsLoaded(Observer* observer) {
181 if (observer && observers_.HasObserver(observer))
182 observer->ItemsLoaded();
183 }
184
185 // This method is only called by OPM when a single item added.
186 // TODO(dimich): change OPM to have real OnPageAdded/OnPageUpdated and
187 // simplify this code.
188 void DownloadUIAdapter::OnOfflinePagesChanged(
189 const MultipleOfflinePageItemResult& pages) {
190 std::vector<std::string> added_guids;
191 for (const auto& page : pages) {
192 if (!IsVisibleInUI(page.client_id)) // Item should be filtered out.
193 continue;
194 const std::string& guid = page.client_id.id;
195 if (items_.find(guid) != items_.end()) // Item already exists.
196 continue;
197 items_[guid] = base::MakeUnique<ItemInfo>(page);
198 added_guids.push_back(guid);
199 }
200 for (auto& guid : added_guids) {
201 const DownloadUIItem& item = *(items_.find(guid)->second->ui_item.get());
202 for (Observer& observer : observers_)
203 observer.ItemAdded(item);
204 }
205 }
206
207 void DownloadUIAdapter::OnDeletePagesDone(DeletePageResult result) {
208 // TODO(dimich): Consider adding UMA to record user actions.
209 }
210
211 bool DownloadUIAdapter::IsVisibleInUI(const ClientId& client_id) {
212 const std::string& name_space = client_id.name_space;
213 return model_->GetPolicyController()->IsSupportedByDownload(name_space) &&
214 base::IsValidGUID(client_id.id);
215 }
216
217 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698