| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| syntax = "proto3"; |
| |
| package feedstore; |
| |
| import "components/feed/core/proto/v2/wire/content_id.proto"; |
| import "components/feed/core/proto/v2/wire/feed_action.proto"; |
| import "components/feed/core/proto/v2/wire/stream_structure.proto"; |
| import "components/feed/core/proto/v2/wire/web_feed_matcher.proto"; |
| import "components/feed/core/proto/v2/wire/web_feeds.proto"; |
| |
| option optimize_for = LITE_RUNTIME; |
| |
| // Actual data stored by the client. |
| // This data is sourced from the wire protocol, which is converted upon receipt. |
| // |
| // This is the 'value' in the key/value store. |
| // Keys are defined as: |
| // [Key format] -> [Record field] |
| // S/<stream-key> -> stream_data |
| // T/<stream-key>/<sequence-number> -> stream_structures |
| // c/<stream-key>/<content-id> -> content |
| // s/<stream-key>/<content-id> -> shared_state |
| // a/<action-id> -> action |
| // m -> metadata |
| // subs -> subscribed_web_feeds |
| // recommendedIndex -> recommended_web_feed_index |
| // R/<web_feed_id> -> recommended_web_feed |
| // W/<operation-id> -> pending_web_feed_operation |
| // v/<docid>/<timestamp> -> docview |
| message Record { |
| oneof data { |
| StreamData stream_data = 1; |
| StreamStructureSet stream_structures = 2; |
| Content content = 3; |
| StoredAction local_action = 4; |
| StreamSharedState shared_state = 5; |
| Metadata metadata = 6; |
| SubscribedWebFeeds subscribed_web_feeds = 7; |
| WebFeedInfo recommended_web_feed = 8; |
| RecommendedWebFeedIndex recommended_web_feed_index = 9; |
| PendingWebFeedOperation pending_web_feed_operation = 10; |
| DocView doc_view = 11; |
| } |
| } |
| |
| // List of the hashes for all the contents in a collection (carousel, list, |
| // or 2-column) if multiple items show up in a row. Otherwise, it just contain |
| // a single hash value. |
| message StreamContentHashList { |
| // The hash of the content URL. |
| repeated uint32 hashes = 1; |
| } |
| |
| // Data about the Feed stream. There is at most one instance of StreamData. |
| message StreamData { |
| // Root ContentId, as provided by the server. |
| feedwire.ContentId content_id = 1; |
| // Token used to request a 'more' request to the server. |
| bytes next_page_token = 2; |
| // The unix timestamp in milliseconds that the most recent content was added. |
| int64 last_added_time_millis = 4; |
| // The content IDs of the shared state for this stream. |
| repeated feedwire.ContentId shared_state_ids = 6; |
| // Was this feed signed in. |
| bool signed_in = 7; |
| // If signed_in, this is the account gaia tied to this stream data. |
| string gaia = 13; |
| // If signed_in, this is the account email tied to this stream data. |
| string email = 14; |
| // Is activity logging enabled? |
| bool logging_enabled = 8; |
| // Has the privacy notice been fulfilled? |
| bool privacy_notice_fulfilled = 9; |
| // Stream ID. Should match the id value stored in the record's key. |
| string stream_key = 10; |
| // List of hashes for all the contents contained in the stream. |
| repeated StreamContentHashList content_hashes = 11; |
| // Root EventID provided by the server. |
| bytes root_event_id = 12; |
| |
| reserved 3, 5, 15; |
| } |
| |
| // Data that doesn't belong to a stream. |
| message Metadata { |
| // Session identifier used for signed-out feed requests and interactions. |
| message SessionID { |
| string token = 1; |
| int64 expiry_time_ms = 2; |
| } |
| |
| // Metadata about a specific stream. |
| message StreamMetadata { |
| string stream_key = 1; |
| // Whether the stream data is known to be stale. This can happen in the |
| // WebFeed stream if the subscription list changes. |
| bool is_known_stale = 3; |
| // If this stream has been viewed before, this is the list of content in the |
| // stream (`StreamData.content_hashes`). This is used to determine whether |
| // the user has already seen a stored stream's data. |
| repeated StreamContentHashList view_content_hashes = 4; |
| |
| message ContentLifetime { |
| int64 stale_age_ms = 1; |
| int64 invalid_age_ms = 2; |
| } |
| ContentLifetime content_lifetime = 5; |
| // The unix timestamp in milliseconds that the stream was fetched last time. |
| int64 last_fetch_time_millis = 6; |
| |
| // The unix timestamp in milliseconds that the feed response is produced on |
| // the server. This is returned from the server and based on server clock. |
| int64 last_server_response_time_millis = 7; |
| |
| // List of IDs of contents that have been viewed by the user. A content is |
| // viewed if 2/3rds of it is in the viewport. |
| repeated uint32 viewed_content_hashes = 8; |
| |
| reserved 2; |
| } |
| |
| // Token used to read or write to the same storage. |
| bytes consistency_token = 1; |
| // ID for the next pending action. |
| int32 next_action_id = 2; |
| // The most recent session identifier. |
| SessionID session_id = 3; |
| // Schema version number. Schema versions: |
| // 0: Initial version. |
| // 1: Current version. Added <stream-key> to the key patterns of "content" and |
| // "shared_state" |
| // records. |
| int32 stream_schema_version = 4; |
| repeated StreamMetadata stream_metadata = 5; |
| // The GAIA ID associated with the store. |
| string gaia = 6; |
| // Whether WAA is enabled for this user, as reported by the last FeedQuery |
| // response. |
| bool web_and_app_activity_enabled = 7; |
| // Whether personalization is enabled for Discover, as reported by the last |
| // FeedQuery response. |
| bool discover_personalization_enabled = 8; |
| // Count of how many times the user has followed from the main menu, so we |
| // can show appropriate user education help for the following feed. |
| int32 followed_from_web_page_menu_count = 9; |
| // The list of IDs representing the most recent contents viewed by the user. |
| // The size of the list is capped to |
| // feedstore_util::kMaxMostRecentContentHashes. The IDs are stored in the |
| // ascending order of the time when the content is viewed by the user. |
| repeated uint32 most_recent_viewed_content_hashes = 11; |
| |
| reserved 10; |
| } |
| |
| // A set of StreamStructures that should be applied to a stream. |
| message StreamStructureSet { |
| // Stream ID. Should match the id value stored in the record's key. |
| string stream_key = 1; |
| int32 sequence_number = 2; |
| repeated StreamStructure structures = 3; |
| } |
| |
| // This is the structure of the stream. It is defined through the parent/child |
| // relationship and an operation. This message will be journaled. Reading |
| // the journal from start to end will fully define the structure of the stream. |
| message StreamStructure { |
| // The defined set of DataOperations |
| // These operations align with the Operation enum defined in |
| // data_operation.proto. |
| enum Operation { |
| UNKNOWN = 0; |
| // Clear all the content in the session, creating a new session |
| CLEAR_ALL = 1; |
| // Append if not present or update |
| UPDATE_OR_APPEND = 2; |
| // Remove the node from its parent |
| REMOVE = 3; |
| } |
| Operation operation = 1; |
| // The ContentId of the content. |
| feedwire.ContentId content_id = 2; |
| // The parent ContentId, or unset if this is the root. |
| feedwire.ContentId parent_id = 3; |
| |
| // Type of node as denoted by the server. This type has no meaning for the |
| // client. |
| enum Type { |
| // Default type for operations that don't affect the stream (e.g. operations |
| // on shared states). |
| UNKNOWN_TYPE = 0; |
| // The root of the stream. |
| STREAM = 1; |
| // An internal tree node, which may have children. |
| CARD = 2; |
| // A leaf node, which provides content. |
| CONTENT = 3; |
| // An internal tree node, which may have children. |
| GROUP = 4; |
| } |
| Type type = 4; |
| // Set iff type=CONTENT |
| ContentInfo content_info = 5; |
| // Is this the root of the stream? |
| bool is_root = 6; |
| } |
| |
| message DataOperation { |
| StreamStructure structure = 1; |
| // Provided if structure adds content. |
| Content content = 2; |
| } |
| |
| message ContentInfo { |
| // Score given by server. |
| float score = 1; |
| // Unix timestamp (seconds) that content was received by Chrome. |
| int64 availability_time_seconds = 2; |
| } |
| |
| message Content { |
| feedwire.ContentId content_id = 1; |
| // Opaque content. The UI layer knows how to parse and render this as a slice. |
| bytes frame = 2; |
| repeated feedwire.PrefetchMetadata prefetch_metadata = 3; |
| // Stream ID. Should match the id value stored in the record's key. |
| string stream_key = 4; |
| } |
| |
| // This represents a shared state item. |
| message StreamSharedState { |
| feedwire.ContentId content_id = 1; |
| // Opaque data required to render content. |
| bytes shared_state_data = 2; |
| // Stream ID. Should match the id value stored in the record's key. |
| string stream_key = 3; |
| } |
| |
| // A stored action awaiting upload. |
| message StoredAction { |
| // Unique ID for this stored action, provided by the client. |
| // This is a sequential number, so that the action with the lowest id value |
| // was recorded chronologically first. |
| int32 id = 1; |
| // How many times we have tried to upload the action. |
| int32 upload_attempt_count = 2; |
| // The action to upload. |
| feedwire.FeedAction action = 3; |
| } |
| |
| // List of web feeds for which the user is subscribed. |
| message SubscribedWebFeeds { |
| repeated WebFeedInfo feeds = 1; |
| // The unix timestamp in milliseconds that this data was updated from the |
| // server. |
| int64 update_time_millis = 2; |
| } |
| |
| message RecommendedWebFeedIndex { |
| message Entry { |
| string web_feed_id = 1; |
| repeated feedwire.webfeed.WebFeedMatcher matchers = 2; |
| } |
| repeated Entry entries = 1; |
| // The unix timestamp in milliseconds that this data was updated from the |
| // server. |
| int64 update_time_millis = 2; |
| } |
| |
| // Reference to an image. |
| message Image { |
| string url = 1; |
| } |
| |
| // See http://go/chrome-web-feed-api. |
| message WebFeedInfo { |
| enum State { |
| STATE_UNSPECIFIED = 0; |
| INACTIVE = 1; |
| ACTIVE = 2; |
| WAITING_FOR_CONTENT = 4; |
| } |
| string web_feed_id = 1; |
| string title = 2; |
| string subtitle = 3; |
| string detail_text = 4; |
| string visit_uri = 5; |
| string rss_uri = 6; |
| Image favicon = 7; |
| int64 follower_count = 8; |
| State state = 9; |
| repeated feedwire.webfeed.WebFeedMatcher matchers = 10; |
| } |
| |
| message PendingWebFeedOperation { |
| enum Kind { |
| KIND_UNSPECIFIED = 0; |
| SUBSCRIBE = 1; |
| UNSUBSCRIBE = 2; |
| } |
| // Unique ID, for sorting operations. |
| int64 id = 1; |
| // The operation kind. |
| Kind kind = 2; |
| // The web feed ID to either subscribe or unsubscribe. |
| string web_feed_id = 3; |
| // Number of times the operation has been attempted. |
| int32 attempts = 4; |
| // Reason for this change. |
| feedwire.webfeed.WebFeedChangeReason change_reason = 5; |
| } |
| |
| message DocView { |
| // Unique ID for the content that was viewed. |
| uint64 docid = 1; |
| // Unix timestamp when the view occurred. |
| int64 view_time_millis = 4; |
| } |