blob: b6cf3f429573b6d44cb396ac67b57ffe888c51f0 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cstdint>
#include <memory>
#include <string>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "components/ntp_snippets/category.h"
#include "url/gurl.h"
namespace ntp_snippets {
// DownloadSuggestionExtra contains additional data which is only available for
// download suggestions.
struct DownloadSuggestionExtra {
DownloadSuggestionExtra(const DownloadSuggestionExtra&);
// The GUID for the downloaded file.
std::string download_guid;
// The file path of the downloaded file once download completes.
base::FilePath target_file_path;
// The effective MIME type of downloaded content.
std::string mime_type;
// Underlying offline page identifier.
int64_t offline_page_id = 0;
// Whether or not the download suggestion is a downloaded asset.
// When this is true, |offline_page_id| is ignored, otherwise
// |target_file_path| and |mime_type| are ignored.
bool is_download_asset = false;
// Contains additional data which is only available for recent tab suggestions.
struct RecentTabSuggestionExtra {
// Corresponding tab identifier.
int tab_id;
// Underlying offline page identifier.
int64_t offline_page_id = 0;
// ReadingListSuggestionExtra contains additional data which is only available
// for Reading List suggestions.
struct ReadingListSuggestionExtra {
// URL of the page whose favicon should be displayed for this suggestion.
GURL favicon_page_url;
// Contains additional data for notification-worthy suggestions.
struct NotificationExtra {
// Deadline for showing notification. If the deadline is past, the
// notification is no longer fresh and no notification should be sent. If the
// deadline passes while a notification is up, it should be canceled.
base::Time deadline;
// A content suggestion for the new tab page, which can be an article or an
// offline page, for example.
class ContentSuggestion {
class ID {
ID(Category category, const std::string& id_within_category)
: category_(category), id_within_category_(id_within_category) {}
Category category() const { return category_; }
const std::string& id_within_category() const {
return id_within_category_;
bool operator==(const ID& rhs) const;
bool operator!=(const ID& rhs) const;
Category category_;
std::string id_within_category_;
// Allow copy and assignment.
// Creates a new ContentSuggestion. The caller must ensure that the |id|
// passed in here is unique application-wide.
ContentSuggestion(const ID& id, const GURL& url);
ContentSuggestion(Category category,
const std::string& id_within_category,
const GURL& url);
ContentSuggestion& operator=(ContentSuggestion&&);
// An ID for identifying the suggestion. The ID is unique application-wide.
const ID& id() const { return id_; }
// The URL where the content referenced by the suggestion can be accessed.
// This may be an AMP URL.
const GURL& url() const { return url_; }
// The URL of the page that links to a favicon that represents the suggestion.
// Path is trimmed for the URL because the current favicon server backend
// prefers it this way.
GURL url_with_favicon() const {
return url_with_favicon_.is_valid() ? GetFaviconDomain(url_with_favicon_)
: GetFaviconDomain(url_);
void set_url_with_favicon(const GURL& url_with_favicon) {
url_with_favicon_ = url_with_favicon;
static GURL GetFaviconDomain(const GURL& favicon_url);
// Title of the suggestion.
const base::string16& title() const { return title_; }
void set_title(const base::string16& title) { title_ = title; }
// Summary or relevant textual extract from the content.
const base::string16& snippet_text() const { return snippet_text_; }
void set_snippet_text(const base::string16& snippet_text) {
snippet_text_ = snippet_text;
// The time when the content represented by this suggestion was published.
const base::Time& publish_date() const { return publish_date_; }
void set_publish_date(const base::Time& publish_date) {
publish_date_ = publish_date;
// The name of the source/publisher of this suggestion.
const base::string16& publisher_name() const { return publisher_name_; }
void set_publisher_name(const base::string16& publisher_name) {
publisher_name_ = publisher_name;
bool is_video_suggestion() const { return is_video_suggestion_; }
void set_is_video_suggestion(bool is_video_suggestion) {
is_video_suggestion_ = is_video_suggestion;
// TODO(pke): Remove the score from the ContentSuggestion class. The UI only
// uses it to track user clicks (histogram data). Instead, the providers
// should be informed about clicks and do appropriate logging themselves.
// IMPORTANT: The score may simply be 0 for suggestions from providers which
// cannot provide score values.
float score() const { return score_; }
void set_score(float score) { score_ = score; }
// Extra information for download suggestions. Only available for DOWNLOADS
// suggestions (i.e., if the associated category has the
// KnownCategories::DOWNLOADS id).
DownloadSuggestionExtra* download_suggestion_extra() const {
return download_suggestion_extra_.get();
void set_download_suggestion_extra(
std::unique_ptr<DownloadSuggestionExtra> download_suggestion_extra);
// Extra information for recent tab suggestions. Only available for
// KnownCategories::RECENT_TABS suggestions.
RecentTabSuggestionExtra* recent_tab_suggestion_extra() const {
return recent_tab_suggestion_extra_.get();
void set_recent_tab_suggestion_extra(
std::unique_ptr<RecentTabSuggestionExtra> recent_tab_suggestion_extra);
// Extra information for reading list suggestions. Only available for
// KnownCategories::READING_LIST suggestions.
ReadingListSuggestionExtra* reading_list_suggestion_extra() const {
return reading_list_suggestion_extra_.get();
void set_reading_list_suggestion_extra(
// Extra information for notifications. When absent, no notification should be
// sent for this suggestion. When present, a notification should be sent,
// unless other factors disallow it (examples: the extra parameters say to;
// notifications are disabled; Chrome is in the foreground).
NotificationExtra* notification_extra() const {
return notification_extra_.get();
void set_notification_extra(
std::unique_ptr<NotificationExtra> notification_extra);
const base::Time& fetch_date() const { return fetch_date_; }
void set_fetch_date(const base::Time& fetch_date) {
fetch_date_ = fetch_date;
const base::Optional<uint32_t>& optional_image_dominant_color() const {
return image_dominant_color_;
void set_optional_image_dominant_color(
const base::Optional<uint32_t>& optional_color_int) {
image_dominant_color_ = optional_color_int;
ID id_;
GURL url_;
GURL url_with_favicon_;
base::string16 title_;
base::string16 snippet_text_;
base::Time publish_date_;
base::string16 publisher_name_;
float score_;
std::unique_ptr<DownloadSuggestionExtra> download_suggestion_extra_;
std::unique_ptr<RecentTabSuggestionExtra> recent_tab_suggestion_extra_;
std::unique_ptr<ReadingListSuggestionExtra> reading_list_suggestion_extra_;
std::unique_ptr<NotificationExtra> notification_extra_;
// The time when the remote suggestion was fetched from the server. This field
// is only populated when the ContentSuggestion is created from a
// RemoteSuggestion.
base::Time fetch_date_;
bool is_video_suggestion_;
// Encoded as an Android @ColorInt.
base::Optional<uint32_t> image_dominant_color_;
std::ostream& operator<<(std::ostream& os, const ContentSuggestion::ID& id);
} // namespace ntp_snippets