Skip to content

Commit

Permalink
[Cormorant] add networking code for query web id
Browse files Browse the repository at this point in the history
Bug: 1400503
Change-Id: Ic6e45647d07abacbd008bf2c09f180507b2c0e48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4180024
Commit-Queue: Jeffrey Cohen <jeffreycohen@chromium.org>
Reviewed-by: Dan H <harringtond@chromium.org>
Reviewed-by: Justin DeWitt <dewittj@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1098207}
  • Loading branch information
Jeffrey Cohen authored and Chromium LUCI CQ committed Jan 28, 2023
1 parent dc2b35a commit 9c616cc
Show file tree
Hide file tree
Showing 21 changed files with 336 additions and 0 deletions.
2 changes: 2 additions & 0 deletions components/feed/core/v2/BUILD.gn
Expand Up @@ -119,6 +119,8 @@ source_set("feed_core_v2") {
"web_feed_subscriptions/fetch_recommended_web_feeds_task.h",
"web_feed_subscriptions/fetch_subscribed_web_feeds_task.cc",
"web_feed_subscriptions/fetch_subscribed_web_feeds_task.h",
"web_feed_subscriptions/query_web_feed_task.cc",
"web_feed_subscriptions/query_web_feed_task.h",
"web_feed_subscriptions/subscribe_to_web_feed_task.cc",
"web_feed_subscriptions/subscribe_to_web_feed_task.h",
"web_feed_subscriptions/subscription_datastore_provider.cc",
Expand Down
Expand Up @@ -229,6 +229,60 @@ TEST_F(FeedApiSubscriptionsTest, FollowWebFeedSuccess) {
WebFeedChangeReason::WEB_PAGE_MENU, 1);
}

TEST_F(FeedApiSubscriptionsTest, QueryWebFeedSuccess) {
{
auto metadata = stream_->GetMetadata();
metadata.set_consistency_token("token");
stream_->SetMetadata(metadata);
}

base::HistogramTester histograms;
network_.InjectResponse(SuccessfulQueryResponse("cats"));
CallbackReceiver<WebFeedSubscriptions::QueryWebFeedResult> callback;

WebFeedPageInformation page_info =
MakeWebFeedPageInformation("http://cats.com");
subscriptions().QueryWebFeed(page_info.url(), callback.Bind());
EXPECT_EQ(WebFeedQueryRequestStatus::kSuccess,
callback.RunAndGetResult().request_status);
auto sent_request = network_.GetApiRequestSent<QueryWebFeedDiscoverApi>();
EXPECT_STREQ("http://cats.com/",
sent_request->web_feed_uris().web_page_uri().c_str());
EXPECT_EQ("token", sent_request->consistency_token().token());
EXPECT_EQ("id_cats", callback.RunAndGetResult().web_feed_id);
EXPECT_EQ("query-ct", stream_->GetMetadata().consistency_token());

histograms.ExpectUniqueSample("ContentSuggestions.Feed.WebFeed.QueryResult",
WebFeedSubscriptionRequestStatus::kSuccess, 1);
}

TEST_F(FeedApiSubscriptionsTest, QueryWebFeedError) {
base::HistogramTester histograms;
network_.InjectQueryResponse(MakeFailedResponse());
CallbackReceiver<WebFeedSubscriptions::QueryWebFeedResult> callback;
subscriptions().QueryWebFeed(GURL("http://cats.com"), callback.Bind());

EXPECT_EQ(WebFeedQueryRequestStatus::kFailedUnknownError,
callback.RunAndGetResult().request_status);

histograms.ExpectUniqueSample("ContentSuggestions.Feed.WebFeed.QueryResult",
WebFeedQueryRequestStatus::kFailedUnknownError,
1);
}

TEST_F(FeedApiSubscriptionsTest, QueryWebFeedInvalidUrlError) {
base::HistogramTester histograms;
CallbackReceiver<WebFeedSubscriptions::QueryWebFeedResult> callback;
subscriptions().QueryWebFeed(GURL(), callback.Bind());

EXPECT_EQ(WebFeedQueryRequestStatus::kFailedInvalidUrl,
callback.RunAndGetResult().request_status);

histograms.ExpectUniqueSample("ContentSuggestions.Feed.WebFeed.QueryResult",
WebFeedQueryRequestStatus::kFailedInvalidUrl,
1);
}

TEST_F(FeedApiSubscriptionsTest, FollowWebFeedAbortOnClearAll) {
// The goal of this test is to test the task order:
// ClearAllTask, SubscribeToWebFeedTask.
Expand Down
6 changes: 6 additions & 0 deletions components/feed/core/v2/api_test/feed_api_test.h
Expand Up @@ -270,6 +270,12 @@ class TestFeedNetwork : public FeedNetwork {
void InjectResponse(feedwire::webfeed::ListWebFeedsResponse response) {
InjectApiResponse<ListWebFeedsDiscoverApi>(std::move(response));
}
void InjectResponse(const feedwire::webfeed::QueryWebFeedResponse& response) {
InjectApiResponse<QueryWebFeedDiscoverApi>(response);
}
void InjectQueryResponse(const FeedNetwork::RawResponse& response) {
InjectApiRawResponse<QueryWebFeedDiscoverApi>(response);
}

void InjectListWebFeedsResponse(
std::vector<feedwire::webfeed::WebFeed> web_feeds) {
Expand Down
2 changes: 2 additions & 0 deletions components/feed/core/v2/enums.cc
Expand Up @@ -38,6 +38,8 @@ std::ostream& operator<<(std::ostream& out, NetworkRequestType value) {
return out << "kQueryNextPage";
case NetworkRequestType::kSingleWebFeedListContents:
return out << "kSingleWebFeedListContents";
case NetworkRequestType::kQueryWebFeed:
return out << "kQueryWebFeed";
}
#endif
return out << (static_cast<int>(value));
Expand Down
1 change: 1 addition & 0 deletions components/feed/core/v2/enums.h
Expand Up @@ -24,6 +24,7 @@ enum class NetworkRequestType : int {
kQueryBackgroundFeed = 9,
kQueryNextPage = 10,
kSingleWebFeedListContents = 11,
kQueryWebFeed = 12,
};
std::ostream& operator<<(std::ostream& out, NetworkRequestType value);

Expand Down
12 changes: 12 additions & 0 deletions components/feed/core/v2/feed_network.h
Expand Up @@ -146,6 +146,18 @@ struct SingleWebFeedListContentsDiscoverApi {
static bool SendRequestMetadata() { return false; }
};

struct QueryWebFeedDiscoverApi {
using Request = feedwire::webfeed::QueryWebFeedRequest;
using Response = feedwire::webfeed::QueryWebFeedResponse;
static constexpr NetworkRequestType kRequestType =
NetworkRequestType::kQueryWebFeed;
static base::StringPiece Method() { return "POST"; }
static base::StringPiece RequestPath(const Request&) {
return "v1/QuerywebFeed";
}
static bool SendRequestMetadata() { return true; }
};

class FeedNetwork {
public:
struct RawResponse {
Expand Down
9 changes: 9 additions & 0 deletions components/feed/core/v2/metrics_reporter.cc
Expand Up @@ -233,6 +233,8 @@ base::StringPiece NetworkRequestTypeUmaName(NetworkRequestType type) {
return "QueryBackgroundFeed";
case NetworkRequestType::kQueryNextPage:
return "QueryNextPage";
case NetworkRequestType::kQueryWebFeed:
return "QueryWebFeed";
}
}

Expand Down Expand Up @@ -1193,6 +1195,13 @@ void MetricsReporter::OnUnfollowAttempt(
}
}

void MetricsReporter::OnQueryAttempt(
const WebFeedSubscriptions::QueryWebFeedResult& result) {
VVLOG << "OnQueryAttempt status=" << result.request_status;
base::UmaHistogramEnumeration("ContentSuggestions.Feed.WebFeed.QueryResult",
result.request_status);
}

void MetricsReporter::RefreshRecommendedWebFeedsAttempted(
WebFeedRefreshStatus status,
int recommended_web_feed_count) {
Expand Down
1 change: 1 addition & 0 deletions components/feed/core/v2/metrics_reporter.h
Expand Up @@ -158,6 +158,7 @@ class MetricsReporter {
void RefreshSubscribedWebFeedsAttempted(bool subscriptions_were_stale,
WebFeedRefreshStatus status,
int subscribed_web_feed_count);
void OnQueryAttempt(const WebFeedSubscriptions::QueryWebFeedResult& result);

// Info card events.
void OnInfoCardTrackViewStarted(const StreamType& stream_type,
Expand Down
17 changes: 17 additions & 0 deletions components/feed/core/v2/public/public_types.cc
Expand Up @@ -124,6 +124,23 @@ std::ostream& operator<<(std::ostream& out,
}
}

std::ostream& operator<<(std::ostream& out, WebFeedQueryRequestStatus value) {
switch (value) {
case WebFeedQueryRequestStatus::kUnknown:
return out << "kUnknown";
case WebFeedQueryRequestStatus::kSuccess:
return out << "kSuccess";
case WebFeedQueryRequestStatus::kFailedOffline:
return out << "kFailedOffline";
case WebFeedQueryRequestStatus::kFailedUnknownError:
return out << "kFailedUnknownError";
case WebFeedQueryRequestStatus::kFailedInvalidUrl:
return out << "kFailedInvalidUrl";
case WebFeedQueryRequestStatus::kAbortWebFeedQueryPendingClearAll:
return out << "kAbortWebFeedQueryPendingClearAll";
}
}

std::ostream& operator<<(std::ostream& out, WebFeedAvailabilityStatus value) {
switch (value) {
case WebFeedAvailabilityStatus::kStateUnspecified:
Expand Down
Expand Up @@ -42,6 +42,9 @@ class StubWebFeedSubscriptions : public WebFeedSubscriptions {
void IsWebFeedSubscriber(base::OnceCallback<void(bool)> callback) override {}
void SubscribedWebFeedCount(base::OnceCallback<void(int)> callback) override {
}
void QueryWebFeed(
const GURL& gurl,
base::OnceCallback<void(QueryWebFeedResult)> callback) override {}
};

} // namespace feed
Expand Down
15 changes: 15 additions & 0 deletions components/feed/core/v2/public/types.h
Expand Up @@ -220,6 +220,21 @@ enum class WebFeedSubscriptionRequestStatus {
std::ostream& operator<<(std::ostream& out,
WebFeedSubscriptionRequestStatus value);

// This must be kept in sync with WebFeedQueryRequestStatus in
// enums.xml. These values are persisted to logs. Entries should not be
// renumbered and numeric values should never be reused.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.feed.webfeed
enum class WebFeedQueryRequestStatus {
kUnknown = 0,
kSuccess = 1,
kFailedOffline = 2,
kFailedUnknownError = 3,
kAbortWebFeedQueryPendingClearAll = 4,
kFailedInvalidUrl = 5,
kMaxValue = kFailedInvalidUrl,
};
std::ostream& operator<<(std::ostream& out, WebFeedQueryRequestStatus value);

using NetworkRequestId = base::IdTypeU32<class NetworkRequestIdClass>;

// Values for the UMA
Expand Down
11 changes: 11 additions & 0 deletions components/feed/core/v2/public/web_feed_subscriptions.h
Expand Up @@ -27,6 +27,12 @@ class WebFeedSubscriptions {
// The change reason from the request.
feedwire::webfeed::WebFeedChangeReason change_reason;
};
struct QueryWebFeedResult {
WebFeedQueryRequestStatus request_status =
WebFeedQueryRequestStatus::kUnknown;
// The id of the queried web feed.
std::string web_feed_id;
};
// Follow a web feed given information about a web page. Calls `callback` when
// complete. The callback parameter reports whether the url is now considered
// followed. This always creates a non-durable request.
Expand Down Expand Up @@ -107,6 +113,11 @@ class WebFeedSubscriptions {
virtual void SubscribedWebFeedCount(
base::OnceCallback<void(int)> callback) = 0;

// return the WebFeed Id based on the Uri provided.
virtual void QueryWebFeed(
const GURL& url,
base::OnceCallback<void(QueryWebFeedResult)> callback) = 0;

// Output debugging information for snippets-internals.
virtual void DumpStateForDebugging(std::ostream& ss) {}
};
Expand Down
1 change: 1 addition & 0 deletions components/feed/core/v2/request_throttler.cc
Expand Up @@ -35,6 +35,7 @@ int GetMaxRequestsPerDay(NetworkRequestType request_type) {
case NetworkRequestType::kUnfollowWebFeed:
case NetworkRequestType::kFollowWebFeed:
case NetworkRequestType::kSingleWebFeedListContents:
case NetworkRequestType::kQueryWebFeed:
return -1;
}
}
Expand Down
7 changes: 7 additions & 0 deletions components/feed/core/v2/test/stream_builder.cc
Expand Up @@ -404,6 +404,13 @@ feedwire::webfeed::UnfollowWebFeedResponse SuccessfulUnfollowResponse() {
SetConsistencyToken(response, "unfollow-ct");
return response;
}
feedwire::webfeed::QueryWebFeedResponse SuccessfulQueryResponse(
const std::string& query_name) {
feedwire::webfeed::QueryWebFeedResponse response;
*response.mutable_web_feed() = MakeWireWebFeed(query_name);
SetConsistencyToken(response, "query-ct");
return response;
}

WebFeedPageInformation MakeWebFeedPageInformation(const std::string& url) {
WebFeedPageInformation info;
Expand Down
2 changes: 2 additions & 0 deletions components/feed/core/v2/test/stream_builder.h
Expand Up @@ -128,6 +128,8 @@ WebFeedPageInformation MakeWebFeedPageInformation(const std::string& url);
feedwire::webfeed::FollowWebFeedResponse SuccessfulFollowResponse(
const std::string& follow_name);
feedwire::webfeed::UnfollowWebFeedResponse SuccessfulUnfollowResponse();
feedwire::webfeed::QueryWebFeedResponse SuccessfulQueryResponse(
const std::string& query_name);
feedwire::webfeed::WebFeedMatcher MakeDomainMatcher(const std::string& domain);

} // namespace feed
Expand Down
27 changes: 27 additions & 0 deletions components/feed/core/v2/web_feed_subscription_coordinator.cc
Expand Up @@ -968,4 +968,31 @@ WebFeedSubscriptionCoordinator::GetPendingOperationStateForTesting() {
return result;
}

void WebFeedSubscriptionCoordinator::QueryWebFeed(
const GURL& url,
base::OnceCallback<void(QueryWebFeedResult)> callback) {
// TODO(crbug/1409701) Combine subscription status into result callback. This
// would require binding a start call via WithModel and updating the local
// state to match the result from the server,
QueryWebFeedTask::Request request;
request.web_feed_url = url;

feed_stream_->GetTaskQueue().AddTask(
FROM_HERE,
std::make_unique<QueryWebFeedTask>(
feed_stream_, token_generator_.Token(), std::move(request),
base::BindOnce(&WebFeedSubscriptionCoordinator::QueryWebFeedComplete,
base::Unretained(this), std::move(callback))));
}

void WebFeedSubscriptionCoordinator::QueryWebFeedComplete(
base::OnceCallback<void(QueryWebFeedResult)> callback,
QueryWebFeedResult result) {
QueryWebFeedResult callback_result;
callback_result.web_feed_id = result.web_feed_id;
callback_result.request_status = result.request_status;
feed_stream_->GetMetricsReporter().OnQueryAttempt(callback_result);
std::move(callback).Run(std::move(callback_result));
}

} // namespace feed
8 changes: 8 additions & 0 deletions components/feed/core/v2/web_feed_subscription_coordinator.h
Expand Up @@ -16,6 +16,7 @@
#include "components/feed/core/v2/public/web_feed_subscriptions.h"
#include "components/feed/core/v2/web_feed_subscriptions/fetch_recommended_web_feeds_task.h"
#include "components/feed/core/v2/web_feed_subscriptions/fetch_subscribed_web_feeds_task.h"
#include "components/feed/core/v2/web_feed_subscriptions/query_web_feed_task.h"
#include "components/feed/core/v2/web_feed_subscriptions/subscribe_to_web_feed_task.h"
#include "components/feed/core/v2/web_feed_subscriptions/subscription_datastore_provider.h"
#include "components/feed/core/v2/web_feed_subscriptions/unsubscribe_from_web_feed_task.h"
Expand Down Expand Up @@ -80,6 +81,9 @@ class WebFeedSubscriptionCoordinator : public WebFeedSubscriptions {
void DumpStateForDebugging(std::ostream& ss) override;
void RefreshRecommendedFeeds(
base::OnceCallback<void(RefreshResult)> callback) override;
void QueryWebFeed(
const GURL& url,
base::OnceCallback<void(QueryWebFeedResult)> callback) override;

// Types / functions exposed for task implementations.

Expand Down Expand Up @@ -181,6 +185,10 @@ class WebFeedSubscriptionCoordinator : public WebFeedSubscriptions {
base::OnceCallback<void(UnfollowWebFeedResult)> callback,
UnsubscribeFromWebFeedTask::Result result);

void QueryWebFeedComplete(
base::OnceCallback<void(QueryWebFeedResult)> callback,
QueryWebFeedResult result);

void EnqueueInFlightChange(
bool subscribing,
WebFeedInFlightChangeStrategy strategy,
Expand Down

0 comments on commit 9c616cc

Please sign in to comment.