blob: d0f74512381b2b792bd4aac404b9382ed6503e11 [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.
#ifndef COMPONENTS_READING_LIST_CORE_READING_LIST_ENTRY_H_
#define COMPONENTS_READING_LIST_CORE_READING_LIST_ENTRY_H_
#include <string>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "url/gurl.h"
namespace reading_list {
class ReadingListLocal;
// The different ways a reading list entry is added.
// |ADDED_VIA_CURRENT_APP| is when the entry was added by the user from within
// the current instance of the app.
// |ADDED_VIA_EXTENSION| is when the entry was added via the share extension.
// |ADDED_VIA_SYNC| is when the entry was added with sync.
enum EntrySource { ADDED_VIA_CURRENT_APP, ADDED_VIA_EXTENSION, ADDED_VIA_SYNC };
// Contains additional data used by the ContentSuggestions.
struct ContentSuggestionsExtra {
// Whether the Reading List Entry has been dismissed in the Content
// Suggestions.
bool dismissed = false;
};
}
namespace sync_pb {
class ReadingListSpecifics;
}
class ReadingListEntry;
// An entry in the reading list. The URL is a unique identifier for an entry, as
// such it should not be empty and is the only thing considered when comparing
// entries.
// A word about timestamp usage in this class:
// - The backing store uses int64 values to code timestamps. We use internally
// the same type to avoid useless conversions. This values represent the
// number of micro seconds since Jan 1st 1970.
// - As most timestamp are used to sort entries, operations on int64_t are
// faster than operations on base::Time. So Getter return the int64_t values.
// - However, to ensure all the conversions are done the same way, and because
// the Now time is alway retrieved using base::Time::Now(), all the timestamp
// parameter are passed as base::Time. These parameters are internally
// converted in int64_t.
class ReadingListEntry {
public:
// Creates a ReadingList entry. |url| and |title| are the main fields of the
// entry.
// |now| is used to fill the |creation_time_us_| and all the update timestamp
// fields.
ReadingListEntry(const GURL& url,
const std::string& title,
const base::Time& now);
ReadingListEntry(const GURL& url,
const std::string& title,
const base::Time& now,
std::unique_ptr<net::BackoffEntry> backoff);
ReadingListEntry(ReadingListEntry&& entry);
~ReadingListEntry();
// Entries are created in WAITING state. At some point they will be PROCESSING
// into one of the three state: PROCESSED, the only state a distilled URL
// would be set, WILL_RETRY, similar to wait, but with exponential delays or
// DISTILLATION_ERROR where the system will not retry at all.
enum DistillationState {
WAITING,
PROCESSING,
PROCESSED,
WILL_RETRY,
DISTILLATION_ERROR
};
static const net::BackoffEntry::Policy kBackoffPolicy;
// The URL of the page the user would like to read later.
const GURL& URL() const;
// The title of the entry. Might be empty.
const std::string& Title() const;
// What state this entry is in.
DistillationState DistilledState() const;
// The local file path for the distilled version of the page. This should only
// be called if the state is "PROCESSED".
const base::FilePath& DistilledPath() const;
// The URL that has been distilled to produce file stored at |DistilledPath|.
const GURL& DistilledURL() const;
// The time distillation was done. The value is in microseconds since Jan 1st
// 1970. Returns 0 if the entry was not distilled.
int64_t DistillationTime() const;
// The size of the stored page in bytes.
int64_t DistillationSize() const;
// The time before the next try. This is automatically increased when the
// state is set to WILL_RETRY or ERROR from a non-error state.
base::TimeDelta TimeUntilNextTry() const;
// The number of time chrome failed to download this entry. This is
// automatically increased when the state is set to WILL_RETRY or ERROR from a
// non-error state.
int FailedDownloadCounter() const;
// The read status of the entry.
bool IsRead() const;
// Returns if an entry has ever been seen.
bool HasBeenSeen() const;
// Extra information about this entry for the Content Suggestions.
const reading_list::ContentSuggestionsExtra* ContentSuggestionsExtra() const;
// The last update time of the entry. This value may be used to sort the
// entries. The value is in microseconds since Jan 1st 1970.
int64_t UpdateTime() const;
// The last update time of the title of the entry. The value is in
// microseconds since Jan 1st 1970.
int64_t UpdateTitleTime() const;
// The creation update time of the entry. The value is in microseconds since
// Jan 1st 1970.
int64_t CreationTime() const;
// The time when the entry was read for the first time. The value is in
// microseconds since Jan 1st 1970.
int64_t FirstReadTime() const;
// Set the update time to |now|.
void MarkEntryUpdated(const base::Time& now);
// Returns a protobuf encoding the content of this ReadingListEntry for local
// storage. Use |now| to serialize the backoff_entry.
std::unique_ptr<reading_list::ReadingListLocal> AsReadingListLocal(
const base::Time& now) const;
// Returns a protobuf encoding the content of this ReadingListEntry for sync.
std::unique_ptr<sync_pb::ReadingListSpecifics> AsReadingListSpecifics() const;
// Created a ReadingListEntry from the protobuf format.
// Use |now| to deserialize the backoff_entry.
static std::unique_ptr<ReadingListEntry> FromReadingListLocal(
const reading_list::ReadingListLocal& pb_entry,
const base::Time& now);
// Created a ReadingListEntry from the protobuf format.
// If creation time is not set, it will be set to |now|.
static std::unique_ptr<ReadingListEntry> FromReadingListSpecifics(
const sync_pb::ReadingListSpecifics& pb_entry,
const base::Time& now);
// Merge |this| and |other| into this.
// Local fields are kept from |this|.
// Each field is merged individually keeping the highest value as defined by
// the |ReadingListStore.CompareEntriesForSync| function.
//
// After calling |MergeLocalStateFrom|, the result must verify
// ReadingListStore.CompareEntriesForSync(old_this.AsReadingListSpecifics(),
// new_this.AsReadingListSpecifics())
// and
// ReadingListStore.CompareEntriesForSync(other.AsReadingListSpecifics(),
// new_this.AsReadingListSpecifics()).
void MergeWithEntry(const ReadingListEntry& other);
ReadingListEntry& operator=(ReadingListEntry&& other);
bool operator==(const ReadingListEntry& other) const;
// Sets |title_| to |title|. Sets |update_title_time_us_| to |now|.
void SetTitle(const std::string& title, const base::Time& now);
// Sets the distilled info (offline path, online URL, size and date of the
// stored files) about distilled page, switch the state to PROCESSED and reset
// the time until the next try.
void SetDistilledInfo(const base::FilePath& path,
const GURL& distilled_url,
int64_t distilation_size,
const base::Time& distilation_time);
// Sets the state to one of PROCESSING, WILL_RETRY or ERROR.
void SetDistilledState(DistillationState distilled_state);
// Sets the read state of the entry. Will set the UpdateTime of the entry.
// If |first_read_time_us_| is 0 and read is READ, sets |first_read_time_us_|
// to |now|.
void SetRead(bool read, const base::Time& now);
// Sets extra information about this entry used by Content Suggestions.
void SetContentSuggestionsExtra(
const reading_list::ContentSuggestionsExtra& extra);
private:
enum State { UNSEEN, UNREAD, READ };
ReadingListEntry(
const GURL& url,
const std::string& title,
State state,
int64_t creation_time,
int64_t first_read_time,
int64_t update_time,
int64_t update_title_time,
ReadingListEntry::DistillationState distilled_state,
const base::FilePath& distilled_path,
const GURL& distilled_url,
int64_t distillation_time,
int64_t distillation_size,
int failed_download_counter,
std::unique_ptr<net::BackoffEntry> backoff,
const reading_list::ContentSuggestionsExtra& content_suggestions_extra);
GURL url_;
std::string title_;
State state_;
base::FilePath distilled_path_;
GURL distilled_url_;
DistillationState distilled_state_;
std::unique_ptr<net::BackoffEntry> backoff_;
int failed_download_counter_;
// These value are in microseconds since Jan 1st 1970. They are used for
// sorting the entries from the database. They are kept in int64_t to avoid
// conversion on each save/read event.
int64_t creation_time_us_;
int64_t first_read_time_us_;
int64_t update_time_us_;
int64_t update_title_time_us_;
int64_t distillation_time_us_;
int64_t distillation_size_;
reading_list::ContentSuggestionsExtra content_suggestions_extra_;
DISALLOW_COPY_AND_ASSIGN(ReadingListEntry);
};
#endif // COMPONENTS_READING_LIST_CORE_READING_LIST_ENTRY_H_