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

Side by Side Diff: components/ntp_snippets/physical_web_pages/physical_web_page_suggestions_provider.cc

Issue 2517113005: [NTP::PhysicalWeb] Wire Physical Web provider to the data source. (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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h" 5 #include "components/ntp_snippets/physical_web_pages/physical_web_page_suggestio ns_provider.h"
6 6
7 #include <algorithm>
8 #include <memory>
9 #include <string>
7 #include <utility> 10 #include <utility>
8 11
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
13 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
14 #include "grit/components_strings.h" 17 #include "grit/components_strings.h"
15 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/gfx/image/image.h" 19 #include "ui/gfx/image/image.h"
20 #include "url/gurl.h"
21
22 using base::DictionaryValue;
23 using base::ListValue;
24 using base::Value;
17 25
18 namespace ntp_snippets { 26 namespace ntp_snippets {
19 27
20 namespace { 28 namespace {
21 29
22 const size_t kMaxSuggestionsCount = 10; 30 const size_t kMaxSuggestionsCount = 10;
23 31
24 } // namespace 32 } // namespace
25 33
26 // TODO(vitaliii): remove when Physical Web C++ interface is provided.
27 UrlInfo::UrlInfo() = default;
28 UrlInfo::~UrlInfo() = default;
29 UrlInfo::UrlInfo(const UrlInfo& other) = default;
30
31 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider( 34 PhysicalWebPageSuggestionsProvider::PhysicalWebPageSuggestionsProvider(
32 ContentSuggestionsProvider::Observer* observer, 35 ContentSuggestionsProvider::Observer* observer,
33 CategoryFactory* category_factory) 36 CategoryFactory* category_factory,
37 physical_web::PhysicalWebDataSource* physical_web_data_source)
34 : ContentSuggestionsProvider(observer, category_factory), 38 : ContentSuggestionsProvider(observer, category_factory),
35 category_status_(CategoryStatus::AVAILABLE_LOADING), 39 category_status_(CategoryStatus::AVAILABLE),
36 provided_category_(category_factory->FromKnownCategory( 40 provided_category_(category_factory->FromKnownCategory(
37 KnownCategories::PHYSICAL_WEB_PAGES)) { 41 KnownCategories::PHYSICAL_WEB_PAGES)),
42 physical_web_data_source_(physical_web_data_source) {
38 observer->OnCategoryStatusChanged(this, provided_category_, category_status_); 43 observer->OnCategoryStatusChanged(this, provided_category_, category_status_);
44 physical_web_data_source_->RegisterListener(this);
45 // TODO(vitaliii): Rewrite initial fetch once crbug.com/667754 is resolved.
46 FetchPhysicalWebPages();
39 } 47 }
40 48
41 PhysicalWebPageSuggestionsProvider::~PhysicalWebPageSuggestionsProvider() = 49 PhysicalWebPageSuggestionsProvider::~PhysicalWebPageSuggestionsProvider() {
42 default; 50 physical_web_data_source_->UnregisterListener(this);
43
44 void PhysicalWebPageSuggestionsProvider::OnDisplayableUrlsChanged(
45 const std::vector<UrlInfo>& urls) {
46 NotifyStatusChanged(CategoryStatus::AVAILABLE);
47 std::vector<ContentSuggestion> suggestions;
48
49 for (const UrlInfo& url_info : urls) {
50 if (suggestions.size() >= kMaxSuggestionsCount) {
51 break;
52 }
53
54 ContentSuggestion suggestion(provided_category_, url_info.site_url.spec(),
55 url_info.site_url);
56
57 suggestion.set_title(base::UTF8ToUTF16(url_info.title));
58 suggestion.set_snippet_text(base::UTF8ToUTF16(url_info.description));
59 suggestion.set_publish_date(url_info.scan_time);
60 suggestion.set_publisher_name(base::UTF8ToUTF16(url_info.site_url.host()));
61 suggestions.push_back(std::move(suggestion));
62 }
63
64 observer()->OnNewSuggestions(this, provided_category_,
65 std::move(suggestions));
66 } 51 }
67 52
68 CategoryStatus PhysicalWebPageSuggestionsProvider::GetCategoryStatus( 53 CategoryStatus PhysicalWebPageSuggestionsProvider::GetCategoryStatus(
69 Category category) { 54 Category category) {
70 return category_status_; 55 return category_status_;
71 } 56 }
72 57
73 CategoryInfo PhysicalWebPageSuggestionsProvider::GetCategoryInfo( 58 CategoryInfo PhysicalWebPageSuggestionsProvider::GetCategoryInfo(
74 Category category) { 59 Category category) {
75 // TODO(vitaliii): Use the proper strings once they've been agreed on. 60 // TODO(vitaliii): Use the proper string once it has been agreed on.
61 // TODO(vitaliii): Use a translateable string. (crbug.com/667764)
62 // TODO(vitaliii): Implement More action. (crbug.com/667759)
76 return CategoryInfo( 63 return CategoryInfo(
77 base::ASCIIToUTF16("Physical web pages"), 64 base::ASCIIToUTF16("Physical web pages"),
78 ContentSuggestionsCardLayout::MINIMAL_CARD, 65 ContentSuggestionsCardLayout::FULL_CARD,
79 /*has_more_action=*/false, 66 /*has_more_action=*/false,
80 /*has_reload_action=*/false, 67 /*has_reload_action=*/false,
81 /*has_view_all_action=*/false, 68 /*has_view_all_action=*/false,
82 /*show_if_empty=*/false, 69 /*show_if_empty=*/false,
83 l10n_util::GetStringUTF16(IDS_NTP_SUGGESTIONS_SECTION_EMPTY)); 70 l10n_util::GetStringUTF16(IDS_NTP_SUGGESTIONS_SECTION_EMPTY));
84 } 71 }
85 72
86 void PhysicalWebPageSuggestionsProvider::DismissSuggestion( 73 void PhysicalWebPageSuggestionsProvider::DismissSuggestion(
87 const ContentSuggestion::ID& suggestion_id) { 74 const ContentSuggestion::ID& suggestion_id) {
88 // TODO(vitaliii): Implement this and then 75 // TODO(vitaliii): Implement this and then
89 // ClearDismissedSuggestionsForDebugging. 76 // ClearDismissedSuggestionsForDebugging. (crbug.com/667766)
90 } 77 }
91 78
92 void PhysicalWebPageSuggestionsProvider::FetchSuggestionImage( 79 void PhysicalWebPageSuggestionsProvider::FetchSuggestionImage(
93 const ContentSuggestion::ID& suggestion_id, 80 const ContentSuggestion::ID& suggestion_id,
94 const ImageFetchedCallback& callback) { 81 const ImageFetchedCallback& callback) {
95 // TODO(vitaliii): Implement. 82 // TODO(vitaliii): Implement. (crbug.com/667765)
96 base::ThreadTaskRunnerHandle::Get()->PostTask( 83 base::ThreadTaskRunnerHandle::Get()->PostTask(
97 FROM_HERE, base::Bind(callback, gfx::Image())); 84 FROM_HERE, base::Bind(callback, gfx::Image()));
98 } 85 }
99 86
100 void PhysicalWebPageSuggestionsProvider::Fetch( 87 void PhysicalWebPageSuggestionsProvider::Fetch(
101 const Category& category, 88 const Category& category,
102 const std::set<std::string>& known_suggestion_ids, 89 const std::set<std::string>& known_suggestion_ids,
103 const FetchDoneCallback& callback) { 90 const FetchDoneCallback& callback) {
104 LOG(DFATAL) 91 LOG(DFATAL)
105 << "PhysicalWebPageSuggestionsProvider has no |Fetch| functionality!"; 92 << "PhysicalWebPageSuggestionsProvider has no |Fetch| functionality!";
(...skipping 25 matching lines...) Expand all
131 } 118 }
132 119
133 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( 120 void PhysicalWebPageSuggestionsProvider::ClearDismissedSuggestionsForDebugging(
134 Category category) { 121 Category category) {
135 // TODO(vitaliii): Implement when dismissed suggestions are supported. 122 // TODO(vitaliii): Implement when dismissed suggestions are supported.
136 } 123 }
137 124
138 //////////////////////////////////////////////////////////////////////////////// 125 ////////////////////////////////////////////////////////////////////////////////
139 // Private methods 126 // Private methods
140 127
141 // Updates the |category_status_| and notifies the |observer_|, if necessary.
142 void PhysicalWebPageSuggestionsProvider::NotifyStatusChanged( 128 void PhysicalWebPageSuggestionsProvider::NotifyStatusChanged(
143 CategoryStatus new_status) { 129 CategoryStatus new_status) {
144 if (category_status_ == new_status) { 130 if (category_status_ == new_status) {
145 return; 131 return;
146 } 132 }
147 category_status_ = new_status; 133 category_status_ = new_status;
148 observer()->OnCategoryStatusChanged(this, provided_category_, new_status); 134 observer()->OnCategoryStatusChanged(this, provided_category_, new_status);
149 } 135 }
150 136
137 void PhysicalWebPageSuggestionsProvider::FetchPhysicalWebPages() {
138 NotifyStatusChanged(CategoryStatus::AVAILABLE);
139 std::unique_ptr<ListValue> page_values =
140 physical_web_data_source_->GetMetadata();
141
142 std::vector<const DictionaryValue*> page_dictionaries;
143 for (const std::unique_ptr<Value>& page_value : *page_values) {
144 const DictionaryValue* page_dictionary;
145 if (!page_value->GetAsDictionary(&page_dictionary)) {
146 LOG(DFATAL) << "Physical Web page is not a dictionary.";
147 }
148 page_dictionaries.push_back(page_dictionary);
149 }
150
151 std::sort(page_dictionaries.begin(), page_dictionaries.end(),
152 [](const DictionaryValue* left, const DictionaryValue* right) {
153 double left_distance, right_distance;
154 bool success = left->GetDouble(physical_web::kDistanceEstimateKey,
155 &left_distance);
156 success = right->GetDouble(physical_web::kDistanceEstimateKey,
157 &right_distance) &&
158 success;
159 if (!success) {
160 LOG(DFATAL) << "Distance field is missing.";
161 }
162 return left_distance < right_distance;
163 });
164
165 std::vector<ContentSuggestion> suggestions;
166 for (const DictionaryValue* page_dictionary : page_dictionaries) {
167 suggestions.push_back(ConvertPhysicalWebPage(*page_dictionary));
168 if (suggestions.size() == kMaxSuggestionsCount) {
169 break;
170 }
171 }
172
173 observer()->OnNewSuggestions(this, provided_category_,
174 std::move(suggestions));
175 }
176
177 ContentSuggestion PhysicalWebPageSuggestionsProvider::ConvertPhysicalWebPage(
178 const DictionaryValue& page) const {
179 std::string scanned_url, raw_resolved_url, title, description;
180 int scan_timestamp;
181 bool success = page.GetString(physical_web::kScannedUrlKey, &scanned_url);
182 success = page.GetInteger(physical_web::kScanTimestampKey, &scan_timestamp) &&
183 success;
184 success = page.GetString(physical_web::kResolvedUrlKey, &raw_resolved_url) &&
185 success;
186 success = page.GetString(physical_web::kTitleKey, &title) && success;
187 success =
188 page.GetString(physical_web::kDescriptionKey, &description) && success;
189 if (!success) {
190 LOG(DFATAL) << "Expected field is missing.";
191 }
192
193 const GURL resolved_url(raw_resolved_url);
194 ContentSuggestion suggestion(provided_category_, resolved_url.spec(),
195 resolved_url);
196 DCHECK(base::IsStringUTF8(title));
197 suggestion.set_title(base::UTF8ToUTF16(title));
198 // TODO(vitaliii): Set the time properly once the proper value is provided
199 // (see crbug.com/667722).
200 suggestion.set_publish_date(
201 base::Time::FromTimeT(static_cast<time_t>(scan_timestamp)));
202 suggestion.set_publisher_name(base::UTF8ToUTF16(resolved_url.host()));
203 DCHECK(base::IsStringUTF8(description));
204 suggestion.set_snippet_text(base::UTF8ToUTF16(description));
205 return suggestion;
206 }
207
208 // PhysicalWebListener implementation.
209 void PhysicalWebPageSuggestionsProvider::OnFound(const std::string& url) {
210 FetchPhysicalWebPages();
211 }
212
213 void PhysicalWebPageSuggestionsProvider::OnLost(const std::string& url) {
214 // TODO(vitaliii): Do not refetch, but just update the current state.
215 FetchPhysicalWebPages();
216 }
217
218 void PhysicalWebPageSuggestionsProvider::OnDistanceChanged(
219 const std::string& url,
220 double distance_estimate) {
221 FetchPhysicalWebPages();
222 }
223
151 } // namespace ntp_snippets 224 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698